알고리즘 이야기/알고리즘 문제풀이

JS 알고리즘 - indexOf(), filter

thisisamrd 2023. 9. 30.

 

아래와 같은 문제를 조금 더 세련되게 풀기 위해 indexOf와 filter의 인자값을 명확히 알 필요가 있었다.

오늘의 알고리즘 문제는 아래와 같다.

 

알고리즘 문제

중복단어제거
N개의 문자열이 입력되면 중복된 문자열은 제거하고 출력하는 프로그램을 작성하세요.
출력하는 문자열은 원래의 입력순서를 유지합니다.

▣ 입력설명
첫 줄에 자연수 N이 주어진다.(3<=N<=30)
두 번째 줄부터 N개의 문자열이 주어진다. 문자열의 길이는 100을 넘지 않습니다.
▣ 출력설명
첫 줄부터 중복이 제거된 문자열을 차례로 출력한다.
▣ 입력예제 1
5
good
time
good
time
student
▣ 출력예제 1
good
time
student

 

우선 내가 푼 답은 이렇다. 이렇게 해도 답은 맞다.

 

내가 푼 답

function solution(s){  
    let answer = [];
    for(let x of s){
        if(answer.indexOf(x) == -1) answer.push(x)
    }
    return answer
}
let str=["good", "time", "good", "time", "student"];
console.log(solution(str));

 

 

그러나 answer.indexOf(x) == -1을 이용해 false에 해당하는 원소를 찾는 방법으로밖에 문제를 풀어봤기 때문에

아래와 같이 filter를 이용한 다른 해답도 익혀보려 한다.

 

해답 예시

 

function solution(s){  
    let answer;
    //console.log(s.indexOf("time"));
    answer=s.filter(function(x, i){
        //console.log(x, i, s.indexOf(x))
        return s.indexOf(x) == i;
    });

    return answer

}
let str=["good", "time", "good", "time", "student"];
console.log(solution(str));

 

문제 해설

여기서 처음 console.log를 보면 알 수 있듯, indexOf는 각 배열의 index를 알려주지만 중복한 원소가 있을 경우 첫 번째 인덱스만 보여준다.

예를 들어 console.log(s.indexOf("time")) 의 값은 첫번째 "good"에 해당하는 인덱스번호인 0만 호출된다.

그러나 filter의 인자인 (x,i) 중 i에 해당하는 index는 중복과 상관없이 모든 배열을 순회하며 인덱스 번호를 호출한다.

따라서 indexOf와 filter에서 출력되는 인덱스번호에 차이가 생긴다.

이를 자세히 알아보기 위해 두번째 console.log인 console.log(x, i, s.indexOf(x))의 출력결과를 보면 다음과 같다.

 

이 같은 점을 이용해, 중복이 있는지 체크하기 위해서는 filter의 i와 indexOf()의 값이 일치하는지 보면 된다.

이미 indexOf에서 출력된 값이 있다면 다음 중복된 원소의 index와 다를 것이기 때문에, 서로 일치하는 것들만 filter로 뽑아서 return 시키면 된다.

댓글