[알고리즘] 문자찾기 (filter(), toUpperString(), match())

Perfume·2022년 4월 25일
0

Algorithm

목록 보기
4/11
post-thumbnail

💡 특정 문자 찾기

한 개의 문자열을 입력받고, 특정 문자를 입력받아 해당 특정문자가 입력받은 문자열에 몇 개 존재하는지 알아내는 프로그램을 작성하세요.
문자열의 길이는 100을 넘지 않습니다.

일단 문제를 봤을 때 split을 이용해서 string을 배열로 쪼개고, filter를 한 다음 length를 구하면 되겠다는 생각이 들었다.

그래서 내가 작성한 코드는 다음과 같다.

function solution(s, t) {
  let answer = s.split("").filter((item) => item === t).length;
  return answer;
}

간단하게 테스트를 통과했지만 풀이를 보니 이보다 더 간결하게 풀 수 있는 방법이 있었다.

function solution(s, t) {
  let answer = s.split(t).length;
  return answer - 1;
}

두 방식 다 split을 사용했지만 나는 ""를 기준으로 모든 문자열을 분해했는데, 이 풀이는 찾고자 하는 특정문자 t를 기준으로 나눈 것이 달랐다. DONTSTOP이라는 string에서 T를 찾는다고 가정해보자. 이를 시각화해보면 다음과 같다.

T를 기준으로 나눈 다음 새 배열로 리턴하기 때문에 answer의 값은 다음과 같다.

["DON", "S", "OP"]

2개의 T를 기준으로 나누기 때문에 3이라는 길이를 가진 배열이 만들어진 것이다. 그래서 return할 때 answer에서 -1을 해주면 우리가 원하는 갯수를 얻을 수 있다.

호기심 많은 사람이라면 여기서 궁금증이 생길 것이다. 만약에 찾고자 하는 문자가 맨 뒤에 있다면?

이러면 ["KEEP", "OIN"]이 되고, 따라서 answer-1을 하면 정답인 2가 아니라 1이 되니까 틀린 거 아닐까 싶을 수 있다. 하지만 실제 값은 그렇지 않다.

["KEEP", "OIN", ""]

이렇게 배열의 맨 뒤에 빈 string 값이 들어간다. 그래서 찾고자 하는 문자가 string의 맨 끝에 있어도 오류없이 정답이 나온다. 이 문제를 통해 맨 끝에서 split을 하면 ""이 들어간다는 것을 처음 알게 되었다.

💡 대문자 찾기

한 개의 문자열을 입력받아 해당 문자열에 알파벳 대문자가 몇 개 있는지 알아내는 프로그램을 작성하세요.

문제를 읽고 알파벳 대문자를 찾은 다음 대문자를 새로운 배열로 return하고 그 배열의 length를 구하면 되겠다는 생각이 들었다. 대문자를 찾는 방법에 관해서 좋은 글을 발견했다.

Find all Uppercase characters in a String using JavaScript

위에 링크한 글에서 설명하는 대문자를 찾는 방법은 다음과 같다.

const str = 'HelloWorld';

const onlyUpper1 = str.replace(/[a-z]/g, '');
console.log(onlyUpper1); // 👉️ "HW"

const onlyUpper2 = str.replace(/[^A-Z]/g, '');
console.log(onlyUpper2); // 👉️ "HW"

const onlyUpper3 = str.match(/[A-Z]/g);
console.log(onlyUpper3); // 👉️ ['H', 'W']

나는 대문자를 찾아 새로운 배열로 return 하는 것을 원해서 세번째 방법인 match()를 사용했다.

match()는 문자열이 정규식과 매치되는 부분을 검색하는 메서드다.

match()의 매개변수로 대문자 A-Z를 뜻하는 정규표현식을 넣었고, 의도대로 s라는 string에서 대문자와 일치하는 값이 새로운 배열로 반환되었다. 문제에서 원하는 바는 대문자의 갯수였기 때문에 .length를 추가했다.(배열의 길이가 곧 대문자의 갯수이기 때문이다.)

최종 코드는 다음과 같다.

function solution(s) {
  let answer = s.match(/[A-Z]/g).length;
  return answer;
}

풀이를 확인해보니 for문으로도 풀 수 있었다. 임의의 변수 x를 선언하고 for로 반복문을 돌면서 x가 x. toUpperCase()한 값과 동일하다면 answer의 숫자를 증가시키는 방식이었다.

function solution(s) {
  let answer = 0;
  for (let x of s) {
    if (x === x.toUpperCase) answer++;
  }
  return answer;
}

여기까지는 짐작 가능했지만, 다른 방식 한 가지가 되게 신기했다. 영어 대문자의 아스키 코드가 65~ 90(A~Z)인 것을 이용해 숫자의 크기를 따져서 대소문자를 확인하는 방법이었다.

function solution(s) {
    let answer = 0;
    for (let x of s) {
      let num = x.charCodeAt();
      if(num>= 65 && num<=90 ) answer++;
    }
    return answer;
  }

💡 대문자로 통일

대문자와 소문자가 같이 존재하는 문자열을 입력받아 대문자로 모두 통일하여 문자열을 출력하는 프로그램을 작성하세요.

toUpperCase()로 간단하게 해결했다.

function solution(s) {
    let answer = s.toUpperCase();

    return answer;
  }

그런데 풀이를 보니 아래처럼 for문을 통해 대소문자를 판별하는 과정이 있었다. 어차피 toUpperCase()를 쓰면 대문자로 통일되는데 왜 판별하는 과정을 거치는걸까? 잘 모르겠다.

  function solution(s) {
    let answer = "";
    for(let x of s) {
        if(x===x.toLowerCase()) answer+=x.toUpperCase();
        else answer +=x;
    }

    return answer;
  }
profile
공부하는 즐거움

0개의 댓글