만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/programmers&bj

[C++][알고리즘] 프로그래머스::전화 번호 목록

D36choi 2019. 8. 20. 17:05
728x90

https://programmers.co.kr/learn/courses/30/lessons/42577

 

코딩테스트 연습 - 전화번호 목록 | 프로그래머스

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 구조대 : 119 박준영 : 97 674 223 지영석 : 11 9552 4421 전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 r

programmers.co.kr

 

문제 설명

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
  • 각 전화번호의 길이는 1 이상 20 이하입니다.

 

 

시행착오

 

이번 문제는 처음에 굉장히 원시적으로 문제를 풀어서... 올리기 좀 민망하다.

주요 아이디어는

 

algorithm 헤더에 포함된 find함수로 < find(...) != string::npos > 문을 통해 문자열이 다른 문자열에 포함되어있는지를

체크하는 것인데 아마 "이것때문에 틀렸을것이다" 추측하는 부분은 이 문제에선

번호의 앞머리부분. 그니까 만약 번호가 123이고 다른 번호가 444123 이면 false가 아니라 true 여야 하는데 아마 이것도

find함수로는 당연히 포함관계로 인식해서 false를 반환한게 아닐까하는 점이다.

그래서 구글링 했더니... 와.. 이게 이렇게 간단히 만들 수 있는 거였구나 하며 자괴감을 느꼈다.

 

참고한 게시물

https://jhnyang.tistory.com/124

 

[프로그래머스 레벨2] 전화번호 목록 문제 풀이

[프로그래머스 알고리즘 Level 2] 오늘은 프로그래머스 코딩테스트 연습에 있는 Level 2 전화번호 목록 문제를 풀이해볼게요. 전화번호 목록 문제 전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어..

jhnyang.tistory.com

이걸로 깨달은건, find함수를 쓸필요도 없다는 것이다. 결국 비교를 하려는, 접두가 가능한 "짧은 번호"의 길이만큼만

비교대상인 "긴 번호"의 시작부터의 번호를 비교하면 되는 건데

이것을 substr를 이용하여 하면 되는 것이다..

 

substr

첫번째 인자로 시작 위치, 두번째는 끝위치를 반환하면 string의 해당 위치 범위안에 있는 문자열을 반환하는 함수.

이거만 있으면 find를 쓸필요가 없다.

 

정답(결국엔 커닝한거지만)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
bool solution(vector<string> phone_book) {
    bool answer = true;
    sort(phone_book.begin(), phone_book.end());
    for (int i = 0; i < phone_book.size(); i++) {
        for (int j = i + 1; j < phone_book.size(); j++) {
            if (phone_book[i] == phone_book[j].substr(0, phone_book[i].size())) {
                answer = false;
                return answer;
            }
        }
    }
    return answer;
}
cs

 

if문안에 return 이 있어도 상관없는게, 어차피 100개의 전화번호 중 접두가능한 번호가 1개만 있어도 결과는

false이므로 굳이 전부를 완전탐색할 필요는 없다.