둘만의 암호 [프로그래머스 Lv1]

hyo·2023년 3월 17일
0

코딩테스트 준비

목록 보기
7/8
post-thumbnail

둘만의 암호 (프로그래머스 Lv1)

문제설명

두 문자열 s와 skip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 합니다. 암호의 규칙은 다음과 같습니다.

문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꿔줍니다.
index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아갑니다.
skip에 있는 알파벳은 제외하고 건너뜁니다.
예를 들어 s = "aukks", skip = "wbqd", index = 5일 때, a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않습니다. 따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됩니다. 나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"가 되며 결과는 "happy"가 됩니다.

두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return하도록 solution 함수를 완성해주세요.


의사코드

우선 alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 선언!
skip의 문자열에 존재하는 문자들을 alphabet의 요소와 비교해 보며 존재하는 요소들을 alphabet요소에서 삭제한다.
근데 위처럼 삭제를 해버리면 s의 문자열과 skip의 문자열이 일치하는게 있을때, alphabet에서도 삭제하기 때문에 s[i]의 문자열 기준으로 index만큼 이 동을 시킬수 없다. -> 기준점을 삭제해서 존재하지않으므로
하지만 제한사항에 skip에 포함되는 알파벳은 s 에 포함되지 않는다고 나와있네?? 또 괜한 고민을 했음.. 문제 잘 읽자..
s 의 문자열 s[i]가 존재하는 alphabet의 요소를 찾아가 그 인덱스 기준에서 매개변수 index만큼 이동후 alphabet의 요소를 빼오고 그 문자열을 리턴!
주의 s의 문자열에서 index만큼 alphabet에서 이동했을때 'z'를 넘어가면 다시 alphabet의 0번째 인덱스부터 시작!


작성코드 ( -> 실패코드)

아래 두 코드는 코드실행했을때 테스트 몇개가 통과되지 않았다..

첫번째 코드에서 실패가 나왔을땐 아무리 수정해봐도 모르겠어서 런타임 문제인가 싶어
불필요한 반복을 줄였다. -> 그래도 실패

function solution(s, skip, index) {
    
    const alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; // 알파벳 순서가 브라우저에 내장되어 있진 않으므로 직접 써준다.
     
    for(let el of skip){
        for(let i = 0; i < alphabet.length; i++){
            if(el === alphabet[i]){
               alphabet.splice(i, 1); // skip 문자열에 존재하는 문자를 alphabet에서 삭제! -> splice매서드 활용.
            }
        }
    }
    
    let result = ''; // 리턴값으로 해줄 result 선언.
    for(let i = 0; i < s.length; i++){
        for(let j = 0; j < alphabet.length; j++){
            let newIdx = 0; // 'z'를 넘어갔을때의 새로운 index를 넣어둘 변수 선언.
            if(s[i] === alphabet[j]){ // 우선 s[i]가 alphabet의 어디에 있는지 확인
              if(j + index >= alphabet.length){ // s[i]와 일치하는 alphabet의 j 번째 에서 index만큼 더해줬을때 'z'를 넘는다면? 
                 newIdx = j + index - alphabet.length; // newIdx에 할당
                 result = result + alphabet[newIdx];
                 break; // 아래코드 result에 두번 할당되는 일이 없도록 다음 반복 진행.
              }
                else {
                 result = result + alphabet[j + index];
                 break;
                }
            }
        }
    }
    return result;
}
불필요한 반복을 줄여본 코드
function solution(s, skip, index) {
    
    let alphabet = 'abcdefghijklmnopqrstuvwxyz'; 
     
    for(let el of skip){
       alphabet = alphabet.replace(el, '');
    }
    
    let result = ''; 
    for(let el of s){
        if(alphabet.indexOf(el) + index >= alphabet.length){
           let newIdx = alphabet.indexOf(el) + index - alphabet.length;
           result = result + alphabet[newIdx];
           continue;
        }
        else {
          result = result + alphabet[alphabet.indexOf(el) + index]
          continue;
        }
    }
    return result;
}

문제발견
런타임문제는 아닌것 같아 문제설명과 제한사항을 다시 읽어보며 생각을 해보니
문제점이 생각났다.
alphabet의 길이는 26이다.
그리고 index20까지가 최대고 skip은 길이가 10이 최대이다.
skip의 문자열들을 alphabet에서 빼주면 alphabet의 최소길이는 16이다.
그럼 만약 skip = 'abcdefghij', index = 20 이고 s'z'가 포함되어있다고 가정해보자.
내가 쓴 코드
if(alphabet.indexOf(el) + index >= alphabet.length){let newIdx = alphabet.indexOf(el) + index - alphabet.length; ...}
이 부분에서 문제가 생긴다.
반복문에서 s'z'문자열 차례가 왔을때
newIdx에 s의 문자열과 일치하는 alphabet의 인덱스번호(15) 와 index = 20을 더한 값에서 alphabet의 길이를 빼줘도 newIdx가 아직도 더 크기 때문에 alphabet의 길이는 16이므로 인덱스로는 접근할 수가 없다.
그렇기때문에 내부에서 한번더 조건을 거쳐
if(newIdx >= alphabet.length){
              newIdx = newIdx - alphabet.length; 
           }
문제를 해결할 수 있었다.

최종코드

function solution(s, skip, index) {
    
    let alphabet = 'abcdefghijklmnopqrstuvwxyz';
     
    for(let el of skip){
       alphabet = alphabet.replace(el, '');
    }
    
    let result = '';
    for(let el of s){
        if(alphabet.indexOf(el) + index >= alphabet.length){
           let newIdx = alphabet.indexOf(el) + index - alphabet.length;
           if(newIdx >= alphabet.length){
              newIdx = newIdx - alphabet.length; 
           }
           result = result + alphabet[newIdx];
           continue;
        }
        else {
          result = result + alphabet[alphabet.indexOf(el) + index]
          continue;
        }
    }
    return result;
}
profile
개발 재밌다

0개의 댓글