변경 가능 알고리즘 (Modifying Sequence Algorithm)
-
copy 원소들을 복사.
-
copy_n 원하는 개수만큼 원소들을 복사
-
copy_if 원소들 중 조건에 일치하는 것들만 복사
-
copy_backward 원소들을 뒤에서부터 복사
-
// until C++20
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
template< class BidirIt1, class BidirIt2 >
BidirIt2 copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
// since C++20
template< class InputIt, class OutputIt >
constexpr OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
template< class InputIt, class OutputIt, class UnaryPredicate >
constexpr OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPredicate pred );
template< class InputIt, class Size, class OutputIt >
constexpr OutputIt copy_n( InputIt first, Size count, OutputIt result );
template< class BidirIt1, class BidirIt2 >
constexpr BidirIt2 copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
// since C++17
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 copy( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPredicate >
ForwardIt2 copy_if( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, UnaryPredicate pred );
template< class ExecutionPolicy, class ForwardIt1, class Size, class ForwardIt2 >
ForwardIt2 copy_n( ExecutionPolicy&& policy, ForwardIt1 first, Size count,
ForwardIt2 result );
// since C++11
template< class InputIt, class OutputIt, class UnaryPredicate >
OutputIt copy_if( InputIt first, InputIt last,
OutputIt d_first, UnaryPredicate pred );
template< class InputIt, class Size, class OutputIt >
OutputIt copy_n( InputIt first, Size count, OutputIt result );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> from_vector, to_vector;
for (int i = 0; i < 10; i++)
from_vector.push_back(i);
copy(from_vector.begin(), from_vector.end(), back_inserter(to_vector));
/* same as
* vector<int> to_vector(from_vector.size());
* copy(from_vector.begin(), from_vector.end(), to_vector.begin());
* or
* vector<int> to_vector = from_vector;
*/
cout << "to_vector contains: ";
copy(to_vector.begin(), to_vector.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "odd numbers in to_vector are: ";
copy_if(to_vector.begin(), to_vector.end(), ostream_iterator<int>(cout, " "),
[](int x) { return (x % 2) == 1; });
cout << endl;
to_vector.clear();
to_vector.resize(20);
cout << "4 numbers in to_vector are: ";
copy_n(from_vector.cbegin(), 4, to_vector.begin());
copy(to_vector.begin(), to_vector.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "copy_backward() on to_vector: ";
copy_backward(from_vector.begin(), from_vector.end(), to_vector.end());
copy(to_vector.begin(), to_vector.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
to_vector contains: 0 1 2 3 4 5 6 7 8 9
odd numbers in to_vector are: 1 3 5 7 9
4 numbers in to_vector are: 0 1 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
copy_backward() on to_vector: 0 1 2 3 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9
*/
-
move 원소들을 이동시킴.
-
move_backward 원소들을 뒤에서부터 이동시킴.
-
// since C++11 until C++20
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last, OutputIt d_first );
template< class BidirIt1, class BidirIt2 >
BidirIt2 move_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
// since C++20
template< class InputIt, class OutputIt >
constexpr OutputIt move( InputIt first, InputIt last, OutputIt d_first );
template< class BidirIt1, class BidirIt2 >
constexpr BidirIt2 move_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
// since C++17
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 move( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator> // next()
#include <thread>
#include <chrono>
using namespace std;
void fn(int n) {
this_thread::sleep_for(chrono::seconds(n));
cout << "thread " << n << " ended" << endl;
}
int main() {
vector<thread> v;
list<thread> l1, l2;
// copy() would not compile, because thread is noncopyable
for (int i = 1; i < 7; i++)
v.emplace_back(fn, i);
cout << "move(): " << endl;
move(v.begin(), next(v.begin(), 3), back_inserter(l1));
for (auto& t : l1) t.join();
cout << endl << "move_backward(): " << endl;
l2.emplace_back(fn, 0);
l2.emplace_back(fn, 0);
l2.resize(5);
// error because [v.begin(), v.begin() + 3] are empty.
// move_backward(v.begin(), v.end(), l2.end());
move_backward(v.begin() + 3, v.end(), l2.end());
for (auto& t : l2) {
t.join();
}
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
move():
thread 1 ended
thread 2 ended
thread 3 ended
move_backward():
thread 0 ended
thread 0 ended
thread 4 ended
thread 5 ended
thread 6 ended
*/
// until C++20
template< class ForwardIt, class T >
void fill( ForwardIt first, ForwardIt last, const T& value );
// since C++20
template< class ForwardIt, class T >
constexpr void fill( ForwardIt first, ForwardIt last, const T& value );
template< class OutputIt, class Size, class T >
constexpr OutputIt fill_n( OutputIt first, Size count, const T& value );
// since C++17
template< class ExecutionPolicy, class ForwardIt, class T >
void fill( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
const T& value );
template< class ExecutionPolicy, class ForwardIt, class Size, class T >
ForwardIt fill_n( ExecutionPolicy&& policy, ForwardIt first, Size count,
const T& value );
// until C++11
template< class OutputIt, class Size, class T >
void fill_n( OutputIt first, Size count, const T& value );
// since C++11 until C++20
template< class OutputIt, class Size, class T >
OutputIt fill_n( OutputIt first, Size count, const T& value );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
fill(v.begin(), v.end(), -1);
for (auto elem : v)
cout << elem << " ";
cout << endl;
fill_n(v.begin(), 5, 0);
for (auto elem : v)
cout << elem << " ";
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0 0 0 0 0 -1 -1 -1 -1 -1
*/
-
transform 범위 내 각 원소에 대해 주어진 함수를 호출.
// until C++20
template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,
UnaryOperation unary_op );
template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation >
OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOperation binary_op );
// since C++20
template< class InputIt, class OutputIt, class UnaryOperation >
constexpr OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,
UnaryOperation unary_op );
template< class InputIt1, class InputIt2, class OutputIt, class BinaryOperation >
constexpr OutputIt transform( InputIt1 first1, InputIt1 last1, InputIt2 first2,
OutputIt d_first, BinaryOperation binary_op );
// since C++17
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryOperation >
ForwardIt2 transform( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 d_first, UnaryOperation unary_op );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class ForwardIt3, class BinaryOperation >
ForwardIt3 transform( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt3 d_first,
BinaryOperation binary_op );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <functional> // plus<>()
using namespace std;
int main() {
string s("hello");
transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) -> unsigned char { return toupper(c); });
vector<size_t> ordinals;
transform(s.begin(), s.end(), back_inserter(ordinals),
[](unsigned char c) -> size_t { return c; });
cout << s << ':';
for (auto ord : ordinals) cout << ' ' << ord;
cout << endl;
// ordinals[i] = ordinals[i] + ordinals[i]
transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
ordinals.begin(), plus<>{});
for (auto ord : ordinals) cout << ord << ' ';
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++17
$ ./a.out
HELLO: 72 69 76 76 79
144 138 152 152 158
*/
-
generate 범위 내 원소들을 주어진 함수를 호출한 결과로 채움.
-
generate_n 범위 내 특정 개수만큼 원소들을 주어진 함수를 호출한 결과로 채움.
-
// until C++20
template< class ForwardIt, class Generator >
void generate( ForwardIt first, ForwardIt last, Generator g );
// since C++20
template< class ForwardIt, class Generator >
constexpr void generate( ForwardIt first, ForwardIt last, Generator g );
template< class OutputIt, class Size, class Generator >
constexpr OutputIt generate_n( OutputIt first, Size count, Generator g );
// since C++17
template< class ExecutionPolicy, class ForwardIt, class Generator >
void generate( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
Generator g );
template< class ExecutionPolicy, class ForwardIt , class Size, class Generator >
ForwardIt generate_n( ExecutionPolicy&& policy, ForwardIt first,
Size count, Generator g );
// until C++11
template< class OutputIt, class Size, class Generator >
void generate_n( OutputIt first, Size count, Generator g );
// since C++11 until C++20
template< class OutputIt, class Size, class Generator >
OutputIt generate_n( OutputIt first, Size count, Generator g );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int fn() {
static int i = 1;
return i++;
}
int main() {
vector<int> v(5);
generate(v.begin(), v.end(), fn);
cout << "v: ";
for (auto iv: v)
cout << iv << " ";
cout << endl;
// Initialize with default values 0,1,2,3,4 from a lambda function
// Equivalent to iota(v.begin(), v.end(), 0);
generate(v.begin(), v.end(), [n = 0] () mutable { return n++; });
cout << "v: ";
for (auto iv: v)
cout << iv << " ";
cout << endl;
generate_n(v.begin(), 2, []() { return -1; });
cout << "v: ";
for (auto iv: v)
cout << iv << " ";
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++17
$ ./a.out
v: 1 2 3 4 5
v: 0 1 2 3 4
v: -1 -1 2 3 4
*/
-
remove 범위 내 특정 값과 일치하는 원소들을 제거.
-
remove_if 조건과 일치하는 원소들을 제거.
-
remove_copy 특정 값과 일치하는 원소들을 복사한 후 제거. (원본은 유지)
-
remove_copy_if 조건과 일치하는 원소들을 복사한 후 제거. (원본은 유지)
-
원본 컨테이너에서 제거할 원소는 뒤의 원소를 옮김(move)으로써 제거하기 때문에 erase() 등의 멤버 함수를 사용해서 뒤에 남은 부분을 제거할 필요가 있음.
-
반환값은 옮긴 후 마지막 원소를 참조하는 iterator.
-
// until C++20
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
template< class InputIt, class OutputIt, class T >
OutputIt remove_copy( InputIt first, InputIt last, OutputIt d_first,
const T& value );
template< class InputIt, class OutputIt, class UnaryPredicate >
OutputIt remove_copy_if( InputIt first, InputIt last, OutputIt d_first,
UnaryPredicate p );
// since C++20
template< class ForwardIt, class T >
constexpr ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
template< class ForwardIt, class UnaryPredicate >
constexpr ForwardIt remove_if( ForwardIt first, ForwardIt last,
UnaryPredicate p );
template< class InputIt, class OutputIt, class T >
constexpr OutputIt remove_copy( InputIt first, InputIt last, OutputIt d_first,
const T& value );
template< class InputIt, class OutputIt, class UnaryPredicate >
constexpr OutputIt remove_copy_if( InputIt first, InputIt last, OutputIt d_first,
UnaryPredicate p );
// since C++17
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt remove( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
const T& value );
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
UnaryPredicate p );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T >
ForwardIt2 remove_copy( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, const T& value );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPredicate >
ForwardIt2 remove_copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, UnaryPredicate p );
// ----------------------------------------------------------------------------------
#include <algorithm>
#include <iterator>
#include <string>
#include <iostream>
#include <cctype>
using namespace std;;
int main()
{
string str1 = "Text with some spaces";
str1.erase(remove(str1.begin(), str1.end(), ' '), str1.end());
cout << str1 << endl;
string str2 = "Text\n with\tsome \t whitespaces\n\n";
string str3 = str2;
str2.erase(remove_if(str2.begin(), str2.end(),
[](unsigned char x) { return isspace(x); }), str2.end());
cout << str2 << endl;
remove(str3.begin(), str3.end(), '\n');
// after just moving
cout << str3 << endl;
str3 = "Text with some spaces";
cout << "Before: " << str3 << endl;
cout << "After remove_copy(): ";
remove_copy(str3.begin(), str3.end(), ostream_iterator<char>(cout), ' ');
cout << endl;
str3 = "Text with some spaces";
cout << "Before: " << str3 << endl;
cout << "After remove_copy_if(): ";
remove_copy_if(str3.begin(), str3.end(), ostream_iterator<char>(cout),
[](unsigned char x) { return isspace(x); });
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
Textwithsomespaces
Textwithsomewhitespaces
Text with some whitespacess
Before: Text with some spaces
After remove_copy(): Textwithsomespaces
Before: Text with some spaces
After remove_copy_if(): Textwithsomespaces
*/
-
replace 특정 범위 내 원소들을 주어진 원소들로 치환.
-
replace_if 범위 내 조건과 일치하는 원소들을 주어진 원소들로 치환.
-
replace_copy 특정 범위 내 원소들을 복사한 후, 주어진 원소들로 치환. (원본은 유지)
-
replace_copy_if 범위 내 조건과 일치하는 원소들을 복사한 후, 주어진 원소들로 치환. (원본은 유지)
-
// until C++20
template< class ForwardIt, class T >
void replace( ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
template< class ForwardIt, class UnaryPredicate, class T >
void replace_if( ForwardIt first, ForwardIt last,
UnaryPredicate p, const T& new_value );
template< class InputIt, class OutputIt, class T >
OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
const T& old_value, const T& new_value );
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
OutputIt replace_copy_if( InputIt first, InputIt last, OutputIt d_first,
UnaryPredicate p, const T& new_value );
// since C++20
template< class ForwardIt, class T >
constexpr void replace( ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
template< class ForwardIt, class UnaryPredicate, class T >
constexpr void replace_if( ForwardIt first, ForwardIt last,
UnaryPredicate p, const T& new_value );
template< class InputIt, class OutputIt, class T >
constexpr OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first,
const T& old_value, const T& new_value );
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
constexpr OutputIt replace_copy_if( InputIt first, InputIt last, OutputIt d_first,
UnaryPredicate p, const T& new_value );
// since C++17
template< class ExecutionPolicy, class ForwardIt, class T >
void replace( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
const T& old_value, const T& new_value );
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate, class T >
void replace_if( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
UnaryPredicate p, const T& new_value );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class T >
ForwardIt2 replace_copy( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, const T& old_value, const T& new_value);
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class UnaryPredicate, class T >
ForwardIt2 replace_copy_if( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, UnaryPredicate p,
const T& new_value );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <algorithm>
#include <array>
#include <functional>
using namespace std;
void print(array<int, 10> &s, string msg) {
cout << msg;
for (int a : s)
cout << a << " ";
cout << endl;
}
int main()
{
array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
print(s, "Before: ");
replace(s.begin(), s.end(), 8, 88);
print(s, "After replace(): ");
replace_if(s.begin(), s.end(), bind(less<int>(), placeholders::_1, 5), 55);
print(s, "After replace_if(): ");
cout << "After replace_copy(): ";
replace_copy(s.begin(), s.end(), ostream_iterator<int>(cout, " "), 88, 1);
cout << endl;
cout << "After replace_copy_if(): ";
replace_copy_if(s.begin(), s.end(), ostream_iterator<int>(cout, " "),
[](int n){return n > 5;}, 99);
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
Before: 5 7 4 2 8 6 1 9 0 3
After replace(): 5 7 4 2 88 6 1 9 0 3
After replace_if(): 5 7 55 55 88 6 55 9 55 55
After replace_copy(): 5 7 55 55 5 6 55 9 55 55
After replace_copy_if(): 5 99 99 99 99 99 99 99 99 99
*/
-
swap 범위 내 두 원소를 교환.
-
swap_ranges 주어진 두 범위의 원소들을 교환.
-
iter_swap 두 반복자가 참조하는 원소들을 교환.
-
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <random>
#include <functional>
using namespace std;
template<class ForwardIt>
void selection_sort(ForwardIt begin, ForwardIt end) {
for (ForwardIt i = begin; i != end; ++i)
iter_swap(i, min_element(i, end));
}
int main() {
int a = 5, b = 3;
cout << "Before swap(): ";
cout << a << ' ' << b << endl;
swap(a,b);
cout << "After swap(): ";
cout << a << ' ' << b << endl;
vector<int> v = {1, 2, 3, 4, 5};
list<int> l = {-1, -2, -3, -4, -5};
cout << "Call swap_ranges():" << endl;
swap_ranges(v.begin(), v.begin()+3, l.begin());
for(int n : v) cout << n << ' ';
cout << endl;
for(int n : l) cout << n << ' ';
cout << endl;
cout << "Call iter_swap():" << endl;
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist(-10, 10);
vector<int> v2;
generate_n(back_inserter(v2), 20, bind(dist, gen));
cout << "Before sort: ";
for(auto e : v2) cout << e << " ";
selection_sort(v2.begin(), v2.end());
cout << endl << "After sort: ";
for(auto e : v2) cout << e << " ";
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
Before swap(): 5 3
After swap(): 3 5
Call swap_ranges():
-1 -2 -3 4 5
1 2 3 -4 -5
Call iter_swap():
Before sort: 8 7 -9 -7 9 0 -8 -8 -2 -9 -4 8 -1 -9 -1 -8 -6 10 -2 -9
After sort: -9 -9 -9 -9 -8 -8 -8 -7 -6 -4 -2 -2 -1 -1 0 7 8 8 9 10
*/
-
reverse 범위 내 원소들을 뒤집음.
-
reverse_copy 범위 내 원소들을 뒤집은 상태로 복사함. (원본은 유지)
-
// until C++20
template< class BidirIt >
void reverse( BidirIt first, BidirIt last );
template< class BidirIt, class OutputIt >
OutputIt reverse_copy( BidirIt first, BidirIt last, OutputIt d_first );
// since C++20
template< class BidirIt >
constexpr void reverse( BidirIt first, BidirIt last );
template< class BidirIt, class OutputIt >
constexpr OutputIt reverse_copy( BidirIt first, BidirIt last, OutputIt d_first );
// since C++17
template< class ExecutionPolicy, class BidirIt >
void reverse( ExecutionPolicy&& policy, BidirIt first, BidirIt last );
template< class ExecutionPolicy, class BidirIt, class ForwardIt >
ForwardIt reverse_copy( ExecutionPolicy&& policy, BidirIt first, BidirIt last,
ForwardIt d_first );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main() {
cout << "Call reverse():" << endl;
vector<int> v{1,2,3};
reverse(begin(v), end(v));
for(auto e : v) cout << e;
cout << endl;
int a[] = {4, 5, 6, 7};
reverse(begin(a), end(a));
for(auto e : a) cout << e;
cout << endl;
cout << "Call reverse_copy():" << endl;
// lambda
auto print = [](vector<int> const& v) {
for (const auto& value : v)
cout << value << ' ';
cout << '\t';
};
print(v);
vector<int> destination(3);
reverse_copy(begin(v), end(v), begin(destination));
print(destination);
reverse_copy(rbegin(v), rend(v), begin(destination));
print(destination);
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++17
$ ./a.out
Call reverse():
321
7654
Call reverse_copy():
3 2 1 1 2 3 3 2 1
*/
-
rotate 범위 내 원소들을 왼쪽으로 회전시킴.
-
rotate_copy 범위 내 원소들을 왼쪽으로 회전시칸 후 복사. (원본은 유지)
-
// until C++11
template< class ForwardIt >
void rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );
// since C++11 until C++20
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );
// until C++20
template< class ForwardIt, class OutputIt >
OutputIt rotate_copy( ForwardIt first, ForwardIt n_first,
ForwardIt last, OutputIt d_first );
// since C++20
template< class ForwardIt >
constexpr ForwardIt rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );
template< class ForwardIt, class OutputIt >
constexpr OutputIt rotate_copy( ForwardIt first, ForwardIt n_first,
ForwardIt last, OutputIt d_first );
// since C++17
template< class ExecutionPolicy, class ForwardIt >
ForwardIt rotate( ExecutionPolicy&& policy, ForwardIt first, ForwardIt n_first,
ForwardIt last );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 rotate_copy( ExecutionPolicy&& policy, ForwardIt1 first,
ForwardIt1 n_first, ForwardIt1 last, ForwardIt2 d_first );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void print(string msg, vector<int> &v) {
cout << msg;
for (auto n : v)
cout << n << " ";
cout << endl;
}
int main() {
vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
print("Before: ", v);
rotate(v.begin(), v.begin() + 1, v.end());
print("Simple left rotate: ", v);
rotate(v.begin(), v.begin() + 1, v.end());
print("Simple left rotate: ", v);
rotate(v.begin(), v.begin() + 1, v.end());
print("Simple left rotate: ", v);
rotate(v.rbegin(), v.rbegin() + 3, v.rend());
print("Simple right rotate: ", v);
vector<int> v2(v.size());
auto pivot = find(v.begin(), v.end(), 5);
rotate_copy(v.begin(), pivot, v.end(), v2.begin());
print("Call rotate_copy(): ", v2);
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
Before: 1 2 3 4 5 6 7 8 9
Simple left rotate: 2 3 4 5 6 7 8 9 1
Simple left rotate: 3 4 5 6 7 8 9 1 2
Simple left rotate: 4 5 6 7 8 9 1 2 3
Simple right rotate: 1 2 3 4 5 6 7 8 9
Call rotate_copy(): 5 6 7 8 9 1 2 3 4
*/
-
shift_left, shift_right 범위 내 주어진 횟수만큼 쉬프트 연산 (C++20부터 지원)
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct S {
int value{0};
bool specified_state{true};
S(int v = 0) : value{v} {}
S(S const& rhs) = default;
S(S&& rhs) { *this = move(rhs); }
S& operator=(S const& rhs) = default;
S& operator=(S&& rhs) {
if (this != &rhs) {
value = rhs.value;
specified_state = rhs.specified_state;
rhs.specified_state = false;
}
return *this;
}
};
ostream& operator<< (ostream& os, vector<S> const& v) {
for (const auto& s : v)
s.specified_state ? os << s.value << ' ' : os << "? ";
return os << '\n';
}
int main() {
vector<S> v{1,2,3,4,5,6,7};
cout << v;
shift_left(v.begin(), v.end(), 3);
cout << v;
shift_right(v.begin(), v.end(), 2);
cout << v;
return 0;
}
/*
$ g++ test.cpp -std=c++2a
$ ./a.out
1 2 3 4 5 6 7
4 5 6 7 ? ? ?
? ? 4 5 6 7 ?
*/
-
shuffle 무작위로 원소들을 섞음.
// since C++11
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );
// ----------------------------------------------------------------------------------
#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
random_device rd;
mt19937 g(rd());
shuffle(v.begin(), v.end(), g);
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
9 2 3 8 1 10 4 6 5 7
$ ./a.out
3 4 1 7 10 6 5 2 8 9
*/
-
sample 범위 내에서 무작위로 주어진 개수만큼 원소를 샘플링. (C++17 부터 지원)
// since C++17
template< class PopulationIterator, class SampleIterator,
class Distance, class URBG >
SampleIterator sample( PopulationIterator first, PopulationIterator last,
SampleIterator out, Distance n, URBG&& g);
// ----------------------------------------------------------------------------------
#include <iostream>
#include <random>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string in = "hgfedcba", out;
sample(in.begin(), in.end(), back_inserter(out), 5,
mt19937{random_device{}()});
cout << "five random letters out of " << in;
cout << " : " << out << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++17
$ ./a.out
five random letters out of hgfedcba : gedcb
$ ./a.out
five random letters out of hgfedcba : hgeda
*/
-
unique 중복된 원소를 제거한 후 마지막 원소의 iterator 반환.
-
unique_copy 중복된 원소를 제거한 후 복사. (원본 유지)
-
// until C++20
template< class ForwardIt >
ForwardIt unique( ForwardIt first, ForwardIt last );
template< class ForwardIt, class BinaryPredicate >
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPredicate p );
template< class InputIt, class OutputIt >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first );
template< class InputIt, class OutputIt, class BinaryPredicate >
OutputIt unique_copy( InputIt first, InputIt last,
OutputIt d_first, BinaryPredicate p );
// since C++20
template< class ForwardIt >
constexpr ForwardIt unique( ForwardIt first, ForwardIt last );
template< class ForwardIt, class BinaryPredicate >
constexpr ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPredicate p );
template< class InputIt, class OutputIt >
constexpr OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first );
template< class InputIt, class OutputIt, class BinaryPredicate >
constexpr OutputIt unique_copy( InputIt first, InputIt last,
OutputIt d_first, BinaryPredicate p );
// since C++17
template< class ExecutionPolicy, class ForwardIt >
ForwardIt unique( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last );
template< class ExecutionPolicy, class ForwardIt, class BinaryPredicate >
ForwardIt unique( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last,
BinaryPredicate p );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
class BinaryPredicate >
ForwardIt2 unique_copy( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryPredicate p );
// ----------------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <iterator>
using namespace std;
int main() {
// a vector containing several duplicate elements
vector<int> v{1,2,1,1,3,3,3,4,5,4};
// remove consecutive (adjacent) duplicates
auto last = unique(v.begin(), v.end());
// v now holds {1 2 1 3 4 5 4 x x x}, where 'x' is indeterminate
v.erase(last, v.end());
for (int i : v) cout << i << " ";
cout << endl;
// sort followed by unique, to remove all duplicates
sort(v.begin(), v.end()); // {1 1 2 3 4 4 5}
last = unique(v.begin(), v.end());
// v now holds {1 2 3 4 5 x x}, where 'x' is indeterminate
v.erase(last, v.end());
for (int i : v) cout << i << " ";
cout << endl;
string s1 = "The string with many spaces!";
string s2;
cout << "before: " << s1 << endl;
unique_copy(s1.begin(), s1.end(), back_inserter(s2),
[](char c1, char c2){ return c1 == ' ' && c2 == ' '; });
cout << "after: " << s2 << endl;
return 0;
}
/*
$ g++ test.cpp -std=c++11
$ ./a.out
1 2 1 3 4 5 4
1 2 3 4 5
before: The string with many spaces!
after: The string with many spaces!
*/
'Programming Language > C++' 카테고리의 다른 글
표준 템플릿 라이브러리(STL) - 정렬 알고리즘 (0) | 2020.11.20 |
---|---|
표준 템플릿 라이브러리(STL) - 파티셔닝 알고리즘 (0) | 2020.11.20 |
표준 템플릿 라이브러리(STL) - 변경 불가 알고리즘 (0) | 2020.11.19 |
표준 템플릿 라이브러리(Standard Template Library) (0) | 2020.11.17 |
템플릿(Template) (0) | 2020.11.16 |