TIL. 알고리즘 문제풀이

seul_velog·2022년 12월 7일
0

TIL_algorithm

목록 보기
9/26

1. 가장 짧은 문자거리

문제 설명

한 개의 문자열 s와 문자 t가 주어지면 문자열 s의 각 문자가 문자 t와 떨어진 최소거리를 출력하는 프로그램을 작성하세요.

입력설명
첫 번째 줄에 문자열 s와 문자 t가 주어진다. 문자열과 문자는 소문자로만 주어집니다. 문자열의 길이는 100을 넘지 않는다.

출력설명
첫 번째 줄에 각 문자열 s의 각 문자가 문자 t와 떨어진 거리를 순서대로 출력한다.

▣ 입출력 예

inputoutput
teachermode / e10121012210
tPPeachermodePP / e321012101221012

풀이

const shortest = (str, c) => {
  let p = 1000; // 1) 문자열보다는 작은 수로
  let answer = []; // 2)
  for (let x of str) { // 3)
    if (x === c) {
      p = 0;
      answer.push(p);
    } else {
      p++;
      answer.push(p);
    }
  }
  // 뒤에서 부터 계산
  p = 1000; // 4)
  for (let i = str.length - 1; i >= 0; i--) { // 5)
    if (str[i] === c) {
      p = 0;
      answer[i] = Math.min(answer[i], p); // 6)
    } else {
      p++;
      answer[i] = Math.min(answer[i], p); // 7)
    }
  }
  return answer;
};

let str = 'tPPeachermodePP';
console.log(shortest(str, 'e')); // [3, 2, 1, 0, 1, 2, 1, 0, 1, 2, 2, 1, 0, 1, 2]
  • for 문을 두 번 돌려서 받아온 c 로부터 왼쪽에서 부터 떨어진 거리와 오른쪽에서 부터 떨어진 거리를 구한다음, 작은 수를 answer 배열에 넣어 return 한다.
  • 1) 기준을 잡기위해 임의의 숫자 p 변수를 만든다. 이 때 주어진 조건(여기서는 주어지지 않았다🤔) 문자열보다 작은 수를 넣자.
  • 2) 결과를 담을 answer 배열을 만들자.
  • 3) for 문을 돌려서 받아온 str 문자열의 0번째 인덱스부터 찾을 c 와 비교하여 동일하다면 p 를 0으로, 그렇지 않다면 기존 p 로부터 1씩 더한다.
    이때 p 의 초기값을 문자열보다 높은숫자 1000 으로 지정한 이유가 보인다! 😀
  • 4) 다시 p 값을 1000으로 초기화한다.
  • 5) 뒤에서부터 비교하기 위한 for 문을 돌린다.
  • 6)7) 왼쪽 기준, 오른쪽 기준 으로 비교한 결과중 더 작은 쪽으로 answer 배열을 만든다.


✍️ solution

function solution(s, t) {
  let answer = [];
  let p = 1000;
  for (let x of s) {
    if (x === t) {
      p = 0;
      answer.push(p);
    } else {
      p++;
      answer.push(p);
    }
  }
  p = 1000;
  for (let i = s.length - 1; i >= 0; i--) {
    if (s[i] === t) p = 0; // 1)
    else {
      p++;
      answer[i] = Math.min(answer[i], p);
    }
  }
  return answer;
}
  • ❗️ 1) 어짜피 0이 가장 작으므로 굳이 Math.min 으로 비교하여 넣어주지 않아도 되는구나.🤔
    기존 0과 0을 비교할 필요가 없기 때문 !
    하지만 이 구문이 빠져버린다면 p 기준점이 1000 인 상태에서 p++ 가 되므로 원하지 않은 결과를 출력할 수 있다는 것을 확인했다. ▼
    let str = 'tPPeachermodePP'; 기준






2. 문자열 압축

문제 설명

알파벳 대문자로 이루어진 문자열을 입력받아 같은 문자가 연속으로 반복되는 경우 반복되는 문자 바로 오른쪽에 반복 횟수를 표기하는 방법으로 문자열을 압축하는 프로그램을 작성하시 오. 단 반복횟수가 1인 경우 생략합니다.

입력설명
첫 줄에 문자열이 주어진다. 문자열의 길이는 100을 넘지 않는다.

출력설명
첫 줄에 압축된 문자열을 출력한다.

▣ 입출력 예

inputoutput
KKHSSSSSSSEK2HS7E
TTJDJDJJJSKKT2JDJDJ3SK2

풀이

const compression = (str) => {
  // 1. 받은 문자를 하나씩 탐색한다.
  // 2. 이전 문자와 동일할경우 숫자 2(1+1)가 입력된다.
  // 2-1. 이전 문자와 여전히 동일할 경우 숫자를 +1 한다.
  // 3. 이전 문자와 동일하지 않을 경우 새로운 문자를 입력받는다.
  let answer = '';
  let num = 1;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === str[i - 1]) { // 이전 문자와 동일한 경우
      num++;
      // answer += num; // 1) X
    } else { // 3) 이전 문자와 다른 경우
      if (num > 1) { // 2)
        answer += num;
      }
      answer += str[i];
      num = 1;
    }
  }
  return answer;
};

str = 'KKHSSSSSSSE';
console.log('answer: ', compression(str)); // answer:  K2HS7E
  • 1) ❌ 여기서 num 을 더해주면 -> K2HS234567E 와 같이 출력되므로 안된다.
  • 2) 따라서 이 위치에 넣어줘야 동일한 문자가 나오지 않고나서야 비로소 합산된 num 값을 넣을 수 있게 되어 K2HS7E 와 같이 출력되는 것을 확인할 수 있다. 🤔
  • 하지만 이렇게 풀 경우 마지막 문자가 중복 되는 상황에서 제대로 출력되지 않는 문제가 있다.
    → 마지막 문자열이 없기 때문에 3) 의 else 문으로 넘어가서 if 조건을 받을 수 없기 때문!
    따라서 마지막 문자열을 추가해 주는 작업이 필요하다.

✍️ 수정

const compression = (str) => {
  let answer = '';
  let num = 1;
  str = str + ' ';
  for (let i = 0; i < str.length; i++) {
    if (str[i] === str[i - 1]) {
      num++;
    } else {
      if (num > 1) {
        answer += num;
      }
      answer += str[i];
      num = 1;
    }
  }
  return answer;
};

str = 'TTJDJDJJJSKK';
console.log('answer: ', compression(str)); // answer: T2JDJDJ3SK2 


✍️ solution

function solution(s) {
  let answer = '';
  let cnt = 1;
  s = s + ' '; // 1)
  for (let i = 0; i < s.length - 1; i++) { // 2)
    if (s[i] === s[i + 1]) cnt++;
    else {
      answer += s[i];
      if (cnt > 1) answer += String(cnt);
      cnt = 1;
    }
  }
  return answer;
}

let str = 'KKHSSSSSSSE';
console.log(solution(str));
  • 1) 마지막 문자 뒤에 빈 공간을 두기
  • 2) 인덱스로 접근해야 하므로 for ... of 문은 안된다.






profile
기억보단 기록을 ✨

0개의 댓글