PS
[C++] 1764 : 듣보잡
왕방토
2021. 2. 11. 21:49
728x90
실버 Ⅳ
우선 틀린 코드 (런타임 에러 - out of range)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int n, m;
vector <string> v1;
vector <string> v2;
int main() {
cin >> n >> m;
string name;
for (int i = 0; i < n; i++) {
cin >> name;
v1.push_back(name);
}
sort(v1.begin(), v1.end());
int low, high, mid;
for (int i = 0; i < m; i++) {
cin >> name;
low = 0;
high = n;
while (low <= high) {
mid = (low + high) / 2;
if (name < v1.at(mid)) {
high = mid - 1;
}
else if (name > v1.at(mid)) {
low = mid + 1;
}
else if (name == v1.at(mid)) {
v2.push_back(name);
break;
}
}
}
sort(v2.begin(), v2.end());
reverse(v2.begin(), v2.end());
cout << v2.size() << endl;
while (!v2.empty()) {
cout << v2.back() << endl;
v2.pop_back();
}
}
정답 코드
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int n, m;
vector <string> v1;
vector <string> v2;
int main() {
cin >> n >> m;
string name;
for (int i = 0; i < n; i++) {
cin >> name;
v1.push_back(name);
}
sort(v1.begin(), v1.end());
for (int i = 0; i < m; i++) {
cin >> name;
if (binary_search(v1.begin(), v1.end(), name)) {
v2.push_back(name);
}
}
sort(v2.begin(), v2.end());
reverse(v2.begin(), v2.end());
cout << v2.size() << endl;
while (!v2.empty()) {
cout << v2.back() << endl;
v2.pop_back();
}
}
다른 부분은 binary search(이진 탐색) 구현했냐 안했냐의 차이..
즉 내가 구현한 이진탐색 부분에서 out of range가 일어났다는 뜻...
내가 구현한 이진탐색 부분 코드
int low, high, mid;
for (int i = 0; i < m; i++) {
cin >> name;
low = 0;
high = n;
while (low <= high) {
mid = (low + high) / 2;
if (name < v1.at(mid)) {
high = mid - 1;
}
else if (name > v1.at(mid)) {
low = mid + 1;
}
else if (name == v1.at(mid)) {
v2.push_back(name);
break;
}
}
}
앗 알아버렸다
high에 n-1을 넣어줘야 하는 것 같은데...
맞네ㅠㅠ~
일단 오류를 알아낸 생각은 다음과 같다
이 부분에서 out of range가 일어남 -> out of range가 일어날 부분은 v1.at(mid) 밖에 없음
-> 그럼 mid가 0~n-1 사이를 벗어난다는 말이 됨 -> 엥 n-1? 그렇네??
아이고.... 이분탐색에서 low와 high는 인덱스!!! 라는걸 왜 자꾸 까먹는지 모르겠다..
꽤 오래걸렸다.. 걍 알고리즘 헤더의 bs 쓰고 말아 버리지ㅋㅋ,,
-------------
아 그리고 추가로.. 런타임 에러 때문에 구글링 하다가 알아낸 건데
이 문제를 풀 때
n개의 이름과 m개의 이름을 모두 같은 벡터에 담고
사전 순으로 정렬한 후,
벡터의 i번째 요소와 i+1번째 요소가 같은지 확인하는 식으로 해서
푼 사람이 있더라...정말 똑똑하게 푼다..!
(문자열의) 중복을 확인할 때
이런 식으로 풀면 좋을 것 같다
굳이 문자열의 중복이 아니어도 괜찮으려나?