도순씨의 코딩일지

C++ :: STL 원소를 수정하는 알고리즘 & 제거 알고리즘 본문

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

C++ :: STL 원소를 수정하는 알고리즘 & 제거 알고리즘

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

원소를 수정하는 알고리즘(modifying algorithms)은 원소의 값을 변경하거나 목적지 순차열로 원소를 복사하는 알고리즘입니다. 

 

v1의 순차열을 v2의 순차열로 복사하는 copy() 알고리즘 예제입니다.

 

⭐️ copy() 알고리즘

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);
 
    vector<int> v2(5);
 
    vector<int>::iterator iter;
    iter = copy(v1.begin(), v1.end(), v2.begin());
    cout << "v2 마지막 원소: " << *(iter-1<< endl;
 
    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;
 
    return 0;
}
cs

 

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

1
2
3
v2 마지막 원소: 50
v1 : 10 20 30 40 50 
v2: 10 20 30 40 50 
cs

 

v1의 순차열을 모두 0으로 채우거나 일부로 55로 채우는 fill(), fill_n() 알고리즘 예제입니다.

 

⭐️ fill(), fill_n() 알고리즘

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
#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(50);
 
    fill(v.begin(), v.end(), 0);
    cout << "v: ";
    for(vector<int> :: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    fill_n(v.begin(), 355);
    cout << "v: ";
    for(vector<int> :: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    return 0;
}
cs

 

⭐️ fill(), fill_n() 알고리즘 실행결과

1
2
v: 0 0 0 0 0 
v: 55 55 55 0 0 
cs

 

for_each()와 transform()이 있으며 for_each() 알고리즘은 출력 매개변수를 사용하고 transform()은 함수의 반환 값을 사용하여 사용자 동작을 원소를 적용합니다.

 

⭐️ 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
27
28
29
30
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
void Func(int& r){
    r += 5;
}
 
int main(){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(50);
 
    cout << "v: ";
    for(vector<int> :: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    for_each(v.begin(), v.end(), Func);
    cout << "v: ";
    for(vector<int>::size_type i = 0; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
    
    return 0;
}
cs

 

⭐️ for_each() 알고리즘을 사용한 원소의 수정

1
2
v: 10 20 30 40 50 
v: 15 25 35 45 55 
cs

 

Func을 통해서 각각의 원소에 += 5를 해줍니다.

 

 

제거 알고리즘은 원소를 수정하는 알고리즘의 특수한 형태입니다. 실제로는 원소를 제거하는 것이 아니라 논리적으로 제거하는 방법입니다.

 

다음은 순차열에서 30원소를 제거하는 remove() 알고리즘 예제입니다.

 

⭐️ remove() 알고리즘

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> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);
    v.push_back(50);
 
    cout << "v: ";
    for(vector<int>::size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int>::iterator iter_end;
    iter_end = remove(v.begin(), v.end(), 30);  // 값으로 지정
 
    cout << "v: ";
    for(vector<int>::size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    cout << "remove 후 [v.begin(), iter_end) 순차열: ";
    for(vector<int> :: iterator iter = v.begin() ; iter != iter_end ; ++iter)
        cout << *iter << " ";
    cout << endl;
 
    return 0;
}
cs

 

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

1
2
3
v: 10 20 30 40 50 
v: 10 20 40 50 50 
remove 후 [v.begin(), iter_end) 순차열: 10 20 40 50 
cs

 

만약 실제로 존재하는 원소까지 존재하고 싶다면 erase() 함수를 사용하면 됩니다.

 

다음은 30이상 40 이하의 원소를 제거하는 remove_if() 알고리즘 예제입니다.

 

⭐️ remove_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
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
bool Pred(int n){
    return 30<= n && n <= 40;
}
 
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);
 
    cout<< "v : ";
    for(vector<int> :: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int>::iterator iter_end;
    iter_end = remove_if(v.begin(), v.end(), Pred);
 
    cout << "[v.begin(), iter_end) : ";
    for(vector<int>::iterator iter = v.begin() ; iter != iter_end ; ++iter)
        cout << *iter << " ";
    cout << endl;
 
    return 0;
}
cs

 

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

1
2
v : 10 20 30 40 50 
[v.begin(), iter_end) : 10 20 50 
cs

 

다음은 인접한 중복 원소 30과 40 원소를 유일하게 만드는 unique() 알고리즘입니다.

 

⭐️ unique() 알고리즘

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
#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(30);
    v.push_back(40);
    v.push_back(40);
    v.push_back(30);
    v.push_back(50);
 
    cout << "v: ";
    for(vector<int> :: size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
 
    vector<int> :: iterator iter_end;
    iter_end = unique(v.begin(), v.end());
 
    cout << "v : ";
    for(vector<int>::size_type i = 0 ; i < v.size() ; ++i)
        cout << v[i] << " ";
    cout << endl;
    cout << "[v.begin(), iter_end : ";
 
    for(vector<int>::iterator iter = v.begin() ; iter != iter_end ; ++ iter)
        cout << *iter << " ";
    cout << endl;
 
    return 0;
}
cs

 

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

1
2
3
v: 10 20 30 30 40 40 30 50 
v : 10 20 30 40 30 50 30 50 
[v.begin(), iter_end : 10 20 30 40 30 50 
cs

 

📚 출처

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

Comments