2023-09-20일자 알고리즘 공부

김재우·2023년 9월 21일
0

알고리듬

목록 보기
1/4
post-thumbnail

js 알고리즘 공부를 하고 배운 내용과 풀이내용을 정리한 게시글입니다.
다른 블로그에 이미 수 많은 문제들이 많이 공유 되어있고, 문제를 게시해도 상관 없을거 같아 오늘부터 문제도 같이 게시 합니다.

1.회문 문자열

앞에서 읽을 때나 뒤에서 읽을 때나 같은 문자열을 회문 문자열이라고 합니다.
문자열이 입력되면 해당 문자열이 회문 문자열이면 "YES", 회문 문자열이 아니면 “NO"를 출력
하는 프로그램을 작성하세요.
단 회문을 검사할 때 대소문자를 구분하지 않습니다.

function solution(a) {
  let answer = '';
  a = a.toUpperCase();
  let reverse = a.split('').reverse().join('');

  if (a === reverse) {
    answer = 'YES';
  } else {
    answer = 'NO';
  }

  return answer;
}
console.log(solution('gooD'));

// method 사용하지 않고 푸는 방법
function sol(s) {
  let answer = 'YES';
  s = s.toLowerCase();
  for (let i = 0; i < Math.floor(s.length / 2); i++) {
    if (s[i] !== s[s.length - i - 1]) return 'NO';
  }
  return answer;
}
console.log(sol('good'));

풀이: 이 문제는 풀이가 두 종류가 있다.
먼저 reverse 라는 method 를 사용하는 방법이 있고, 길이를 이용해서 푸는 방법이 있다.
먼저 reverse 를 이용해서 푸는 방법에 대해서 설명 해 보겠다.
앞서 문제에서 대,소문자 구분을 하지 않는다고 했으니 문자열을 대문자 혹은 소문자로 바꿀 필요가 있습니다.
reverse 라는 변수를 선언해 배열로 만들어준 뒤 reverse method 를 사용하고 다시 join을 시켜서 거꾸로 된 문자열을 만들었습니다.
그리고 조건문을 통해 거꾸로 된 문자열 과 문자열을 비교하여 같으면 answer 에 "YES" 를 틀리다면 "NO"를 할당 시켜주어 풀었습니다.

두번째 풀이: 이것은 문자열의 길이를 이용해서 i가 증가할때마다 배열의 길이 -i를 하면서 뒤에서부터 탐색하는 알고리즘 풀이입니다.
먼저 문제에서 대,소문자 구분을 하지 않는다 하였으니 소문자나 대문자로 통일 시켜줍니다.
그리고 문자 탐색을 length 의 절반까지만 돌게 합니다. 그리고 Math.floor 을 이용해 소숫점이 아닌 자연수로 만들어줍니다.

2.유효한 팰린드롬

앞에서 읽을 때나 뒤에서 읽을 때나 같은 문자열을 팰린드롬이라고 합니다.
문자열이 입력되면 해당 문자열이 팰린드롬이면 "YES", 아니면 “NO"를 출력하는 프로그램을
작성하세요.
단 회문을 검사할 때 알파벳만 가지고 회문을 검사하며, 대소문자를 구분하지 않습니다.
알파벳 이외의 문자들의 무시합니다.

function solution(s) {
  let answer = 'YES';

  s = s.toLowerCase();
  for (let i = 0; i < Math.floor(s.length / 2); i++) {
    if (
      (s[i].charCodeAt() >= 65 && s[i].charCodeAt() <= 90) ||
      (s[i].charCodeAt() >= 97 && s[i].charCodeAt() <= 122)
    ) {
      if (s[i] !== s[s.length - i - 1]) {
        return 'NO';
      }
    }
  }
  return answer;
}
console.log(solution('found7, time: study; Yduts; emit, 7Dnuod'));

// 정규식을 이용한 문제풀이

function reg(s) {
  let answer = 'YES';
  s = s.toLowerCase().replace(/[^a-z]/g, '');
  if (s.split('').reverse().join('') !== s) return 'NO';

  return answer;
}
console.log(reg('found7, time: study; Yduts; emit, 7Dnuod'));

풀이: 알파벳만 검사하고 나머지는 무시한다는 조건 때문에
나는 아스키 코드를 이용해서 풀면 되겠다 라고 생각했고 , 내가 푼 식은 대문자 범위 , 소문자 범위인 65 부터 90까지
97부터 122까지 s[i]를 charCodeAt() 이용해가지고 아스키코드로 변환해서 조건문을 걸어주고 조건에 맞으면 s[i] 가 s[s.length - i -1] 가 다르다면 팰린드롬이 아니기 때문에 바로 NO 를 출력했습니다.
2. 정규식을 이용하여 문제를 풀이했는데 엄청 간단합니다.
소문자나 대문자로 통일 시킨 뒤 replace함수를 이용해서 정규식을 넣고 빈문자열로 바꿉니다.
replace(pattern, replacement)
replace(/[^a-z]/g) g 는 전역을 의미하고 ^a-z 는 a부터z까지 를 의미합니다.
알파벳만 남긴 뒤 s와 reverse 를 적용시킨 s와 비교하여 다르다면 NO를 출력.

3.숫자만 추출

문자와 숫자가 섞여있는 문자열이 주어지면 그 중 숫자만 추출하여 그 순서대로 자연수를 만듭니다.
만약 “tge0a1h205er”에서 숫자만 추출하면 0, 1, 2, 0, 5이고 이것을 자연수를 만들면 1205이 됩니다.
추출하여 만들어지는 자연수는 100,000,000을 넘지 않습니다.

function sol(s) {
  let answer = '';
  s = s.replace(/[^0-9]/g, '');
  answer = s.indexOf(0);
  answer = s.substring(answer + 1, s.length);
  return answer;
}
console.log(sol('g0en2T0s8eSoft'));
//부끄러운 나의 코드 ㅠㅠ

//
function solution(s) {
  let answer = '';
  for (let i = 0; i < s.length; i++) {
    if (!isNaN(s[i])) answer += s[i];
  }
  return parseInt(answer);
}
console.log(solution('g0en2T0s8eSoft'));

이건 전에 배운 정규식을 이용해서 문제를 풀어보고 싶었고 substring을 이용해서 풀면 될거같아서 작성을 해봤는데 내가 간과하지 못한 사실이 있다 . 000 즉 '0' 이 한번이 아닌 여러번이 올 수 있다는 사실을 그래서 답은 나왔지만 결과적으로는 잘못된 코드이다.
두번째 풀이를 보면 isNaN 를 이용해서 Number가 아닌게 오면 true 가 되고 ,Number가 오면 false 를 반환한다. 그래서 앞에 ! 부정을 붙여주면서 Number일때만 알파벳을 빈 문자열인 answer 에 더해주었다 . 그리고 앞에 0 을 지우기 위해서 parseInt라는것을 사용해서 0을 한번에 지웠다.

profile
프론트엔드 꾸준개발자입니다.

0개의 댓글