도순씨의 코딩일지

C++ :: STL 원소를 수정하지 않는 알고리즘 본문

𝐏𝐑𝐎𝐆𝐑𝐀𝐌𝐌𝐈𝐍𝐆/𝐂++

C++ :: STL 원소를 수정하지 않는 알고리즘

도순씨 2020. 9. 23. 00:00

원소를 수정하지 않는 알고리즘(nonmodifying algorithms)은 원소의 순서나 원소의 값을 변경하지 않고 원소를 읽기만 하는 알고리즘입니다. 먼저 다음 예제는 adjacent_find() 알고리즘 예제로 vector의 순차열에서 현재 원소와 다음 원소가 같아지는 첫 원소의 반복자를 반환합니다.

 

⭐️ adjacent_find() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(30);
    v.push_back(40);
    v.push_back(40);
    v.push_back(50);
 
    for(vector<int> :: size_type i = 0 ; i < v.size(); ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int> :: iterator iter;
    iter = adjacent_find(v.begin(), v.end());
 
    if(iter != v.end())
        cout << *iter << endl;
 
    for(; iter != v.end() ; ++iter)
        cout << *iter << " ";
    cout << endl;
 
    return 0;
}
cs

 

⭐️ adjacent_find() 알고리즘

1
2
3
10 20 30 30 40 40 50 
30
30 30 40 40 50 
cs

 

다음 예제는 인접해 있는(현재 원소와 다름 원소) 원소의 차가 10보다 큰 첫 원소의 반복자를 반환하는 예제입니다.

 

⭐️ adjacent_find() 조건자 버전

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
// 이항 조건자
bool Pred(int a, int b){
    return abs(b-a) > 10;
}
 
int main(void){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(50);
    v.push_back(90);
 
    for(vector<int> :: size_type i = 0 ; i < v.size(); ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int>::iterator iter;
    iter = adjacent_find(v.begin(), v.end(), Pred);
 
    if(iter != v.end())
        cout << *iter << endl;
 
    for( ; iter != v.end() ; ++ iter)
        cout << *iter << " ";
    cout << endl;
 
    return 0;
}
cs

 

⭐️ adjacent_find() 조건자 버전

1
2
3
10 20 30 50 90 
30
30 50 90 
cs

 

순차열에서 원소의 개수를 구하려면 count() 알고리즘을 사용합니다.

 

⭐️ count() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(30);
    v.push_back(50);
 
    for(vector<int>::size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    int n = count(v.begin(), v.end(), 30);
    cout << "30의 개수: " << n << endl;
 
    return 0;
}
cs

 

⭐️ count() 알고리즘 실행결과

1
2
10 20 30 40 30 50 
30의 개수: 2
cs

 

조건자 버전의 count_if()를 사용하여 원소가 25보다 큰 원소의 개수를 출력하는 예제입니다.

 

⭐️ 조건자 버전의 count_if()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
bool Pred(int n){
    return 25 < n;
}
 
int main(void){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(50);
    
    for(vector<int>::size_type i = 0 ; i < v.size() ; ++ i)
        cout << v[i] << " ";
    cout << endl;
    
    int n = count_if(v.begin(), v.end(), Pred);
    cout << "25보다 큰 원소의 개수: " << n << endl;
    
    return 0;
}
cs

 

⭐️ 조건자 버전의 count_if() 실행결과

1
2
10 20 30 40 30 50 
30의 개수: 2
cs

 

다음은 두 순차열의 원소를 비교는 equal() 알고리즘 예제입니다.

 

⭐️ equal() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
 
    vector<int> v2;
    v2.push_back(10);
    v2.push_back(20);
    v2.push_back(30);
    v2.push_back(40);
    v2.push_back(50);
 
    cout << "v1 : ";
    for(vector<int> :: size_type i = 0; i < v1.size() ; ++i)
        cout << v1[i] << " ";
    cout << endl;
 
    cout << "v2: ";
    for(vector<int> :: size_type i = 0 ; i < v2.size() ; ++i)
        cout << v2[i] << " ";
    cout << endl;
 
    if(equal(v1.begin(), v1.end(), v2.begin()))
        cout << "두 순차열은 같습니다." << endl;
 
    return 0;
}
cs

 

