05. [Code kata] 1Week - Day 5

Lemon·2022년 5월 16일
0

알고리즘

목록 보기
4/4
post-thumbnail

문제가 어려워서 30분정도 풀다가 구글링 답안을 보고 이해하는 형식으로 바꿨다.

문제

strs은 단어가 담긴 배열입니다. 공통된 시작 단어(prefix)를 반환해주세요.
예를 들어

strs = ['start', 'stair', 'step'] return은 'st'
strs = ['start', 'wework', 'today'] return은 ''

구글링 코드

function getPrefix (strs){
  let answer = '';
  let sortStrs = strs.sort();
  
  if(sortStrs.length === 0){
    return ''
  }

  for(let i = 0; i <sortStrs[0].length; i++){
    if(sortStrs[0][i] === sortStrs[sortStrs.length-1][i]){
       answer += sortStrs[0][i]
    }else{
       answer
    }
  }
  return answer;
}

let strs = ['start', 'stair', 'step']
console.log( getPrefix(strs) )

해석과정

.sort()

처음 보는 메소드였다.
.sort() : 배열을 정렬하는 함수로 () 값을 생략하면 문자열로 인지하고 배열의 문자열을 유니코드 값 순서대로 정렬한다.

.sort() 공식문서 확인하기 👀 https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort


.sort() 예제

a → b → c 순서대로 정렬된 배열로 나타난 것을 볼 수 있다.


🤔왜 sort를 사용했을까?

sort로 배열을 재 정렬 한 후 배열의 처음과 끝만 비교하면 된다.
이걸 이해하는데 한참 걸렸다...! 병휘님이 설명해주셔서 겨우 이해가능했다.


예제를 통한 이해

start, steir, satbpd ⇒ satbpd, start, steir

같은 문자가 있으면 그 다음문자를 기준으로 순서대로 정렬한다.
따라서 만약 sa → st → st 로 배열됐다면 s를 제외한 다른 영문자는 동일하지 않다는 뜻이다.


더 긴 배열을 예제로 본다면

동일한 문자인 st 다음 문자들을 순서대로 정렬한걸 볼 수 있다.

a → a → c → d → e

결국 중간에서 동일한 아닌 다른 문자가 들어왔다!!
그렇다면 공통된 시작 단어만 뽑는 배열의 경우 굳이 5개의 요소를 전부 비교할 필요없이

a → a → c → d → e

첫번째 인덱스와 마지막 인덱스 요소만 비교하면 될 것이다.


결과를 담을 변수answer

let answer = '';

.sort() 인자로 받은 strs 배열을 문자의 순서대로 재정렬

let sortStrs = strs.sort();

배열을 loop하기 위해서 for문 사용

for(let i = 0; i <sortStrs[0].length; i++){
    
}

배열안에 배열로 문자 접근
(문자도 배열처럼 index로 한글자씩 접근 가능하다는 걸 알았다.)

문자순으로 재정렬한 배열 sortStrs index의 처음과 끝 요소의 문자 한글자씩을 비교해야되니까

sortStrs[0][0] === sortStrs [sortStrs 마지막 index][0] // s === s true
sortStrs[0][1] === sortStrs [sortStrs 마지막 index][1] // t === t true
sortStrs[0][2] === sortStrs [sortStrs 마지막 index][2] // a === c false
end!!

위의 조건을 for문의 i를 이용해서 정리

sortStrs[0][i] === sortStrs[sortStrs.length-1][i]

조건이 true일때 까지만 결과로 넣을 배열인 answer에 하나씩 넣어준다.

answer += sortStrs[0][i]

👾문제점 발견

여기서 구글링 코드의 이상한 점을 발견한다.

for(let i = 0; i <sortStrs[0].length; i++){
    if(sortStrs[0][i] === sortStrs[sortStrs.length-1][i]){
       answer += sortStrs[0][i]
    }else{
       answer
    }
  }

false이면 멈춰야하는데 answer로 돌아간다. 그러면 false가 나온 후에도 for문은 계속 돌아서 이 후에 같은 문자열이 나온다면 그 값도 answer의 요소로 들어간다
현민님과 병휘님 둘 다 for문 else 뒤에 answer 이 왜 있지?라고 의문을 가졌다. 나는 왜인지 몰랐다....
몰랐던 이유는 if문처럼 for문도 false면 자동으로 return 되는줄 알았던 것..!! for문에 대해 애매하게 이해하고있었다는 사실을 깨달았다. for문은 false 의 값이 나온다고 반복을 멈추는게 아니라 false를 결과값으로 내고 조건만큼 전부 돈다는 사실을 완벽하게 이해하게됐다. 때문에 false가 나왔을 때 for 문이 멈추길 바란다면 break를 걸어줘야한다. 그동안 break를 왜 쓰지? 싶었는데 그 이유도 확실히 알게되었다.

for(let i = 0; i <sortStrs[0].length; i++){
    if(sortStrs[0][i] === sortStrs[sortStrs.length-1][i]){
       answer += sortStrs[0][i]
    }else{
       break
    }
  }

이렇게 코드를 해석하고 잘못되었던 부분을 수정 후 답안을 제출했다.


✅최종 제출 답안

const getPrefix = strs => {
  let answer = '';
  let sortStrs = strs.sort();
  
  if(sortStrs.length === 0){
    return ''
  }

  for(let i = 0; i <sortStrs[0].length; i++){
    if(sortStrs[0][i] === sortStrs[sortStrs.length-1][i]){
       answer += sortStrs[0][i]
    } else {
      break;
    }
  }
  
  return answer;
}

module.exports = { getPrefix };
profile
프론트엔드 개발자 가보자고~!!

0개의 댓글