본문 바로가기

알고리즘

유용한 내장 함수 추천(C++, 알고리즘, 백준)

vector와 관련해서 내장 함수들을 매우 많다. 일반적으로, sort 함수는 대부분 사용한다.

 

 

 

하지만, sort 함수이외에도 훌륭한 내장함수들이 많다.

 

 

 

- std::binary_search

- std::upper_bound

- std::lower_bound

- std:equal_range

 

 

 

위의 4가지 함수들은 매우 유용하게 사용될 것이다. 시간복잡도와 예제를 아래에서 설명하도록 하겠다.

 

 

 


 

 

1. std::binary_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
// binary_search example
#include <iostream>     // std::cout
#include <algorithm>    // std::binary_search, std::sort
#include <vector>       // std::vector
 
bool myfunction (int i,int j) { return (i<j); }
 
int main () {
  int myints[] = {1,2,3,4,5,4,3,2,1};
  std::vector<int> v(myints,myints+9);                         // 1 2 3 4 5 4 3 2 1
 
  // using default comparison:
  std::sort (v.begin(), v.end());
 
  std::cout << "looking for a 3... ";
  if (std::binary_search (v.begin(), v.end(), 3))
    std::cout << "found!\n"else std::cout << "not found.\n";
 
  // using myfunction as comp:
  std::sort (v.begin(), v.end(), myfunction);
 
  std::cout << "looking for a 6... ";
  if (std::binary_search (v.begin(), v.end(), 6, myfunction))
    std::cout << "found!\n"else std::cout << "not found.\n";
 
  return 0;
}

위의 예제를 실행시켜보면 간단히 알 수 있다. 이진탐색으로, 벡터의 원소를 찾는 것이다. 만약에 찾는다면 return value로 true를 반환하고, 그렇지 않으면 false를 반환한다.

 

 

 

이진탐색이므로, 시간복잡도는 log(v.size())가 될 것이다. 일반적으로, 전체 탐색을 하는 것보다 훨씬 효율적이다.

 

 

 

2, 3. std::upper_bound, std::lower_bound

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// lower_bound/upper_bound example
#include &lt;iostream&gt;     // std::cout
#include &lt;algorithm&gt;    // std::lower_bound, std::upper_bound, std::sort
#include &lt;vector&gt;       // std::vector
 
int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  std::vector&lt;int&gt; v(myints,myints+8);           // 10 20 30 30 20 10 10 20
 
  std::sort (v.begin(), v.end());                // 10 10 10 20 20 20 30 30
 
  std::vector&lt;int&gt;::iterator low,up;
  low=std::lower_bound (v.begin(), v.end(), 20); //          ^
  up= std::upper_bound (v.begin(), v.end(), 20); //                   ^
 
  std::cout &lt;&lt; "lower_bound at position " &lt;&lt; (low- v.begin()) &lt;&lt; '\n';
  std::cout &lt;&lt; "upper_bound at position " &lt;&lt; (up - v.begin()) &lt;&lt; '\n';
 
  return 0;
}

위의 예제를 보면, lower_bound는 찾는 값의  하한 index를 반환한다.

 

 

 

upper_bound는 찾는 값보다 큰(greater than) 상한 index를 반환한다.

 

 

 

 

이분탐색이기때문에, 시간복잡도는 log(v.size())의 형태를 이룬다.

 

 

 

 

4. std:equal_range

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
// equal_range example
#include <iostream>     // std::cout
#include <algorithm>    // std::equal_range, std::sort
#include <vector>       // std::vector
 
bool mygreater (int i,int j) { return (i>j); }
 
int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  std::vector<int> v(myints,myints+8);                         // 10 20 30 30 20 10 10 20
  std::pair<std::vector<int>::iterator,std::vector<int>::iterator> bounds;
 
  // using default comparison:
  std::sort (v.begin(), v.end());                               // 10 10 10 20 20 20 30 30
  bounds=std::equal_range (v.begin(), v.end(), 20);            //          ^         ^
 
  // using "mygreater" as comp:
  std::sort (v.begin(), v.end(), mygreater);                   // 30 30 20 20 20 10 10 10
  bounds=std::equal_range (v.begin(), v.end(), 20, mygreater);  //        ^         ^
 
  std::cout << "bounds at positions " << (bounds.first - v.begin());
  std::cout << " and " << (bounds.second - v.begin()) << '\n';
 
  return 0;
}

이 함수는 upper_bound와 lower_bound의 혼합해서 만들어진 함수이다.

 

 

 

 

이 함수를 통해서, 만약에 찾는 값이 벡터의 원소로 존재한다면 구간(bounds.second, bounds.first)을 알 수 있다. 

 

 

 

 

시간복잡도는, 2 * log(v.size())다.

 

 

 


 

 

위의 함수들을 통해서 조금 더 나은 코드를 작성할 수 있을 것이다.