인프런 커뮤니티 질문&답변
교안 공부 + unique()질문
작성
·
394
0
C를 어느정도 하고 바로 C++ 교안을 공부하고 있는 중입니다.
초반에 예제에서 벡터를 모르는 상태에서 벡터가 나와서
아 벡터는 대충 배열이랑 비슷한 무언가겠구나 생각하면서 예제를 이해해가면서 공부를 하고있었습니다.
그런데 가면 갈수록 예제들이 이해가 안가는데 이게 당연한거죠?
unique()가 중복되는 요소를 제거하고 중복되지 않은 요소들로 앞에서부터 정렬되어 채우고
나머지 요소들은 삭제하지 않고 둔다는 말은
1 1 2 2 3 3 4 4 5 5
1 2 3 4 5 3 4 4 5 5
중복되는 1 2 3 4 5를 제거하고 앞에서부터 정렬되어 채우면 1 2 3 4 5 가 된다는 말인건 이해했고 1 2 3 4 5 뒤에 ㅁ ㅁ ㅁ ㅁ ㅁ 자리에 왜 3 4 4 5 5가 오는지 모르겠습니다.
그냥 단순하게 앞에 지워진 갯수만큼 앞으로 땡기고 남은 자리수는 그냥 원래 데이터에서
뒤에 남은 5자리가 3 4 4 5 5이니 그냥 이걸 그대로 두면 된다는 말인가요?
3일에서 14일 걸린다는데 예제를 이해를 못하니 제가 멍청한건지 약간 자괴감이 드네요
이 문제뿐만 아니라 다른 예제도 학습을 하지 않은 개념들이 섞이는데 벡터에 대한 이론을 아직 공부를 하지 않아서 제가 잘 모르는거죠?
공부를 하고 다시 위로 돌아가면 이해하겠죠?
답변 1
0
안녕하세요 ㅎㅎ
그냥 단순하게 앞에 지워진 갯수만큼 앞으로 땡기고 남은 자리수는 그냥 원래 데이터에서
뒤에 남은 5자리가 3 4 4 5 5이니 그냥 이걸 그대로 두면 된다는 말인가요?
>> 해당 배열에서 유니크한 값들을 뽑아내고. 앞으로 옮기고. 나머지 것들은 그대로 두는 것을 의미합니다.
unique() 함수자체가 원래 그렇습니다.
나머지 것들은 "신경자체"를 쓰지 않는 함수입니다.
해서 unique함수를 쓸 때는 erase()를 같이 쓰는게 정신건강에 이롭습니다.
해당 부분 설명이 좀 헷갈리는 것 같아 교안을 수정했는데요. 다음과 같습니다.
unique는 범위안의 있는 요소 중 앞에서부터 서로를 비교해가며 중복되는 요소를 제거하고 나머지 요소들은 삭제하지 않고 그대로 두는 함수입니다. O(n)의 시간복잡도를 가집니다.
#include <bits/stdc++.h>
using namespace std;
vector<int> v;
int main () {
for(int i = 1; i <= 5; i++){
v.push_back(i);
v.push_back(i);
}
for(int i : v) cout << i << " ";
cout << '\n';
// 중복되지 않은 요소로 채운 후, 그 다음 이터레이터를 반환한다.
auto it = unique(v.begin(), v.end());
cout << it - v.begin() << '\n';
// 앞에서 부터 중복되지 않게 채운 후 나머지 요소들은 그대로 둔다.
for(int i : v) cout << i << " ";
cout << '\n';
return 0;
}
/*
1 1 2 2 3 3 4 4 5 5
5
1 2 3 4 5 3 4 4 5 5
*/unique() 같은 경우 앞에서 부터 서로를 비교해가며 중복된 요소를 제거 하기 때문에 sort()를 하지 않고 쓰면 예상치 못한 경우에 빠질 수 있습니다. sort(), erase(), unique() 순으로 코드를 구축하는게 정신건강에 이롭습니다.
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
vector<int> s {4, 3, 3, 5, 1, 2, 3};
s.erase(unique(s.begin(),s.end()),s.end());
for(int i : s) cout << i << " ";
cout << '\n';
vector<int> s2 {4, 3, 3, 5, 1, 2, 3};
sort(s2.begin(), s2.end());
s2.erase(unique(s2.begin(),s2.end()),s2.end());
for(int i : s2) cout << i << " ";
return 0;
}
/*
4 3 5 1 2 3
1 2 3 4 5
*/
그리고 수강생님이 멍청해서 그런게 아닙니다. 제가 설명이 부족했을 확률이 더 높죠.
차근차근 공부하시고.
꼭 궁금하거나 이것처럼 이해가 안되시면 반드시 질문주세요.
반드시 이해시켜드리겠습니다.
또 질문 있으시면 언제든지 질문 부탁드립니다.
감사합니다.
강사 큰돌 올림.
안녕하세요 ㅎㅎ
일단 교안 내 설명은 다음과 같습니다.
unique는 범위안의 있는 요소 중 앞에서부터 서로를 비교해가며 중복되는 요소를 제거하고 나머지 요소들은 삭제하지 않고 그대로 두는 함수입니다. O(n)의 시간복잡도를 가집니다.
제가 하나 예를 더 들어볼게요.
#include <bits/stdc++.h>
using namespace std;
vector<int> v {1, 1, 2, 2, 3, 3, 5, 6, 7, 8, 9};
int main () {
auto it = unique(v.begin(), v.end());
for(int i : v) cout << i << " ";
cout << '\n';
return 0;
}
/*
*/자 이 경우 unique()는
1 1 서로를 비교하며 1
2 2 서로를 비교하며 2
3 3 서로를 비교하며 3
그리고 쭉 5, 6, 7, 8, 9를 배열에 채워넣습니다.
채워넣지 않은 영역의 요소는 건드리지 않구요.
그래서 1 2 3 5 6 7 8 9 7 8 9이 반환됩니다.
뭔가 쓰기 어렵죠? 그렇기 때문에 unique()를 쓸 경우 꼭 sort()와 같이 써야 합니다.
왜냐하면 앞의 경우 처럼 앞에서 부터 서로를 비교해가며 중복된 요소를 제거 하기 때문에 sort()를 써야 우리가 예상한 중복된 수를 제거한 배열이 나오게 됩니다.
즉, 다음과 같이 sort(), erase(unique()) 로 코드를 구축하는게 정신건강에 이롭습니다.
감사합니다.
또한, 교안 내 설명을 좀 더 추가해서 반영하도록 하겠습니다.
큰돌님 답변 감사합니다.
질문 올리고 다시 차근 차근 값 출력하면서 이해하다보니 이해하게 됐습니다.
중복 요소를 제거하고 그 뒤 값들을 지우지 않고 둔다는 의미였더라구요 ㅎㅎ 동시에 sort() 와 erase() 가 함께 사용되어야 하는 이유도 정확히 알았습니다.
빠른 답변 감사드립니다!






큰돌님 안녕하세요.
저도 교안에서 이 unique() 예제가 잘 이해가 가지 않았는데요,
unique() 후 프린트되는 결과물이 아래와 같습니다.
1 2 3 4 5 3 4 4 5 5는 이해했는데 중복요소 제거 후, 나머지 요소들을 제거 하지 않았다면 중복이었던 1과 2 는 왜 뒤에 쌓이지 않고 제거되고 왜 3부터 쌓이는건가요??