Function (2)

EHminShoov2J·2023년 8월 20일
0

CPP/코딩테스트

목록 보기
6/25
post-thumbnail

1. Unique() - O(N)

중복된 요소를 제거해 주는 함수. 엄밀히는 연속된 원소를 제거하는 함수.
연속된 원소를 제거하여 앞에서 부터 채우고, 배열의 뒷부분은 그대로 둔다. ex) 1122345 >> 1234545

unique(start, last) // 반환값은 iterator

따라서 set 처럼 만들어주고 싶다면 sort() 를 이용하여 중복 값이 뭉치게 하고, erase()함수를 사용하여 남는 값을 제거해 주어야 한다.

#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    cout << "Unique" << endl;
    vector<int> v_unique;
    
    v_unique = {1,1,2,2,3,4,5};
    auto it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    v_unique = {3,3,5,3,2,3};
    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique){
        cout << v ;
    }
    cout << endl;

    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;
	
    // 연속된 원소를 제거하는 것에 가까움! 따라서 sort()랑 같이 사용해 주어야 한다.
    sort(v_unique.begin(), v_unique.end());
    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    //Erase 함수까지 사용하면 깔끔하게 중복되지 않은 요소만 돌려받을 수 있음!
    v_unique.erase(unique(v_unique.begin(), v_unique.end()), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;
}

2. lower_boud, upper_bound

1. lower_bound()

해당 값 이상인 iterator를 반환한다.

lower_bound(start, last, value) // return 값은 iterator

2. upper_bound()

해당 값 초과인 iterator를 반환한다.

upper_bound(start, last, value) // return 값은 iterator

3. 활용

  • 위 두개의 함수에 같은 값을 적용하여, 같은 값이 몇개 있는지 확인하는 용도로 사용할 수 있다.
  • 만약 조건을 만족하는 값을 찾지 못한다면, 가장 근접한 값을 리턴
  • 주의 ! 반드시 정렬된 상태에서만 해당 함수들을 사용하여야 한다!
#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    cout << "upper_bound(), lower_bound()" << endl;

    vector<int> v_bound = {1,3,5,7,9,11};
    cout << lower_bound(v_bound.begin(), v_bound.end(), 5) - v_bound.begin() << endl; // 5이상인 지점 반환
    cout << lower_bound(v_bound.begin(), v_bound.end(), 6) - v_bound.begin() << endl; // 6이상인 지점 반환
    cout << upper_bound(v_bound.begin(), v_bound.end(), 5) - v_bound.begin() << endl; // 5초과인 지점 반환

    cout << *lower_bound(v_bound.begin(), v_bound.end(), 5)<< endl; // 주소값이 리턴되기 때문에 역참조연산을 통해서 값확인가능
    
    v_bound = {1,3,3,3,9,11};
    //이를 활용하여 동일 원소의 개수를 구할 수도 있음!
    cout << upper_bound(v_bound.begin(), v_bound.end(), 3) - lower_bound(v_bound.begin(), v_bound.end(), 3)<< endl; // 주소값이 리턴되기 때문에 역참조연산을 통해서 값확인가능

    //해당 조건을 만족시키는 경우가 없는경우 근방 지점 리턴
    cout << upper_bound(v_bound.begin(), v_bound.end(), 13) - v_bound.begin() << endl; // 13초과인 부분이 없으므로, 그중에 조건에 가장 가까운 지점 리턴
    cout << endl;
}
#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    cout << "Unique" << endl;
    vector<int> v_unique;

    // 연속된 원소를 제거하는 것에 가까움! 따라서 sort()랑 같이 사용해 주어야 한다.
    v_unique = {1,1,2,2,3,4,5};
    auto it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    v_unique = {3,3,5,3,2,3};
    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique){
        cout << v ;
    }
    cout << endl;

    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    sort(v_unique.begin(), v_unique.end());
    it = unique(v_unique.begin(), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    //Erase 함수까지 사용하면 깔끔하게 중복되지 않은 요소만 돌려받을 수 있음!
    v_unique.erase(unique(v_unique.begin(), v_unique.end()), v_unique.end());
    for(int v : v_unique)cout << v ;
    cout << endl;

    cout << "upper_bound(), lower_bound()" << endl;

    vector<int> v_bound = {1,3,5,7,9,11};
    cout << lower_bound(v_bound.begin(), v_bound.end(), 5) - v_bound.begin() << endl; // 5이상인 지점 반환
    cout << lower_bound(v_bound.begin(), v_bound.end(), 6) - v_bound.begin() << endl; // 6이상인 지점 반환
    cout << upper_bound(v_bound.begin(), v_bound.end(), 5) - v_bound.begin() << endl; // 5초과인 지점 반환

    cout << *lower_bound(v_bound.begin(), v_bound.end(), 5)<< endl; // 주소값이 리턴되기 때문에 역참조연산을 통해서 값확인가능
    
    v_bound = {1,3,3,3,9,11};
    //이를 활용하여 동일 원소의 개수를 구할 수도 있음!
    cout << upper_bound(v_bound.begin(), v_bound.end(), 3) - lower_bound(v_bound.begin(), v_bound.end(), 3)<< endl; // 주소값이 리턴되기 때문에 역참조연산을 통해서 값확인가능

    //해당 조건을 만족시키는 경우가 없는경우 근방 지점 리턴
    cout << upper_bound(v_bound.begin(), v_bound.end(), 13) - v_bound.begin() << endl; // 13초과인 부분이 없으므로, 그중에 조건에 가장 가까운 지점 리턴
    cout << endl;

    /////////////////////////////////////////////////////////////////////////////
    cout << "accumulate()" << endl;
    vector<int> v_acc = {1,2,3,4,5,6,7,8,9};
    int sum = accumulate(v_acc.begin(), v_acc.end(),0); //numeric lib을 import 해주어야 한다. 
    cout << sum << endl << endl;

    /////////////////////////////////////////////////////////////////////////////////
    cout << "max_element(), min_element" << endl;
    vector<int> v_mm = {1,2,3,4,5,6,7,8,9};
    cout << *max_element(v_mm.begin(), v_mm.end()) << endl; // 이터레이터가 반환되므로 역참조 연산으로 값 확인가능
    cout << max_element(v_mm.begin(), v_mm.end()) - v_mm.begin() << endl; // index 값 확인도 가능!

    cout << *min_element(v_mm.begin(), v_mm.end()) << endl; 
    cout << min_element(v_mm.begin(), v_mm.end()) - v_mm.begin() << endl;
}

0개의 댓글