STL 제네릭 알고리즘 정리 DarkKaiser, 2007년 7월 17일2023년 9월 6일 accumulate() 기본적으로, 컨테이너의 요소들을 세 번째 인수로 지정한 초기값에 모두 더합니다. 기본 덧셈을 오버라이딩하기 위해 이항 연산을 넘길 수 있습니다. #include <numeric> iresult = accumulate(ia, ia + 9, 0); iresult = accumulate(ilist.begin(), ilist.end(), 0, plus<int>()); adjacent_difference() 기본적으로 주어진 열 내에서 인접하는 각 요소의 차이를 값으로 하는 새로운 열을 생성합니다. {0, 1, 1, 2, 3, 5, 8}이 주어진다면 그 결과는 {0, 1, 0, 1, 1, 2, 3}이 됩니다. 기본 뺄셈을 오버라이딩하는 이항 연산을 넘길 수 있습니다. 예를 들면, times<int>는 {0, 0, 1, 2, 6, 15, 40}이라는 결과를 도출합니다. 세 번째 인수는 결과가 복사될 컨테이너를 가리키는 반복자입니다. #include <numeric> adjacent_difference(ilist.begin(), ilist.end(), iresult.begin()); adjacent_difference(ilist.begin(), ilist.end(), iresult.begin(), times<int>()); adjacent_find() 기본적으로 중복된 요소가 인접된 최초의 곳을 찾습니다. 기본 상등 연산자(==)를 오버라이딩하기 위해 이항 연산을 넘길 수 있습니다. 찾은 요소를 가리키는 반복자를 반환합니다. #include <algorithm> class TwiceOver { public: bool operator() (int val1, int val2) { return val1 == val2 / 2 ? true : false; } } piter = adjacent_find(ia, ia + 8); iter = adjacent_find(vec.begin(), vec.end(), TwiceOver()); binary_search() 컨테이너가 보다 작은가의 비교 연산자(<)로 정렬되어 있다고 가정합니다. 컨테이너가 다른 관계로 정렬되어 있다면 그에 대한 이항 연산자를 넘겨야 합니다. 알고리즘은 true나 false를 반환합니다. #include <algorithm> found_it = binary_search(ilist.begin(), ilist.end(), value); found_it = binary_search(vec.begin(), vec.end(), value, greator<int>()); copy() 한 컨테이너의 요소들을 다른 컨테이너로 복사합니다. #include <algorithm> ostream_iterator<int> ofile(cout, " "); copy(vec.begin(), vec.end(), ofile); vector<string> target(svec.size()); copy(svec.begin(), svec.end(), target.begin()); copy_backward() copy()와 동일하게 동작하시만, 요소들을 반대의 순서로 복사합니다. #include <algorithm> copy_backward(svec.begin(), svec.end(), target.begin()); count() 컨테이너 내에서 value와 같은 요소의 개수를 반환합니다. #include <algorithm> cout << value << " occurs " << count(svec.begin(), svec.end(), value) << " times in string vector.\n"; count_if() 연산의 결과가 true로 계산되는 요소의 개수를 반환합니다. #include <algorithm> class Even { public: bool operator()(int val) { return !(val % 2); } } ires = count_if(ia, ia + 8, bind2nd(less<int>(), 10)); ires = count_if(ilist.begin(), ilist.end(), Even()); equal() 두 열이 서로 같다면 true를 반환합니다. 이때 첫 컨테이너를 기준으로 하기 때문에 첫 컨테이너에 있는 요소의 개수만큼 비교됩니다. 기본적으로, 상등 연산자(==)가 사용되고, 함수 객체나 함수의 포인터를 지정할 수도 있습니다. #include <algorithm> class EqualAndOdd { public: bool operator()(int v1, int v2) { return ((v1 == v2) && (v1 % 2)); } } int ia1[] = {1, 1, 2, 3, 5, 8, 13}; int ia2[] = {1, 1, 2, 3, 5, 8, 13, 21, 34}; res = equal(ia1, ia1 + 7, ia2); /* true */ res = equal(ia1, ia1 + 7, ia2, equalAndOdd()); /* false */ fill() 컨테이너 내에 있는 각 요소들에 대해 value를 대입합니다. #include <algorithm> fill(ivec.begin(), ivec.end(), value); fill_n() 컨테이너 내에 있는 각 요소들에 대해 value를 count의 개수만큼 대입합니다. #include <algorithm> fill_n(ia, count, value); fill_n(svec.begin(), count, string_value); find() 컨테이너 내의 각 요소들을 value와 같은지 비교합니다. 같은 요소가 있다면 비교를 중단하고, 그 요소의 반복자를 반환합니다. 같은 요소가 없으면 container.end()를 반환합니다. #include <algorithm> piter = find(ia, ia + 8, value); iter = find(svec.begin(), svec.end(), "rosebud"); find_end() 이 알고리즘은 두 쌍의 반복자를 매기변수로 받습니다. 첫 쌍은 검색될 컨테이너를 나타내고, 두 번째의 쌍은 검색할 열을 나타냅니다. 첫 컨테이너 내의 요소들에서 상등 연산자(==)나 지정된 이항 연산을 사용해서 마지막으로 일치되는 열을 찾습니다. 일치되면 일치된 열의 첫 요소를 가리키는 반복자를 반환합니다. 일치되는 요소가 없으면 첫 컨테이너의 끝을 표시하는 반복자를 반환합니다. 예를 들어 Mississippi라는 열이 주어졌을 때 두 번째 열이 ss라면 find_end()는 두 번째 ss의 첫 글자인 s를 가리키는 반복자를 반환합니다. #include <algorithm> int ia[17] = {7, 3, 3, 7, 6, 5, 8, 7, 2, 1, 3, 7, 6, 3, 8, 4, 3}; int seq[3] = {3, 7, 6}; /* found_it은 ia[10]을 가리키게 됩니다. */ found_it = find_end(ia, ia + 17, seq, seq + 3); find_first_of() find_first_of()는 두 쌍의 반복자를 매개변수로 받습니다. 첫 쌍은 검색될 요소들을 표시하고, 두 번째 쌍은 검색할 요소들의 모음을 표시합니다. 예를 들어, synesthesia라는 문자열에서 첫 모음을 찾으려면 두 번째 열을 aeiou로 정의합니다. find_first_of()는 모음이 처음으로 나타나는 요소의 반복자를 반환합니다. 이 경우는 최초의 e가 됩니다. 일치되는 것이 없으면 첫 열의 마지막을 가리키는 반복자를 반환합니다. 다섯 번째 매개변수로 기본 상등 연산자를 오버라이딩 할 수 있는 이항 연산을 추가할 수도 있습니다. #include <algorithm> string s_array[] = {"Ee", "eE", "ee", "Oo", "oo", "ee"}; string to_find[] = {"oo", "gg", "ee"}; /* &s_array[2]에 있는 최초의 "ee"를 반환합니다. */ found_it = find_first_of(s_array, s_array + 6, to_find, to_find + 3); find_if() 컨테이너 내의 요소들을 지정된 이항 연산으로 비교합니다. 일치되는 요소가 발견되면 검색이 중단됩니다. find_if()는 일치된 요소의 반복자를 반환하고, 일치되는 요소가 없으면 container.end()를 반환합니다. #include <algorithm> find_if(vec.begin(), vec.end(), LessThanVal(ival)); for_each() for_each()는 세 번째 매개변수로 받은 연산을 각 요소들에 적용합니다. 이 연산은 요소들을 수정할 수는 없습니다(transform()을 쓰면 수정할 수 있습니다). 연산이 값을 반환해도 그 값은 무시됩니다. #include <algorithm> template<typename Type> void print_elements(Type elem) { cout << elem << " "; }; for_each(ivec.begin(), ivec.end(), print_elements); generate() generate()는 지정된 생성자를 적용시켜 열을 채우게 됩니다. #include <algorithm> class GenByTwo { void operator() { static int seed = -1; return seed += 2; } }; list<int> ilist<10>; /* ilist에 채워질 값: 1 3 5 7 9 11 13 15 17 19 */ generate(ilist.begin(), ilist.end(), GenByTwo()); generate_n() generate_n()은 지정된 생성자를 n부터 호출해 열을 채우게 됩니다. #include <algorithm> class gen_by_two { public: gen_by_two(int seed = 0) : _seed(seed) {} int operator()() { return _seed += 2; } private: int _seed; }; vector<int> ivec(10); /* ivec에 채워질 값: 102 104 106 108 110 112 114 116 118 120 */ generate_n(ivec.begin(), ivec.size(), gen_by_two(100)); includes() 두 번째 열의 모든 요소가 첫 번째 열에 포함되어 있다면 includes()는 true를 반환하고, 그렇지 않으면 false를 반환합니다. 양쪽 열 모두 기본 비교 연산자(<)나 지정된 연산으로 정렬하여 있어야 합니다. 지정된 연산은 다섯 번째 매개변수로 넘겨집니다. #include <algorithm> int ia1[] = {13, 1, 21, 2, 0, 34, 5, 1, 8, 3, 21, 34}; int ia2[] = {21, 2, 8, 3, 5, 1}; /* includes에는 정렬된 컨테이너를 넘겨야 합니다. */ sort(ia1, ia1 + 12); sort(ia2, ia2 + 6); res = includes(ia1, ia1 + 12, ia2, ia2 + 6); // true inner_product() inner_product()는 두 열의 내적(inner product)값을 사용자가 지정한 초기값에 차례로 더합니다. 예를 들어, 두 열 {2,3,5,8}과 {1,2,3,4}가 주어졌다면 결과값은 (2*1)+(3*2)+(5*3)+(8*4)가 됩니다. 만약 초기값으로 0을 주었다면 결과는 55가 됩니다. 두 번째 형태는 기본 덧셈과 곱셈 연산을 오버라이딩할 수 있습니다. 예를 들어, 같은 열에 대해 뺄셈과 덧셈을 지정하면 결과는 (2+1)-(3+2)-(5+3)-(8+4)가 됩니다. 초기값으로 0을 주었으면 결과는 -28이 됩니다. #include <numeric> int ia[] = {2, 3, 5, 8}; int ia2[] = {1, 2, 3, 4}; int res = inner_product(ia, ia + 4, ia2, 0); vector<int> vec(ia, ia + 4); vector<int> vec2(ia2, ia2 + 4); res = inner_product(vec.begin(), vec.end(), vec2.begin(), 0, minus<int>(), plus<int>()); inplace_merge() inplace_merge()는 first, middle, last라는 세 개의 반복자를 매개변수로 받습니다. 두 입력열은 [first, middle]과 [middle, last]로 표시죕니다(middle은 첫 열의 마지막 요소에서 하나가 더 지납니다). 이 열들은 연속적이어야 합니다. 결과 열은 first에서 시작해 두 범위를 모두 덮어씁니다. 선택적인 네 번째 매개변수에 기본 연산자가 아닌 다른 정렬 알고리즘을 지정할 수 있습니다. #include <algorithm> int ia[20] = {29, 23, 20, 17, 15, 26, 51, 12, 35, 40, 74, 16, 54, 21, 44, 62, 10, 41, 65, 71}; int *middle = ia + 10, *last = ia + 20; /* 12 15 17 20 23 26 29 35 40 51 10 16 21 41 44 54 62 65 71 74 */ sort(ia, middle); sort(middle, last); /* 10 12 15 16 17 20 21 23 26 29 35 40 41 44 51 54 62 65 71 74 */ inplace_merge(ia, middle, last); iter_swap() 두 반복자가 가리키는 요소들 안에 저장된 값들을 바꿉니다. #include <algorithm> typedef list<int>::iterator iterator; iterator it1 = ilist.begin(), it2 = ilist.begin() + 4; iter_swap(it1, it2); lexicographical_compare() 기본적으로, 보다 작은가의 비교 연산자(<)가 적용됩니다. 선택적인 다섯 번째 매개변수로 다른 배치 연산을 제공할 수도 있습니다. 첫째 열이 둘째 열보다 작거나 같다면 true가 반환됩니다. #include <algorithm> class size_compare { public: bool operator()(const string& a, const string& b) { return a.length() <= b.length(); } }; string sa1[] = {"Piglet", "Pooh", "Tigger"}; string sa2[] = {"Piglet", "Pooch", "Eeyore"}; /* 'c'가 'h' 보다 작기 때문에 false */ res = lexicographical_compare(sa1, sa1 + 3, sa2, sa2 + 3); list<string> ilist1(sa1, sa1 + 3); list<string> ilist2(sa2, sa2 + 3); /* Pooh < Pooch이므로 true */ res = lexicographical_compare(ilist1.begin(), ilist1.end(), ilist2.begin(), ilist2.end(), size_compare()); max(), min() 두 요소 중 더 큰것(혹은 더 작은 것)을 반환합니다. 세 번째 매개변수에 다른 비교 연산을 제공할 수도 있습니다. max_element(), min_element() 열 내에서 가장 큰 값(혹은 가장 작은 값)을 가리키는 반복자를 반환합니다. 세 번째 매개변수에 다른 비교 연산을 제공할 수도 있습니다. #include <algorithm> int mval = max(max(max(max(ivec[4], ivec[3]), ivec[2]), ivec[1]), ivec[0]); mval = min(min(min(min(min(ivec[4], ivec[3]), ivec[2]), ivec[1]), ivec[0]); vector<int>::const_iterator iter; iter = max_element(ivec.begin(), ivec.end()); iter = min_element(ivec.begin(), ivec.end()); merge() 두 개의 정렬된 열을 다섯 번째 반복자가 가리키는 하나의 정렬된 열로 합칩니다. 선택적으로, 여섯 번째 매개변수에 기본 비교 연산자가 아닌 다른 정렬 연산자를 줄 수도 있습니다. #include <algorithm> int ia[12] = {29, 23, 20, 22, 17, 15, 26, 51, 19, 12, 35, 40}; int ia2[12] = {74, 16, 39, 54, 21, 44, 62, 10, 27, 41, 65, 71}; vector<int> vec1(ia, ia + 12), vec2(ia2, ia2 + 12); vector<int> vec_result(vec1.size() + vec2.size()); sort(vec1.begin(), vec1.end(), greater<int>()); sort(vec2.begin(), vec2.end(), greater<int>()); merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec_result.begin(), greater<int>()); nth_element() nth_element()는 nth 요소보다 작은 모든 요소들이 앞에 나타나고, 그보다 큰 모든 요소들이 뒤에 나오도록 열을 재배치합니다. 예를 들어, 다음의 열이 주어졌다면 int ia[] = {29, 23, 20, 22, 17, 15, 26, 51, 19, 12, 35, 40}; nth로 ia + 6(이 값은 26)을 표시하여 nth_element()를 호출해보겠습니다. nth_element(ia, ia + 6, &ia?12); 이 결과는 26보다 작은 7의 요소는 왼쪽에 위치되고, 26보다 큰 4개의 요소는 26의 오른쪽에 위치됩니다. {23, 20, 22, 17, 15, 19, 12, 26, 51, 35, 40, 29} nth 요소의 양쪽에 있는 요소들은 특정한 순서로 되어 있음을 보증할 수 없습니다. 선택적으로, 네 번째 매개변수에 기본 비교 연산자를 대신할 수 있는 비교를 지정할 수 있습니다. partial_sort(), partial_sort_copy() partial_sort()는 first, middle, last의 세 매개변수를 받습니다. 선택적으로 다른 배치 연산을 제공하는 네 번째 매개변수를 받을 수 잇습니다. 반복자 first와 middle은 컨테이너의 정렬된 요소들을 배치시킬 슬롯의 범위를 표시합니다(middle은 유효한 슬롯의 마지막보다 1이 큽니다). middle에서 last까지 저장된 요소들은 정렬되지 않았습니다. 예를 들어, 다음 배열이 주어졌다면 int ia[] = {29, 23, 20, 22, 17, 15, 26, 51, 19, 12, 35, 40}; middle로 여섯 번째 요소를 표시해서 partial_sort()를 호출하겠습니다. partial_sort(ia, ia + 5, ia + 12); 이렇게 하면 가장 작은 다섯 요소들이 정렬됩니다. {12, 15, 17, 19, 20, 29, 23, 22, 26, 51, 35, 40} middle에서 last -1까지의 요소들은 특정한 순서로 배치되지 않습니다. partial_sum() 기본적으로, 각 요소가 이전의 모든 요소들부터 그 위치까지를 합으로 하는 새로운 열을 만듭니다. 예를 들어, {0, 1, 1, 2, 3, 5, 8}의 열이 주어졌다면 새로운 열은 {0, 1, 2, 4, 7, 12, 20}이 됩니다. 네 번째 요소를 예로 들면, 이전의 세 값인 (0, 1, 1)의 합과 자신인 (2)를 더합니다. 선택적으로, 네 번째 매개변수에 적용될 연산을 지정할 수도 있습니다. #include <numeric> int ires[7], ia[7] = {1, 3, 4, 5, 7, 8, 9}; vector<int> vres(7), vec(ia, ia + 7); /* partial_sum(): 1 4 8 13 20 28 37 */ partial_sum(ia, ia + 7, ires); /* times<int>()를 사용한 partial_sum: 1 3 12 60 420 3360 30240 */ partial_sum(vec.begin(), vec.end(), vres.begin(), times<int>()); partition(), stable_partition() partition()은 단항 연산의 결과인 true/false에 따라 요소들을 재배치시킵니다. true로 계산된 모든 요소들은 false로 계산된 요소들의 앞에 위치됩니다. 예를 들어, {0, 1, 2, 3, 4, 5, 6}의 열이 주어지고 짝수인지를 검사한다면 true와 false는 각각 {0, 2, 4, 6}과 {1, 3, 5}가 됩니다. 모든 짝수 요소들은 홀수 요소들의 앞에 위치되지만, 재배치된 열에서 각각의 상대적인 위치가 유지되는 것은 보증할 수 없습니다. stable_partition()은 상대적인 위치까지 유지시키는 것을 보증합니다. #include <algorithm> class even_elem { public: bool operator()(int elem) { return elem % 2 ? false : true; } }; int ia[] = {29, 23, 20, 22, 17, 15, 26, 51, 19, 12, 35, 40}; vector<int> vec(ia, ia + 12); /* 요소가 짝수인지에 따라 재배치: 40 12 20 22 26 15 17 51 19 23 35 29 */ stable_partition(vec.begin(), vec.end(), even_elem()); random_shuffle() 기본적으로, random_shuffle()은 항들이 자신의 알고리즘에 따라 무작위적으로 배치합니다. 선택적으로, 세 번째 매개변수에 난수를 생성하는 연산을 넘길 수도 있습니다. 이 연산은 [0, 1] 사이에서 double 타입의 값을 반환해야 합니다. #include <algorithm> random_shuffle(ivec.begin(), ivec.end()); remove(), remove_copy() remove()는 열 내에서 value와 같은 모든 요소들은 분리시켜 냅니다. 일치된 요소들을 실제로 지우지는 않습니다(컨테이너 크기는 그대로 유지됩니다). 다만, 일치되지 않은 요소들은 차례로 다음의 빈 슬롯에 대입뇝니다. 반환된 반복자는 새로운 요소들의 범위보다 1이 큰 곳을 가리킵니다. 예를 들어, {0, 1, 0, 2, 0, 3, 0, 4}의 열을 가정하겠습니다. 여기에서 모든 0 값을 제거한다고 하면 결과는 {1, 2, 3, 4, 0, 3, 0, 4}가 됩니다. 1은 첫째 슬롯에 복사되고, 2는 둘째 슬롯에, 3은 셋째 슬롯에, 4는 넷째 슬롯에 각각 복사됩니다. 다섯째 슬롯에 있는 0은 남은 것을 나타냅니다. 반환됩 반복자가 바로 여기를 가리킵니다. 일반적으로, 이 반복자는 erase()에 넘겨집니다(기본 배열은 크기가 쉽게 변경될 수 없기 때문에 remove() 알고리즘이 적합하지 않습니다. 이런 이유로, 배열에서는 remove_copy()가 더 적합한 알고리즙입니다). #incldue <algorithm> int ia[] = {0, 1, 0, 2, 0, 3, 0, 4, 0, 5}; vector<int> vec(ia, ia + 10); /* erase()의 적용 없이 remove()한 후의 벡터: 1 2 3 4 5 3 0 4 0 5 */ vec_iter = remove(vec.begin(), vec.end(), 0); /* erase() 후의 벡터: 1 2 3 4 5 */ vec.erase(vec_iter, vec.end()); int ia2[5]; /* ia2: 1 2 3 4 5 */ remove_copy(ia, ia + 10, ia2, 0); remove_if(), remove_copy_if() remove_if()는 주어진 연산 결과가 true인 모든 요소들을 제거합니다. 그렇지 않으면 remove_if()와 remove_copy_if()는 각각 remove()와 remove_copy()와 동일하게 동작합니다. #include <algorithm> class EvenValue { public: bool operator()(int value) { return value % 2 ? false : true; } }; int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34}; vector<int> vec(ia, ia + 10); iter = remove_if(vec.begin(), vec.end(), bind2nd(less<int>(), 10)); vec.erase(iter, vec.end()); /*/ 열은 이제 13 21 34가 됨 */ int ia2[10]; remove_copy_if(ia, ia + 10, ia2, EvenValue()); replace(), replace_copy() replace()는 열 내에 있는 모든 old_value를 new_value로 대체합니다. #include <algorithm> string oldval("Mr. Winnie the Pooh"); string newval("Pooh"); string sa[] = {"Christopher Robin", "Mr. Winnie the Pooh", "Piglet", "Tigger", "Eeyore"}; vector<string> vec(sa, sa + 5); /* Christopher Robin Pooh Piglet Tigger Eeyore */ replace(vec.begin(), vec.end(), oldval, newval); vector<string> vec2; /* Christopher Robin Mr. Winnie the Pooh Piglet Tigger Eeyore */ replace_copy(vec.begin(), vec.end(), inserter(vec2, vec2.begin()), newval, oldval); replace_if(), replace_copy_if() replace_if()는 열 내에서 비교 연산 결과가 true인 모든 요소들을 new_value로 대체합니다. #include <algorithm> int new_value = 0; int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34}; vector<int> vec(ia, ia + 10); /* 결과 : 0 0 0 0 0 0 0 13 21 34 */ replace_if(vec.begin(), vec.end(), bind2nd(less<int>(), 10), new_value); reverse(), reverse_copy() 컨테이너 내에 있는 요소들의 순서를 반대로 합니다. #include <algorithm> list<string> slist_copy(slist.size()); reverse(slist.begin(), slist.end()); reverse_copy(slist.begin(), slist.end(), slist_copy.begin()); rotate(), rotate_copy() rotate()는 first, middle, last 세 가지 반복자를 매개변수로 받습니다. first와 middle – 1로 표시되는 범위와 middle과 last – 1로 표시되는 범위를 서로 바꿉니다. 예를 들어, 다음과 같은 C 스타일의 문자열이 주어졌다고 가정하겠습니다. char ch[] = “boohiss!!”; 이를 hissboo!!로 변경하려면 다음과 같이 rotate()를 호출합니다. rotate(ch, ch + 3, ch + 7); 다음은 다른 예제입니다. #incldue <algorithm> int ia[] = {1, 3, 5, 7, 9, 0, 2, 4, 6, 8, 10}; vector<int> vec(ia, ia + 11), vec2(11); 첫 번째 호출에서는 0으로 시작하는 마지막 여섯 개의 요소와 1로 시작하는 처음 다섯 개의 요소를 바꿉니다. // 결과: 0 2 4 6 8 10 1 3 5 7 9 rotate(ia, ia + 5, ia + 11); 두 번째 호출에서는 8로 시작하는 마지막 두 개의 요소와 1로 시작하는 처음 9개의 요소를 바꿉니다. // 결과: 8 10 1 3 5 7 9 0 2 4 6 rotate_copy(vec.begin(), vec.end – 2, vec.end, vec2.begin()); search() 두 개의 열이 주어졌을 때 searh()는 첫 열에서 둘째 열이 나타나는 처음 위치를 가리키는 반복자를 반환합니다. 만약 일치되는 열이 없으면 첫 열의 마지막이 반환됩니다. 예를 들어, Mississippi 내에서 iss가 두 번 나타나는데, search()는 처음의 iss를 가리키는 반복자를 반환합니다. 선택적인 다섯 번째 매개변수로 기본 상등 연산자(==)를 오버라이딩할 수 있습니다. #include <algorithm> char str[25] = "a fine and private place"; char substr[4] = "ate"; int* piter = search(str, str + 25, substr, substr + 4); search_n() search_n()은 열 내에서 value가 n만큼 나타나는 곳을 찾습니다. 다음의 예제에서는 str에서 o가 연속적으로 두 번 나오는 곳을 찾습니다. 그래서 moose의 첫 o를 나타내는 반복자를 반환합니다. 일치되지 않으면 첫 열의 마지막을 가리키는 반복자를 반환합니다. 선택적인 다섯 번째 매개변수로 기본 상등 연산자를 오버라이딩할 수 있습니다. #include <algorithm> const char oh = 'o'; char str[26] = "oh my a mouse ate a moose"; char* found_str = search_n(str, str + 26, 2, oh); set_difference() set_difference()는 첫째 열에는 존재하고, 둘째 열에는 존재하지 않는 요소들로 이루어진 정렬된 열을 생성합니다. 예를 들어, {0, 1, 2, 3}과 {0, 2, 4, 6}이 주어진다면 연산의 결과는 {1, 3}이 됩니다. 모든 set 알고리즘(다음의 세 개의 알고리즘을 포함)은 다섯 개의 반복자를 매개변수로 받습니다. 첫째 열을 나타내는 두 개의 반복자와 둘째 열을 나타내는 두 개의 반복자 그리고 다섯번째 반복자는 요소들이 복사될 컨테이너를 가리킵니다. 알고리즘은 열들이 보다 작은가의 비교 연산자로 정렬되어 있다고 가정합니다. 여섯 번째의 선택적인 배개변수에는 다른 정렬 알고리즘을 넘길 수 있습니다. set_intersection() set_intersection()은 양쪽 열 모두 존재하는 요소들의 정렬된 열을 생성합니다. 예를 들어, {0, 1, 2, 3}과 {0, 2, 4, 6}이 주어진다면 결과는 {0, 2}가 됩니다. set_symmetric_difference() set_symmetric_difference()는 첫째 열에는 존재하지만, 둘째 열에는 존재하지 않는 요소들과 둘째 열에는 존재하지만, 첫째 열에는 존재하지 않는 요소들로 이루어진 정렬된 열을 생성합니다. 예를 들어, {0, 1, 2, 3}과 {0, 2, 4, 6}이 주어진다면 결과는 {1, 3, 4, 6}이 됩니다. set_union() set_union()은 두 개의 열 내에 있는 요소들이 모두 포함된 정렬된 열을 생성합니다. 예를 들어, {0, 1, 2, 3}과 {0, 2, 4, 6}이 주어진다면 결과는 {0, 1, 2, 3, 4, 6}이 됩니다. 만약 0이나 2처럼 요소가 양쪽 열 모두에 존재한다면 첫째 열에 있는 요소가 복사됩니다. #include <algorithm> string str1[] = {"Pooh", "Piglet", "Tigger", "Eerore"}; string str2[] = {"Pooh", "Heffalump", "Woozles"}; set<string> set1(str1, str1 + 4), set2(str2, str2 + 3); /* 각각의 set 연산의 결과를 저장합니다. */ set<string> res; /* set_union(): Eeyore Heffalump Piglet Pooh Tigger Woozles */ set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), inserter(res, res.begin())); res.clear(); /* set_intersection(): Pooh */ set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), inserter(res, res.begin())); res.clear(); /* set_difference(): Eeyore Piglet Tigger */ set_difference(set1.begin(), set1.end(), set2.begin(), set2.end(), inserter(res, res.begin())); res.clear(); /* set_symmetric_difference(): Eeyore Heffalump Piglet Tigger Woozles */ set_symmetric_difference(set1.begin(), set1.end(), set2.begin(), set2.end(), inserter(res, res.begin())); sort(), stable_sort() 기본적으로, 보다 작은가의 비교 연산자를 이용해서 오름차순으로 요소들을 정렬합니다. 선택적인 세 번째 매개변수에 다른 정렬 연산을 지정할 수 있습니다. stable_sort()는 컨테이너 내의 상대적인 요소들의 순서를 유지시킵니다. 예를 들어, 알파멧순으로 단어를 정렬했고, 이제 단어의 길이로 정렬하려고 합니다. 이를 위해 두 문자열을 길이로 비교할 수 있는 ?LessThan 함수 객체를 넘깁니다. sort()를 사용한다면 알파벳 순서가 유지된다고 보증할 수 없습니다. #include <algorithm> stable_sort(ia, ia + 8); stable_sort(svec.begin(), svec.end(), greater<string>()); transform() transform()의 첫 번째 형태는 열의 각 요소에 매개변수로 넘긴 당항 연산자를 적용시킵니다. 예를 들어, {0, 1, 1, 2, 3, 5}와 각각의 요소를 2배로 하는 Double의 함수 객체가 주어졌다고 가정하면 결과는 {0, 2, 2, 4, 6, 10}이 됩니다. 두 번째 형태는 두 열의 관련된 요소에 매개변수로 넘긴 이항 연산자를 적용시킵니다. 예를 들어, {1, 3, 5, 9}와 {2, 4, 6, 8} 그리고 두 요소를 더한 뒤 그 합을 2배로 만드는 ?AddAndDouble 함수 객체가 주어졌다면 결과는 {6, 14, 22, 34}가 됩니다. 결과 열은 첫 번째 형태에서는 세 번째 반복자에, 두 번째 형태에서는 네 번째 반복자에 복사됩니다. #include <algorithm> int double_val(int val) { return val + val; } int difference(int val1, int val2) { return abs(val1 - val2); } int ia[] = {3, 5, 8, 13, 21}; vector<int> vec(5), vec2(5); /* 첫 번째 형태: 6 10 16 26 42 */ transform(ia, ia + 5, vec.begin(), double_val); /* 두 번째 형태: 3 5 8 13 21 */ transform(ia, ia + 5, vec.begin(), vec2.begin(), difference); unique(), unique_copy() 상등 연산자를 사용해서 같은 값들이 연속적으로 있는 그룹들을 하나의 요소로 합칩니다. 상든 연산을 오버라이딩해서 다른 비교 연산을 넘길 수도 있습니다. Mississippi란 단어는 그 결과가 Misisipi가 됩니다. 세 개가 연속적이지 않기 때문에 다 합쳐지지는 않습니다. 중복되는 모든 요소들을 합치려면 먼저 컨테이너를 정렬해야 합니다. remove()에서처럼 컨테이너의 실제 크기는 변하지 않습니다. 각각의 고유한 요소들은 차례로 빈 슬롯에 대입됩니다. 예제에서 물리적인 결과는 Misisipippi입니다. ppi란 문자열은 알고리즘의 나머지 조각을 나타냅니다. 반환됩 반복자는 이 부분을 가리킵니다. 일반적으로, 이 반복자를 erase()에 넘깁니다(기본 배열은 erase() 연산을 지원하지 않기 때문에 unique()가 적합하지 않습니다. 그 대신 unique_copy()가 보다 적합합니다). #include <algorithm> int ia[] = {0, 1, 0, 2, 0, 3, 0, 4, 0, 5}; vector<int> vec(ia, ia + 10); sort(vec.begin(), vec.end()); iter = unique(vec.begin(), vec.end()); vec.erase(vec_iter, vec.end()); /* vec: 0 1 2 3 4 5 */ int ia2[10]; sort(ia, ia + 10); unique_copy(ia, ia + 10, ia2); C/C++/VC++ STLGeneric