2022/01/07) 4. 가장 짧은 문자거리 [문자열 탐색]

굥굥이·2022년 1월 7일
0
post-thumbnail

1. 문제

<가장 짧은 문자거리>
: 한 개의 문자열 s와 문자 t가 주어지면 문자열 s의 각 문자가 문자 t와 떨어진 최소거리를 출력하는 프로그램을 작성한다. 정리하자면 각 문자열 s의 각 문자가 문자 t와 떨어진 거리를 순서대로 출력하면되는 것이다.

2. 해결 방법

  1. 우선 예시로 문제 이해부터 해보자. teachermode e.
    저 값들이 주어지면, h는 어떤 값을 갖게 될까? 1을 갖게 된다.
    그리하여 우리는 왼쪽 오른쪽 모두 탐색하여, 그 중 더 짧은 거리를 출력한다.
  2. 먼저 p라는 변수를 생성하는데, 문자열보다 큰 값으로 초기화해준다. 1000으로 해주겠다.
  3. 만약 e를 만나면 p의 값을 다시 0으로 초기화해주고, e가 아닌 다른 문자를 만나면 +1을 해준다.
  4. 그렇게 하여 우선 왼쪽에 있는 e로부터의 거리를 구한다. ㅋㅋ 빡치네 아이패드샀으니 도착하면 수정하겠다.
  5. 이렇게 오른쪽으로도 구하는데, 주의할 점이 위의 것과 비교하여(Math.min) 더 작은 값을 넣을 것이므로, i를 i=s.length-1;로 초기화하여 -1해준다.
    그림으로 설명해야하는데 그림판으로 도저히 못하겠음 월욜에 다시 또 푼다.
    (ㅜ 아이패드 월욜에 도착했는데 불량임. 어쩔 수 없다. 손코딩한다.
    분명히 알아야 하는 건 왼쪽에 있는 e로부터의 거리를 할 땐 answer에 push해주어야 하지만, 오른쪽에 있는 e로부터의 거리를 할 땐 push를 하면 안되고 값을 바꿔줘야 한다는 것이다. 또한 1000으로 초기화한 이유를 이제 진짜 깨달았다. 우선 우린 왼쪽에 있는 e로부터의 거리를 구할 때 t엔 1001이라는 값이 들어갔는데, 사실 이 값은 옳은 값이 아니다. 그 이유는 t는 왼쪽에 있는 e가 없기 때문이다. 그리하여 아무리 누적된 p가 들어와도 그 값으로 대체될 수 있도록 제일 큰 값으로 초기화했던 것이다.)

3. 정답

        <script>
            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;  //주의! push하면 안됨! 그리고 여긴 어차피 0이므로 그냥 0으로 초기화만 해주고 넘어가면 된다.
                    else{
                        p++;
                        answer[i]=Math.min(answer[i], p);
                    }
                }
                return answer;
            }
            let str="teachermode";
            console.log(solution(str, 'e'));
        </script>
        <script>  //마음아프지만 쓰레기라고밖에 할 수 없는 내 코드.. 이거도 월요일에 다시 해본다
            function solution(s, t){
                //e라는 문자가 주어진다. 그리고 문자열이 주어지는데, 이 문자열엔 e가 포함돼 있다.
                //여기서 문제 : e와의 거리는? 순차 or 역순 상관 x, 최단거리거리를 출력하면 됨.
                //문자열을 배열로 만들어서 for..of를 돌리면서, for문? 
                let answer = "";
                s = s.split(''); //배열이 된 s
                let left = 0;
                let right = 0;
                for(let i = 0; i < s.length; i ++){
                    for(let j = 0; j < s.length; j ++){
                        if(s[i-j] === "e" && (i-j)>= 0){
                            left = i-(i-j);
                            break;
                        } 
                    }    
                    for(let j = 0; j < s.length; j ++){    
                        if(s[i+j] === "e" ){
                            right = (i+j)-i;
                            break;
                        }
                        console.log(right)
                    }
                    if( left >= right ? answer+= left: answer += right );
                }
                return answer;
            }      
            let str="teachermode";
            console.log(solution(str, 'e'));
        </script>

4. 내 코드와 비교 그리고 반성

30분 좀 넘게 풀었는데 실패했다. 어떤 식으로 하려 했냐면 먼저 s를 split를 이용해 배열로 만든 후, 배열의 인덱스를 이용해서 하려 했다. 두 개의 for문을 돌리는데, 하나는 고정된 인덱스를 돌리기 위한 용이고, 하나는 그 고정된 인덱스에서 -j 혹은 +j하여 같은 값이 나오면 break;하여 그 값들을 더하거나 빼서 최소거리를 구하려 했다. 그리하여 left와 right변수를 선언하여 시도해 봤지만, left는 됐는데 right는 되지 않았다 ㅠ 그리고 로직을 짤때도 대충짰던 게 문제였던 거 같다. 오늘 아이패드 샀는데 오면 이제 직접 필기해보면서 해야겠다.

profile
아자아자 파이띵굥!

2개의 댓글

comment-user-thumbnail
2022년 1월 9일

인경아

답글 달기
comment-user-thumbnail
2022년 1월 9일

정말 모든걸 걸고 마지막으로 부탁할게

답글 달기