⭐️ equal() 알고리즘 실행결과

1
2
3
v1 : 10 20 30 
v2 : 10 20 30 40 50 
두 순차열은 같습니다.
cs

 

find()는 특정 원소를 찾는 알고리즘이고 find_if()는 조건에 따라 원소를 찾는 알고리즘입니다.

 

⭐️ find() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
bool Pred(int n){
    return 35 < n;
}
 
int main(void){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(50);
 
    for(vector<int>:: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int>::iterator iter;
    iter = find(v.begin(), v.end() ,20);
    if(iter != v.end())
        cout << *iter << "을 찾다!" << endl;
 
    iter = find_if(v.begin(), v.end(), Pred);
    if(iter != v.end())
        cout << "순차열에서 35보다 큰 첫 번째 원소: " << *iter << endl;
 
    return 0;
}
cs

 

⭐️ find() 알고리즘 실행결과

1
2
3
10 20 30 40 50 
20을 찾다!
순차열에서 35보다 큰 첫 번째 원소: 40
cs

 

find_end() 알고리즘을 컨테이너 v1의 순차열에 v2의 순차열이 포함되는지를 판단하는 예제입니다.

 

⭐️ find_end() 알고리즘 이용해 컨테이너 판단

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    v1.push_back(60);
    v1.push_back(70);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
 
    vector<int> v2;
    v2.push_back(30);
    v2.push_back(40);
    v2.push_back(50);
 
    vector<int> :: iterator iter;
    iter = find_end(v1.begin(), v1.end() , v2.begin(), v2.end());
    if(iter != v1.end()){
        cout << "iter : " << *iter << endl;
        cout << "iter-1 : " << *(iter - 1<< endl;
        cout << "iter+1 : " << *(iter + 1<< endl;
    }
    return 0;
}
cs

 

⭐️ find_end() 알고리즘 이용해 컨테이너 판단 실행결과

1
2
3
iter : 30
iter-1 : 70
iter+1 : 40
cs

 

find_first_of() 알고리즘은 두 순차열을 비교하여 모든 원소 중 같은 원소가 하나라도 발견되면 발견된 첫 원소의 반복자를 반복합니다.

 

⭐️ find_first_of() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
 
    vector<int> v2;
    v2.push_back(40);
    v2.push_back(80);
    v2.push_back(20);
 
    cout << "v1 : ";
    for(vector<int>::size_type i = 0 ; i < v1.size() ; ++i)
        cout << v1[i] << " ";
    cout << endl;
 
    cout << "v2 : ";
    for(vector<int> :: size_type i = 0 ; i < v2.size() ; ++i)
        cout << v2[i] << " ";
    cout << endl;
 
    vector<int> :: iterator iter;
    iter = find_first_of(v1.begin(), v1.end(), v2.begin(), v2.end());
    if(iter != v1.end())
        cout << "iter: " << *iter << endl;
 
    return 0;
}
cs

 

⭐️ find_first_of() 알고리즘

1
2
3
v1 : 10 20 30 40 50 
v2 : 40 80 20 
iter: 20
cs

 

 

for_each() 알고리즘을 사용하여 모든 원소를 출력하는 예제입니다.

 

⭐️ for_each() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
void Print(int n){
    cout << n << " ";
}
 
int main(void){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(50);
 
    for_each(v.begin(), v.begin()+2, Print);
    cout << endl;
    for_each(v.begin(), v.begin() + 4, Print);
    cout << endl;
    for_each(v.begin(), v.end(), Print);
    cout << endl;
 
    return 0;
}
cs

 

⭐️ for_each() 알고리즘 실행결과

1
2
3
10 20 
10 20 30 40 
10 20 30 40 50 
cs

 

vector v1, v2, v3의 순차열을 lexicographical_compare() 알고리즘으로 비교한 것입니다.

 

⭐️ lexicographica_compare() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
template<typename T>
struct Less{
    bool operator()(const T& left, const T& right) const{
        return left < right;
    }
};
 
int main(){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
 
    vector<int> v2;
    v2.push_back(10);
    v2.push_back(25);
    v2.push_back(30);
 
    if(lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end(), less<int>()))
        cout << "기준 less v1과 v2의 비교: true" << endl;
    else
        cout << "기준 less v1과 v2의 비교: false" << endl;
 
    if(lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end(), greater<int>()))
        cout << "기준 greater v1과 v2 비교: true" << endl;
    else
        cout << "기준 greater v1과 v2의 비교: false" << endl;
 
    if(lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end(), Less<int>()))
        cout << "사용자 기준 Less v1과 v2의 비교: true" << endl;
    else
        cout << "사용자 기준 Less v1과 v2의 비교: false" << endl;
 
    return 0;
}
cs

 

