Skip to content
DarkKaiser의 블로그
DarkKaiser의 블로그
  • 개발 관련 자료(노션)
  • Raspberry Pi(노션)
  • WD My Cloud(노션)
  • GitHub
DarkKaiser의 블로그

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

글 내비게이션

Previous post
Next post

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

최신 글

  • AssertJ 소개testCompile ‘org.assertj:assertj-core:3.6.2’ 2017년 9월 14일
  • 자주 사용되는 Lombok 어노테이션 2017년 9월 14일
  • 유니코드 #3 2017년 9월 14일
  • 유니코드 #2 2017년 9월 14일
  • 유니코드 #1 2017년 9월 14일

최신 댓글

    카테고리

    • 개인 자료 (1)
      • 일기 (1)
    • 주절주절 (7)
    • 프로그래밍 갤러리 (16)
    • 프로그래밍 언어 (186)
      • Java (29)
      • C/C++/VC++ (114)
      • C# (11)
      • Visual Basic (6)
      • 안드로이드 (9)
      • Objective-C (5)
      • JavaScript (4)
      • JSP/Servlet (2)
      • Python (4)
      • 어셈블러 (1)
    • 개발++ (44)
      • Book (11)
        • Joel On Software (10)
      • 프로젝트 관리 (6)
      • Maven (1)
      • 디버깅 (1)
      • DirectX (1)
      • Silverlight (1)
      • RESTful (1)
      • Hacking (1)
      • WDM (4)
      • VoIP (5)
      • 기타 (1)
    • 개발 도구 (15)
      • eclipse (14)
      • Sublime Text (1)
    • 네트워크 (7)
    • 설치 및 배포 (7)
      • InstallShield (2)
      • NSIS (4)
    • 버전 관리 (9)
      • Git (2)
      • CVS (2)
      • Subversion (5)
    • 데이터베이스 (7)
      • Oracle (3)
      • Sybase (2)
      • MS-SQL (2)
    • 단위테스트 (3)
      • JUnit (1)
      • NUnit (2)
    • 버그추적시스템 (2)
      • mantis (2)
    • 운영체제 (7)
      • Windows (5)
      • 리눅스 (2)
    • WAS (3)
      • WebLogic (3)
    • 디자인패턴 (1)
    • 디지털 이미지 프로세싱 (16)

    태그

    Abstract ActiveX AfxParseURL Automation boost devenv.exe event EventLogTraceListener Hover interface IO iTextSharp JAD jar JavaScript Joel Leave MFC Monitor msdev.com MSDN mutable PDF Properties RAW Saturation SHGetFolderPath SHGetKnownFolderPath SQLite STLTask String TextWriterTraceListener URL VI 권한 데이터소스 디컴파일러 문자열 스레드 동기화 스레드 생성 실용주의 프로그래머 자동화 테스팅 파일포맷 프리컴파일

    메타

    • 로그인
    • 엔트리 피드
    • 댓글 피드
    • WordPress.org
    ©2025 DarkKaiser의 블로그 | WordPress Theme by SuperbThemes