문자열이 있다고 치자. 그리고 이 문자열의 각 문자들이 특정 문자와의 거리(가까운 거리)를 구해야 한다.

 

이해하기 쉽게 예시로 teachermode라는 문자열이 있고 특정 문자 e가 입력되면, 출력은

1 0 1 2 1 0 1 2 2 1 0 이다.

 

나는 처음에 문자열의 각 문자를 같은 문자열의 다른 문자와 비교해야하므로 무조건 이중 for문을 써야할 수 밖에 없다고 생각해서 아래와 같이 풀었다.

function solution(s,t){
  const answer = [];
  for(let i=0; i<s.length; i++){
    let min_distance = Number.MAX_SAFE_INTEGER;
    for(let j=0; j<s.length; j++){
      if(s[j] === t){
        const distance = Math.abs(i-j);
        if(distance < min_distance) min_distance = distance;
      }
    }
    answer.push(min_distance);
  }

  return answer.join(" ")
}

 

 

IDEA : 왼쪽에서부터의 거리와 오른쪽에서부터의 거리를 각각 검사하고, 작은것들로 취합.

function solution(s,t) {
  const answer = [];
  let p = 100;
  for(let i=0; i<s.length; i++){
    if(s[i] === t) {
      p = 0;
      answer.push(p);
    } else {
      p++;
      answer.push(p);
    }
  }

  p = 100;
  for(let i=s.length-1; i>=0; i--){
    if(s[i] === t) p=0;
    else {
      p++;
      answer[i] = Math.min(p, answer[i]); // 원래있던 왼쪽에서와의 거리와 현재 오른쪽에서와의 거리중 작은값
    }
  }
  return answer.join(" ")
}

아스키코드

언젠가 쓸 일이 있으니 소문자 a-z 부터 대문자 A-Z까지는 외워두자.

 

대문자 알파벳 : 65~90 까지 26개
소문자 알파벳 : 97~122 까지 26개

 

charCodeAt(), String.fromCharCode()

// 문자의 아스키코드 체크하는 법
'A'.charCodeAt() // 65

// 반대로 아스키코드로 문자 체크하는 법
String.fromCharCode(65) // 'A'

 

replace 로 문자열 바꾸기 + 정규표현식

replace(a,b) -> a를 b로 바꾼다.

 

정규표현식을 이용하면 /A/를 #으로 바꾼다. 다만, A를 만나면 #으로 바꾸고 아예 끝나버리기 때문에 문자열 전체에서 A를 #으로 바꾸려면 g(global)를 붙여준다.

function solution(str) {
  let answer = str;
  str = str.replace('/A/g', '#');
  return answer
}

console.log(solution("BANANA"));

 

정규표현식을 이용하면 문자열에서 알파벳들만 걸러낼 수 있다.

function solution(str) {
  const answer = s.replace("/[^a-z]/g","")
  return answer
}

const s = 'ab ;c, dA'
console.log(solution(s)) // abcd

 

문자열에서 숫자만 걸러내기 + 028 과 같은 문자열 28숫자로 나타내기 원리

 

문자열이 있을 때 숫자만 걸러낼 수 있는 방법

 

isNaN : 문자열이 NaN(숫자가아니면) true 숫자이면 false

function solution(str) {
  let numberStr = "";
  for(let i=0; i<str.length; i++){
    if(!isNaN(str[i])) numberStr+=str[i]
  }
}

const s = 'a0b1 ;c, dA23'

console.log(solution(s)) // "0123"

 

여기서 0123을 123으로 바꾸려면 parseInt, Number, *1 을 해주는 여러가지 내장함수들을 사용했었다. 근데 직접 구현해보자.

어떤 숫자이던 일의자리 숫자 전까지 10을 곱하고 일의자리만 더해주면 그 숫자가 나온다.

즉 0123 이면 10*0+0 = 0, 1*10+2, 12*10+3 이런식으로 표현할 수 있다.

function solution(str) {
  let numberStr = 0;
  for(let i=0; i<str.length; i++){
    if(!isNaN(str[i])) numberStr = numberStr*10 + Number(str[i])
  }
}

const s = 'a0b1 ;c, dA23'

console.log(solution(s)) // "123"

 

알고리즘 문제를 풀다 보면, 최댓값이나 최솟값을 구해야 하는 문제가 종종 있다.

 

나는 지금까지 최솟값을 구할 때나 최댓값을 구할 때 어떤 값으로 초기화 해야할 지 고민하는데 시간을 썼다.

 

쉬운 문제라면 최솟값이나 최댓값의 범위를 알려줘서 (ex. 자연수일 때 최솟값 0으로 초기화) 고민이 없었는데, 어려운 문제를 풀다 보면 설정하기 애매한 조건들이 있었다.

 

이 방법을 왜 이제 알았을까?

 

최소값 초기화 Number.MAX_SAFE_INTEGER

어떤 입력값들을 탐색할 때 최솟값을 가장 크게 해놓는다면, 입력값의 처음 인덱스 혹은 첫 값부터 최솟값이 되고, 이후 모두 탐색할 수 있다.

 

  let min = Number.MAX_SAFE_INTEGER;
  for(let i=0; i<arr.length; i++){
    if(arr[i] < min) {
      min = arr[i];
    }
  }

 

 

최대값 초기화 Number.MIN_SAFE_INTEGER

마찬가지로 최댓값은 반대로 최댓값을 가장 작은 값으로 초기화한다면, 첫 값부터 최댓값이되고, 모두를 탐색할 수 있다.

  let max = Number.MIN_SAFE_INTEGER;
  for(let i=0; i<arr.length; i++){
    if(arr[i] > max) {
      max = arr[i];
    }
  }

+ Recent posts