⭐️ lexicographica_compare() 알고리즘 실행결과

1
2
3
기준 less v1과 v2의 비교: true
기준 greater v1과 v2의 비교: false
사용자 기준 Less v1과 v2의 비교: true
cs

 

max(), min() 알고리즘을 사용해보는 예제입니다.

 

⭐️ max(), min() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
class Point{
    int x, y;
public:
    explicit Point(int _x = 0int _y = 0) : x(_x), y(_y) {}
    int GetX() const {return x;}
    int GetY() const {return y;}
    void Print() const { cout << '(' << x << ',' << y << ')' << endl;}
};
 
bool XCompare(const Point& left, const Point& right){
    return left.GetX() < right.GetX();
}
 
bool YCompare(const Point& left, const Point& right){
    return left.GetY() < right.GetY();
}
 
int main(void){
    int a = 10, b = 20;
    int r;
 
    r = max(a, b);
    cout << "max: " << r << endl;
    r = min(a, b);
    cout << "min: " << r << endl;
 
    Point pt1(58), pt2(39);
    Point pt3;
 
    pt3 = max(pt1, pt2, XCompare);
    cout << "x max: "; pt3.Print();
    pt3 = max(pt1, pt2, YCompare);
    cout << "y max: "; pt3.Print();
 
    return 0;
}
cs

 

⭐️ max(), min() 알고리즘 실행결과

1
2
3
4
max: 20
min: 10
x max: (5,8)
y max: (3,9)
cs

 

vector 순차열에서 가장 큰 원소와 가장 작은 원소를 찾아 출력하는 예제입니다.

 

⭐️ max_element(), min_element() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v;
 
    v.push_back(30);
    v.push_back(10);
    v.push_back(20);
    v.push_back(50);
    v.push_back(40);
 
    vector<int>::iterator iter;
    iter = max_element(v.begin(), v.end());
    cout << *iter << endl;
 
    iter = min_element(v.begin(), v.end());
    cout << *iter << endl;
 
    return 0;
}
cs

 

⭐️ max_element(), min_element() 알고리즘 실행결과

1
2
50
10
cs

 

두 순차열을 비교하여 원소의 값이 서로 다른 위치를 찾는 mismatch() 알고리즘 예제입니다.

 

⭐️ mismatch() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
 
    vector<int> v2;
    v2.push_back(10);
    v2.push_back(20);
    v2.push_back(30);
    v2.push_back(80);
    v2.push_back(90);
 
    pair<vector<int> :: iteratorvector<int> :: iterator> iter_pair;
    iter_pair = mismatch(v1.begin(), v1.end(), v2.begin());
 
    cout << "v1: " << *iter_pair.first << ", " << "v2: "
        << *iter_pair.second << endl;
 
    return 0;
}
cs

 

⭐️ mismatch() 알고리즘 실행결과

1
v1: 40, v2: 80
cs

 

find_end() 알고리즘 예제를 search() 알고리즘으로 변환한 예제입니다.

 

⭐️ search() 알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void){
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    v1.push_back(70);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
 
    vector<int> v2;
    v2.push_back(30);
    v2.push_back(40);
    v2.push_back(50);
 
    vector<int> :: iterator iter;
    iter = search(v1.begin(), v1.end(), v2.begin(), v2.end());
    if(iter != v1.end()){
        cout << "iter: " << *iter << endl;
        cout << "iter-1: " << *(iter-1<< endl;
        cout << "iter+1: " << *(iter+1<< endl;
    }
    return 0;
}
cs

 

⭐️ search() 알고리즘 예제

1
2
3
iter: 30
iter-1: 20
iter+1: 40
cs

 

📚 출처

공동환(2012), 뇌를 자극하는 C++ STL, 한빛미디어.

Comments