#include <algorithm> 헤더를 사용해야 한다.
| 알고리즘 함수 | 사용 형태 (인자) | 역할 | 반환값 |
|---|---|---|---|
| adjacent_find | adjacent_find(first, last)adjacent_find(first, last, binary_pred) | 인접한 동일 원소 또는 조건 만족 쌍 찾기 | 조건 만족하는 첫 번째 반복자, 없으면 last |
| count | count(first, last, value) | 주어진 값과 같은 원소 개수 세기 | 일치하는 원소 개수 (int) |
| count_if | count_if(first, last, unary_pred) | 조건을 만족하는 원소 개수 세기 | 조건을 만족하는 개수 (int) |
| equal | equal(first1, last1, first2)equal(first1, last1, first2, binary_pred) | 두 범위가 같은지 비교 | 같으면 true, 아니면 false |
| find | find(first, last, value) | 특정 값을 가진 첫 원소 찾기 | 해당 원소의 반복자, 없으면 last |
| find_if | find_if(first, last, unary_pred) | 조건 만족 첫 원소 찾기 | 조건 만족 원소 반복자, 없으면 last |
| find_first_of | find_first_of(first1, last1, first2, last2)find_first_of(first1, last1, first2, last2, binary_pred) | 첫 번째 범위에서 두 번째 범위와 일치하는 첫 원소 찾기 | 일치하는 첫 번째 원소 반복자, 없으면 last1 |
| find_end | find_end(first1, last1, first2, last2)find_end(first1, last1, first2, last2, binary_pred) | 첫 번째 범위에서 마지막으로 일치하는 부분 찾기 | 마지막으로 일치하는 부분 시작 반복자 |
| search | search(first1, last1, first2, last2)search(first1, last1, first2, last2, binary_pred) | 부분 시퀀스를 찾음 | 부분 시퀀스의 시작 반복자 |
| search_n | search_n(first, last, count, value)search_n(first, last, count, value, binary_pred) | 동일한 값이 연속된 부분 찾기 | 시작 반복자 |
| for_each | for_each(first, last, func) | 각 원소에 함수 적용 (수정은 하지 않음) | 함수 객체 또는 람다의 복사본 반환 |
| lexicographical_compare | lexicographical_compare(first1, last1, first2, last2)... , comp | 두 범위를 사전순으로 비교 | true or false |
| min | min(a, b)min(a, b, comp) | 두 값 중 작은 값 반환 | 더 작은 값 |
| max | max(a, b)max(a, b, comp) | 두 값 중 큰 값 반환 | 더 큰 값 |
| min_element | min_element(first, last)min_element(first, last, comp) | 가장 작은 원소 찾기 | 최소값 반복자 |
| max_element | max_element(first, last)max_element(first, last, comp) | 가장 큰 원소 찾기 | 최대값 반복자 |
| mismatch | mismatch(first1, last1, first2)mismatch(first1, last1, first2, binary_pred) | 두 범위가 처음 불일치하는 위치 찾기 | pair<first1_iter, first2_iter> |
변수명.first pair<string, int> p;
cout << p.first << endl;
변수명->firstmap<string, int> m;
auto iter = m.begin();
cout << iter->first << endl;
인접한 동일 원소 또는 조건 만족 쌍 찾기
➡ 현재 원소와 다음 원소가 같아지는 첫 원소의 반복자를 반환한다.
➡ 이항 조건자 버전으로, 현재 원소와 다음 원소가 해당 함수에 적합한 지 확인하고 반환한다.
ex1) [v.begin(), v.end()) 구간에서 찾고자 하는 원소가 없다면 v.end() 반복자를 반환한다.
ex2) [v.begin(), v.begin() + 3) 구간에서 찾고자 하는 원소가 없다면 v.begin() + 3 반복자를 반환한다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool Calculate(int a, int b)
{
return abs(a - b) > 10; // a - b가 10 보다 크다면 true
}
int main()
{
// adjacent_find는 찾는 원소가 없으면 구간의 끝 반복자를 반환한다.
vector<int>v;
v.push_back(10);
v.push_back(20);
v.push_back(20);
v.push_back(30);
vector<int>::iterator iter = adjacent_find(v.begin(), v.end());
if (iter != v.end())
{
cout << *iter << endl; // 결과 : 20
}
// -----------------------------
vector<int>v2;
v2.push_back(10); // begin()
v2.push_back(50);
v2.push_back(60);
v2.push_back(70); // begin() + 3
v2.push_back(80);
vector<int>::iterator iter2 = adjacent_find(v2.begin(), v2.begin() + 3, Calculate);
if (iter2 != v2.begin() + 3)
{
cout << *iter2 << endl; // 결과 : 10
}
}
주어진 값과 같은 원소 개수 세기
➡ 세고자 하는 값의 갯수가 int로 반환된다.
➡ 조건자에 해당하는 원소들을 반환한다.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool Calculate(int n)
{
return n > 10; // 10보다 크다면 true 반환
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(10);
v.push_back(10);
v.push_back(20);
v.push_back(30);
// 원소가 10인 갯수
int num = count(v.begin(), v.end(), 10);
cout << num << "개" << endl; // 결과 : 3개
// ----------------------------------
vector<int> v2;
v2.push_back(10);
v2.push_back(10);
v2.push_back(10);
v2.push_back(20);
v2.push_back(30);
// 원소가 10인 갯수
int num2 = count_if(v2.begin(), v2.end(), Calculate);
cout << num2 << "개" << endl; // 결과 : 2개
}
두 범위가 같은지 비교
➡ 첫번째 순차열은 구간[b, e)를 필요로 하지만, 두번째 순차열은 시작 반복자만 필요로 한다.
➡ 두번째 순차열의 범위는 첫번째 순차열의 크기만큼 결정된다.
➡ 두 순차열이 같은 지 확인하고 bool 타입을 반환한다.
➡ 두 순차열의 조건자에 해당하는 원소들이라면 true를 반환한다.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool Calculate(int left, int right)
{
return abs(left - right) >= 0;
}
int main()
{
vector<int> v1;
v1.push_back(10);
v1.push_back(10);
v1.push_back(10);
vector<int> v2;
v2.push_back(10);
v2.push_back(10);
v2.push_back(10);
v2.push_back(20);
v2.push_back(30);
// [v2.begin() ~ v2.begin()+3) 범위
bool result = equal(v1.begin(), v1.end(), v2.begin());
if (result == true)
{
cout << "두 순차열이 같습니다1" << endl;
}
bool result2 = equal(v1.begin(), v1.end(), v2.begin(), Calculate);
if (result2 == true)
{
cout << "두 순차열이 같습니다2" << endl;
}
}
특정 값을 가진 첫 원소 찾기
➡ 원하는 구간 안에서 찾고자 하는 값 중 가장 첫 원소의 반복자를 반환한다.
➡ 원하는 구간 안에서 조건자에 맞는 값 중 가장 첫번째 원소의 반복자를 반환한다.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool Calculate(int n)
{
return n > 25; // 25보다 크면 true 반환
}
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);
vector<int>::iterator iter = find(v.begin(), v.end(), 30);
if (iter != v.end())
{
cout << "첫번째 일치 원소의 시작 반복자 : " << *iter << endl;
}
vector<int>::iterator iter2 = find_if(v.begin(), v.end(), Calculate);
if (iter2 != v.end())
{
cout << "25보다 큰 원소 중 가장 첫번째 원소 : " << *iter2 << endl;
}
}
첫 번째 범위에서 일치하는 순차열 중 마지막 순차열을 찾는 법 ➡ 순차열이 여러개라면 마지막 순차열의 반복자를 반환한다.
➡ 1구간의 범위 내에서 2구간의 순차열과 일치하는 것들 중 마지막 순차열의 시작 반복자를 반환한다.
➡ 아래의 코드에서 구간1의 뒷 부분 10, 30이 발견되어 반환된다.
int main()
{
vector<int> v;
v.push_back(10); // 일치
v.push_back(30); // 일치
v.push_back(10);
v.push_back(40);
v.push_back(10); // 일치
v.push_back(30); // 일치
vector<int> v2;
v2.push_back(10);
v2.push_back(30);
vector<int>::iterator iter = find_end(v.begin(), v.end(), v2.begin(), v2.end());
if (iter != v.end())
{
cout << "일치하는 마지막 순차열의 시작 반복자 : " << *iter << endl; // 10
cout << "시작 반복자의 앞 : " << *(iter-1) << endl; // 40
}
}
➡ 1구간의 범위 내에서 2구간의 원소가 조건에 맞는 것들 중 마지막 순차열의 시작 반복자를 반환한다.
➡ 아래의 코드에서 구간 2보다 작은 순차열들(Calculate가 true인 것들) 중 마지막 순차열의 시작 반복자의 값은 10이다.
bool Calculate(int left, int right)
{
return left <= right;
}
int main()
{
vector<int> v;
v.push_back(10); // 일치
v.push_back(20); // 일치
v.push_back(30); // 일치
v.push_back(10); // 일치 -> 일치하는 마지막 순차열의 시작 반복자
v.push_back(20); // 일치
v.push_back(30); // 일치
vector<int> v2;
v2.push_back(15);
v2.push_back(25);
v2.push_back(35);
vector<int>::iterator iter = find_end(v.begin(), v.end(), v2.begin(), v2.end(), Calculate);
if (iter != v.end())
{
cout << "일치하는 마지막 순차열의 시작 반복자 : " << *iter << endl; // 10
cout << "시작 반복자의 앞 : " << *(iter-1) << endl; // 30
}
}
find_end()와 동일한데 find_end()는 일치하는 마지막 순차열의 반복자를 반환하고, search()는 일치하는 첫번째 순차열의 반복자를 반환한다.
int main()
{
vector<int> v;
v.push_back(10); // 일치
v.push_back(30); // 일치
v.push_back(10);
v.push_back(40);
v.push_back(10);
v.push_back(30);
vector<int> v2;
v2.push_back(10);
v2.push_back(30);
vector<int>::iterator iter = search(v.begin(), v.end(), v2.begin(), v2.end());
if (iter != v.end())
{
cout << "일치하는 처음 순차열의 시작 반복자 : " << *iter << endl; // 10
cout << "시작 반복자의 뒤 : " << *(iter + 1) << endl; // 30
cout << "시작 반복자의 뒤 뒤 : " << *(iter + 2) << endl; // 10
}
}
➡ 아래의 코드에서 3, 30이면 30의 값이 3번 반복되는 순차열을 찾고 그 순차열의 시작 반복자를 반환한다.
➡ 아래의 코드에서 찾고자 하는 값과 순차열들의 값의 조건이 맞고 3번 반복된다면 그 순차열의 시작 반복자를 반환한다.
bool Calculate(int a, int b)
{
return abs(a - b) <= 5; // 5이하라면 true 반환
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(31);
v.push_back(31);
v.push_back(31);
v.push_back(10);
v.push_back(10);
// 30과의 차이가 5 이하면서 3번 연속되는 순차열의 시작 반복자를 반환
vector<int>::iterator iter = search_n(v.begin(), v.end(), 3, 30, Calculate);
cout << "찾은 순차열 시작 반복자 : " << *iter << endl; // 31
cout << "찾은 순차열 이전 반복자 : " << *(iter-1) << endl; // 10
}
첫 번째 범위에서 두 번째 범위와 일치하는 첫 원소 찾기
➡ 1구간의 범위 내에서 2구간의 원소 중 가장 먼저 발견된 원소의 시작 반복자를 반환한다.
➡ 아래의 코드에서 구간 2에 있는 값들 중 구간1의 10이 제일 먼저 발견되었다.
➡ 1구간의 범위 내에서 2구간의 원소 보다 큰 값의 시작 반복자를 반환한다.
➡ 아래의 코드에서 구간 2에 있는 값들 중 구간1의 20이 제일 먼저 구간2보다 큰 값으로 발견되었다.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool Calculate(int left, int right)
{
return left > right; // v1 > v2인 순차열들은 모두 true를 반환
}
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
vector<int> v2;
v2.push_back(30);
v2.push_back(20);
v2.push_back(10);
vector<int>::iterator iter = find_first_of(v.begin(), v.end(), v2.begin(), v2.end());
if (iter != v.end())
{
cout << "가장 먼저 발견된 원소의 시작 반복자 : " << *iter << endl; // v1 = 10
// left 순차열에서 right 값 중 가장 먼저 발견된 원소의 시작 반복자를 반환한다.
}
vector<int>::iterator iter2 = find_first_of(v.begin(), v.end(), v2.begin(), v2.end(), Calculate);
if (iter2 != v.end())
{
cout << "함수객체가 true이면서 가장 먼저 발견된 원소의 시작 반복자 : " << *iter2 << endl; // v1 = 20
// left 순차열에서 right의 값들보다 큰 값의 시작 반복자를 제일 먼저 반환한다.
// -> v1의 20은 v2의 10보다 크다.
}
}
각 원소에 함수 적용 (수정은 하지 않음)
void Print(int n)
{
cout << n << " ";
}
class PrintFunctor
{
char fmt;
public:
explicit PrintFunctor(char c = ' ') :fmt(c) { }
void operator () (int n) const
{
cout << n << fmt;
}
};
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
for_each(v.begin(), v.end(), Print);
cout << '\n';
for_each(v.begin(), v.end(), PrintFunctor(','));
}
두 범위를 사전순으로 비교
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(30);
v2.push_back(30);
vector<int>v3;
v3.push_back(10);
v3.push_back(25);
v3.push_back(30);
// 두 범위를 사전적으로 비교해서, 첫번째 범위가 두 번째보다 사전순으로 앞서면 true,
// 아니면 false를 반환합니다.
// default = less<int>()
if (lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end()))
{
cout << "v1 < v2" << endl; // v2가 사전순으로 앞선다. (오름차순)
}
// greater<int>()
if (lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end(), greater<int>()))
{
cout << "v1 < v2" << endl;
}
else
{
cout << "v1 > v2" << endl; // v1이 사전순으로 앞선다. (내림차순)
}
// 사용자 정의 함수 객체
if (lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end(), Less<int>()))
{
cout << "c1 < v2" << endl;// v2가 사전순으로 앞선다. (오름차순)
}
}
두 값 중 작은값 & 큰 값을 반환한다. ➡ 사용자 정의 함수 객체 가능
int main()
{
int a = 10; int b = 20;
int r;
r = max(a, b);
cout << "max값 : " << r << endl; // 20
r = min(a, b);
cout << "min값 : " << r << endl; // 10
}
class Point
{
int x, y;
public :
// 생성자 생성 & 초기화 (입력받은 x, y를 할당한다.)
Point(int _x = 0, int _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) // x값만 비교
{
return left.GetX() < right.GetX();
}
bool YCompare(const Point& left, const Point& right) // y값만 비교
{
return left.GetY() < right.GetY();
}
int main()
{
Point pt1(5, 8);
Point pt2(3, 9);
Point pt3; // (0, 0)
pt3 = max(pt1, pt2, XCompare);
cout << "X max값 : "; pt3.Print();
pt3 = max(pt1, pt2, YCompare);
cout << "Y max값 : "; pt3.Print();
}
모든 인자 타입이 동일하다면 여러 변수에서 최소 / 최대값을 구할 수 있다.
int main()
{
int a = 5, b = 2, c = 9, d = 3;
int minimum = std::min({a, b, c, d});
int maximum = std::max({a, b, c, d});
cout << "min: " << minimum << "\n"; // 2
cout << "max: " << maximum << "\n"; // 9
}
최대, 최소값을 찾을 때, 모든 타입이 int인 2차원 배열의 값을 {a, b, c, d} 형태로 인자에 넣었다.
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int solution(vector<vector<int>> dots)
{
int num1 = max({dots[0][0], dots[1][0], dots[2][0], dots[3][0]});
int num2 = min({dots[0][0], dots[1][0], dots[2][0], dots[3][0]});
int num3 = max({dots[0][1], dots[1][1], dots[2][1], dots[3][1]});
int num4 = min({dots[0][1], dots[1][1], dots[2][1], dots[3][1]});
return (num1 - num2) * (num3 - num4);
}
최소값의 반복자 & 최대값의 반복자를 반환한다.
int main()
{
vector<int>v;
v.push_back(10);
v.push_back(70);
v.push_back(40);
v.push_back(20);
v.push_back(50);
vector<int>::iterator iter1 = max_element(v.begin(), v.end());
vector<int>::iterator iter2 = min_element(v.begin(), v.end());
cout << "범위 내 가장 큰 원소 : " << *iter1 << endl;
cout << "범위 내 가장 작은 원소 : " << *iter2 << endl;
}
class Point
{
int x, y;
public :
// 생성자 생성 & 초기화 (입력받은 x, y를 할당한다.)
Point(int _x = 0, int _y = 0) : x(_x), y(_y) { }
int GetX() const { return x; }
int GetY() const { return y; }
void Print() const { cout << '(' << x << ',' << y << ')' << endl; }
};
bool Compare(const Point& left, const Point& right)
{
// X값 먼저 비교 후 Y값 비교
if (left.GetX() < right.GetX())
{
return true;
}
else if (left.GetX() > right.GetX())
{
return false;
}
else // X값이 같다면 Y값으로 비교
{
return left.GetY() < right.GetY();
}
}
int main()
{
vector<Point>v;
v.push_back(Point(3, 2));
v.push_back(Point(2, 5));
v.push_back(Point(1, 5));
v.push_back(Point(3, 3));
v.push_back(Point(3, 2));
vector<Point>::iterator iter = max_element(v.begin(), v.end(), Compare);
// 동일한 의미의 값 접근법
cout << "max :"; iter->Print(); cout << endl;
cout << "max :"; (*iter).Print(); cout << endl;
}
두 범위가 불일치하는 처음 순차열 찾기 ➡ 반복자 쌍을 반환한다. pair<first_iter, second_iter>
➡ 반복자 쌍이 반환되기 때문에 타입은 pair로 반환된다.
➡ 함수 객체가 false를 반환하는 것이 mismatch에서는 조건에 맞는 답이다.
bool Calculate(int a, int b)
{
return abs(a - b) < 10; // 두 값의 차가 10미만이면 true반환
}
// mismatch는 false를 반환하는 것을 찾는다.
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(20);
v2.push_back(50);
pair<vector<int>::iterator, vector<int>::iterator> p;
// v2는 v1의 크기만큼 끝 반복자
p = mismatch(v1.begin(), v1.end(), v2.begin());
// 처음 발견된 서로 다른 원소의 반복자 쌍을 반환
cout << "v1 : " << *p.first << endl; // 30
cout << "v2 : " << *p.second << endl; // 50
// -----------------------------------
pair<vector<int>::iterator, vector<int>::iterator> p2;
p2 = mismatch(v1.begin(), v1.end(), v2.begin(), Calculate);
// fasle를 반환하는 30, 50 반복자 쌍이 반환된다.
cout << "v1 : " << *p2.first << endl; // 30
cout << "v2 : " << *p2.second << endl; // 50
}