Algorithms Overview
En çok kullanılan bir takım algoritmalar STL kütüphanesinde bulunmaktadır. Bunlar iyi implemente ve test edilmiş algoritmalar olup hali hazırda kullandığımız container’larla da uyumludur.
Algorithms with Predicates
A predicate is a C++ function returning a boolean or an object having a bool operator()
member. A unary predicate takes one argument, a binary takes two, and so on. Examples of questions predicates can answer for a particular algorithm are:
- Is this element what we are looking for?
- Is the first of two arguments ordered first in our order?
- Are the two arguments equal?
Almost all STL algorithms take a predicate as last argument.
You can construct new predicates using standard, self-defined, and/or predicate-making classes (here is a good reference).
https://stackoverflow.com/questions/5921609/what-is-predicate-in-c
Algorithms with _if Versions
Algoritmaların predicate’li halidir. Belli bir koşulun gerçekleşmesi durumunda işlem yapar. Örneğin count algoritması verilen elemanın container içinde kaç tane bulunduğunu sayar. count_if fonksiyonunda bunu daha da özelleştirip belli bir koşula göre saymasını sağlayabiliyoruz.
vector <int> vec{3,5,6,8,10,5,5,6,8};
cout << count(vec.begin(), vec.end(), 5) << endl; //3
cout << count_if(vec.begin(), vec.end(),
[](int n) {
return n % 2 == 0;
}
) << endl; // 5
Lambda Expressions
isimsiz fonksiyonlardır. Başka bir fonksiyona atmak için normal bir fonksiyon yazmak istemiyorsanız kullanabilirsiniz.
- capture clause (Also known as the lambda-introducer in the C++ specification.)
- parameter list Optional. (Also known as the lambda declarator)
- mutable specification Optional.
- exception-specification Optional.
- trailing-return-type Optional.
- lambda body.
Capture
[] // capture nothing
[=] // capture all by value
[&] // capture all by reference
[&total, factor] // capture by reference, capture by value
[factor, &total] // capture by value, capture by reference
[&, factor] // capture all by reference EXCEPT factor
[=, &total] // capture all by value EXCEPT total
mutable
Typically, a lambda’s function call operator is const-by-value, but use of the mutable
keyword cancels this out. It doesn’t produce mutable data members. The mutable
specification enables the body of a lambda expression to modify variables that are captured by value. Some of the examples later in this article show how to use mutable
.
https://learn.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-170
Pair Type
pair<int, string> myPair{5,"Hello"};
auto myPair {make_pair{5,"Hello"}}; // std::make_pair
pair myPair{5,"Hello"}; // C++11 CTAD
Insert Iterators
container’a yeni ögeler eklememize olanak tanır.
- back_inserter() -> back_insert_iterator döndürür
- front_inserter() -> front_insert_iterator döndürür
- inserter -> insert_iterator döndürür
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main() {
auto printList = [](list<int> myList) {
for (auto& i : myList) cout << i << ", ";
cout << endl;
};
list<int> l{ 3,4,5 };
printList(l);
// 3, 4, 5,
auto bi = back_inserter(l);
*bi = 6;
*bi = 7;
*bi = 8;
printList(l);
// 3, 4, 5, 6, 7, 8,
auto fi = front_inserter(l);
*fi = 2;
*fi = 1;
*fi = 0;
printList(l);
// 0, 1, 2, 3, 4, 5, 6, 7, 8,
auto loc = find(l.begin(), l.end(), 5);
auto in = inserter(l, loc);
*in = 99;
*in = 99;
*in = 99;
printList(l);
// 0, 1, 2, 3, 4, 99, 99, 99, 5, 6, 7, 8,
}
Library Function Objects
A function object is any object for which the function call operator is defined. C++ provides many built-in function objects as well as support for creation and manipulation of new function objects.
https://en.cppreference.com/w/cpp/utility/functional
Searching Algorithms
find
N tane eleman içinde verilen tek bir elemanı arar. Bulduğu ilk elemanın iteratörünü döndürür.
string str = "This is a string";
string vowels = "aeiou";
auto firstOne = find(str.begin(), str.end(), 'a');
if (firstOne != str.end()) {
cout << *firstOne; //a
cout << distance(str.begin(), firstOne); //8
}
https://cplusplus.com/reference/algorithm/find
find_end & search
N tane eleman içinde, S tane elemandan oluşan aralığı arar. Yani büyük bir parçanın içinde küçük bir parçayı arar.
- search -> ilk görülen lokasyonu döndürür
- find_end -> son görülen lokasyonu döndürür
string str = "This thing is a string";
string vowels = "ng";
auto firstOne = search(str.begin(), str.end(), vowels.begin(), vowels.end());
auto lastOne = find_end(str.begin(), str.end(), vowels.begin(), vowels.end());
if (firstOne != str.end()) {
cout << *firstOne; //n
cout << distance(str.begin(), firstOne); //8
}
cout << endl;
if (lastOne != str.end()) {
cout << *lastOne; //n
cout << distance(str.begin(), lastOne); //20
}
find_first_of
N tane eleman içinde, S tane elemandan herhangi birini arar. Yani aranan ögenin elemanlarından bir tanesi tutsun da hangisi tutarsa tutsun.
string str = "This is a string";
string vowels = "aeiou";
auto firstOne = find_first_of(str.begin(), str.end(), vowels.begin(), vowels.end());
if (firstOne != str.end())
cout << *firstOne; // i
https://cplusplus.com/reference/algorithm/find_first_of
find_if & find_if_not
vector<int> vec{ 1,2,3,4,5,6,7,8,9,10,12 };
auto fi = *find_if(vec.begin(), vec.end(), [](int& i) { return i % 3 == 0; });
auto fin = *find_if_not(vec.begin(), vec.end(), [](int& i) {return i % 2 == 1; });
cout << fi << " " << fin << endl; // 3 2
adjacent_find
birbirine bitişik aynı elamanları arar. == operatörünü kullanır ama biz bir predicate vererek bu
vector<int> vec0{ 0,1,0,0,1,0,0,0,1,1 };
auto af0 = adjacent_find(vec0.begin(), vec0.end());
vector<int> vec1{ 0,1,2,3,5,6,7 };
auto f = [](int i, int j) { return i + 2 == j; };
auto af1 = adjacent_find(vec1.begin(), vec1.end(), f);
cout << distance(vec0.begin(), af0) << endl; // 2
cout << distance(vec1.begin(), af1) << endl; // 3
search_n
verilen elemandan n adet yan yana gelirse
vector<int> vec{ 0,1,0,0,1,0,0,0,1,1 };
auto one = search_n(vec.begin(), vec.end(), 1, 0);
auto two = search_n(vec.begin(), vec.end(), 2, 0);
auto thr = search_n(vec.begin(), vec.end(), 3, 0);
cout << distance(vec.begin(), one) << endl; // 0
cout << distance(vec.begin(), two) << endl; // 2
cout << distance(vec.begin(), thr) << endl; // 5
mismatch
İki conteiner’ı karşılaştırır, ilk eşleşmeyen elemanları pair<> şeklinde döndürür.
vector<int> vec { 3, 5, 1, 7, 9, 11 };
vector<int> vec2{ 3, 5, 1, 99, 9, 11 };
auto p = mismatch(vec.begin(), vec.end(), vec2.begin());
cout << *p.first << " " << *p.second << endl; // 7 99
all_of, none_of, any_of
- all_of() -> predicate her eleman için true => true
- none_of() -> predicate her eleman için false => true
- any_of() -> predicate en az bir eleman için true => true
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
auto is_odd = [](int& i) { return i % 2 == 1; };
auto is_even = [](int& i) { return i % 2 == 0; };
vector<int> vec{ 3,5,1,7,9,11 };
auto b = vec.begin();
auto e = vec.end();
cout << all_of(b, e, is_odd) << endl; // 1
cout << all_of(b, e, is_even) << endl; // 0
cout << none_of(b, e, is_odd) << endl; // 0
cout << none_of(b, e, is_even) << endl;// 1
vector<int> vec2{ 4,5,1,7,9,11 };
b = vec2.begin();
e = vec2.end();
cout << any_of(b, e, is_odd) << endl; // 1
cout << any_of(b, e, is_even) << endl;// 1
}
Binary Search
Sıralı bir container’da, Binary Search algoritmasını kullanarak verilen aralıkta istenilen elemanı arar.
vector<int> vec{ 3,5,1,7,9,11 };
sort(vec.begin(), vec.end());
if (binary_search(vec.begin(), vec.end(), 7))
cout << "7 is an element of vec\n";
else
cout << "7 is not an element of vec\n";
// 7 is an element of vec
includes
Verilen elemanlar(vec2), bakılan aralıkta(vec) bir alt küme ise true döndürür. Container’ların sıralı olması gerekmektedir.
vector<int> vec{ 3,5,1,7,9,11 };
vector<int> vec2{11,1,3 };
sort(vec.begin(), vec.end());
sort(vec2.begin(), vec2.end());
if (includes(vec.begin(), vec.end(), vec2.begin(),vec2.end()))
cout << "vec includes vec2\n";
else
cout << "vec does not includes vec2\n";
// vec includes vec2
Numeric Algorithms
iota
Fills the range [
first,
last)
with sequentially increasing values, starting with value and repetitively evaluating ++value.
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
void pvec(vector<int> v) {
for (auto& i : v) cout << i << ", ";
cout << endl;
}
int main(){
vector<int> vec0(10);
vector<int> vec1(10);
iota(vec0.begin(), vec0.end(), 0);
iota(vec1.begin(), vec1.end(), 5);
pvec(vec0); // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
pvec(vec1); // 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
}
accumulate
Verilen aralığı toplar
std::accumulate
performs a left fold. In order to perform a right fold, one must reverse the order of the arguments to the binary operator, and use reverse iterators.
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
void pvec(vector<int> v) {
for (auto& i : v) cout << i << ", ";
cout << endl;
}
int main(){
vector<int> vec(10);
iota(vec.begin(), vec.end(), 7);
pvec(vec);
// 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
int initial_value0{ 0 }, initial_value1{ 20 };
cout << accumulate(vec.begin(), vec.end(), initial_value0) << endl;
cout << accumulate(vec.begin(), vec.end(), initial_value1) << endl;
// 115
// 135
accumulate(vec.begin(), vec.end(), initial_value0,
[](int& a, int& b) {
cout << "a: " << a << "\tb: " << b << endl;
return a + b;
}
);
// a: 0 b: 7
// a: 7 b: 8
// a: 15 b: 9
// a: 24 b: 10
// a: 34 b: 11
// a: 45 b: 12
// a: 57 b: 13
// a: 70 b: 14
// a: 84 b: 15
// a: 99 b: 16
}
reduce
accumulate’in modern versiyonu.
https://blog.tartanllama.xyz/accumulate-vs-reduce
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <execution>
using namespace std;
void pvec(vector<int> v) {
for (auto& i : v) cout << i << ", ";
cout << endl;
}
int main(){
vector<int> vec(10);
iota(vec.begin(), vec.end(), 7);
pvec(vec);
// 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
int initial_value0{ 0 }, initial_value1{ 20 };
cout << reduce(vec.begin(), vec.end(), initial_value0) << endl;
cout << reduce(vec.begin(), vec.end(), initial_value1) << endl;
// 115
// 135
reduce(std::execution::par,vec.begin(), vec.end(), initial_value0,
[](int a, int b) {
cout << "a: " << a << "\tb: " << b << endl;
return a + b;
}
);
// a: 0 b: a: 97
// a: b: 10
// 7 b: 8
// a: 11 b: 12
// a: 15 b: 16
// a: 13 b: 14
// a: 15 b: 19
// a: 34 b: 23
// a: 57 b: 31
// a: 88 b: 27
}
Write-only Algorithms
fill & fill_n
fill, verilen elemanla istenilen aralığı doldurur.
vector<int> vec(10);
fill(vec.begin(), vec.end(), 5);
pvec(vec);
fill_n(vec.begin(), 5, 3);
pvec(vec);
// 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
// 3, 3, 3, 3, 3, 5, 5, 5, 5, 5,
generate & generate_n
int jj = 0;
auto f = [&jj]() {return ++jj; };
vector<int> vec(10);
generate(vec.begin(), vec.end(), f);
pvec(vec);
generate_n(vec.begin(), 5, f);
pvec(vec);
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
// 11, 12, 13, 14, 15, 6, 7, 8, 9, 10,
for_each Algorithm
vector<int> vec{7,4,5,2,6,4,6,4,1,2,3};
for_each(vec.begin(), vec.end(), [](int& i) {cout << i << ", "; });
// 7, 4, 5, 2, 6, 4, 6, 4, 1, 2, 3,
Copying Algorithms
int main(){
vector<int> vec{7,4,5,2,6,4,6,4,1,2,3};
vector<int> vec1;
copy(vec.begin(), vec.end(), back_inserter(vec1));
pvec(vec1);
// 7, 4, 5, 2, 6, 4, 6, 4, 1, 2, 3,
vector<int> vec2(vec.size());
copy_n(vec.begin(), 7, vec2.begin());
pvec(vec2);
// 7, 4, 5, 2, 6, 4, 6, 0, 0, 0, 0,
vector<int> vec3(vec.size());
copy_if(vec.begin(), vec.end(), vec3.begin(), [](int& i) {return i % 2; });
pvec(vec3);
// 7, 5, 1, 3, 0, 0, 0, 0, 0, 0, 0,
}
Write Algorithms (replace)
string str = { "AATTSSSGGGGAA"};
cout << str << endl;// AATTSSSGGGGAA
replace(str.begin(), str.end(), 'A', 'T');
cout << str << endl << endl;// TTTTSSSGGGGTT
string str2;
replace_copy(str.begin(), str.end(), back_inserter(str2), 'S', 'A');
cout << str2 << endl; // TTTTAAAGGGGTT
cout << str << endl; // TTTTSSSGGGGTT
replace_if(str.begin(), str.end(), [](const char& c) {return c != 'G'; }, '-');
cout << str << endl; // -------GGGG--
Removing Algorithms
remove
- shifting yaparak eleman siler. Silinen elemanlar mantıksal olarak silinmiş olup container’ın boyutu değişmez.
- _if ve _copy ‘li versiyonları mevcuttur.
string str = { "AATTSSSGGGGAA"};
cout << str << endl;
auto it = remove(str.begin(), str.end(), 'A');
cout << str << endl;
string new_str(str.begin(), it);
cout << new_str << endl;
// AATTSSSGGGGAA // original
// TTSSSGGGGGGAA // after remove
// TTSSSGGGG // new string by iterator
erase
vector<int> vec{3, 4, 8, 5, 5, 9, 0, 4, 5, 5, 6, 5, 0, 9, 7, 2, 3, 6, 4, 5};
pvec(vec);
erase(vec, 5);
pvec(vec);
// 3, 4, 8, 5, 5, 9, 0, 4, 5, 5, 6, 5, 0, 9, 7, 2, 3, 6, 4, 5,
// 3, 4, 8, 9, 0, 4, 6, 0, 9, 7, 2, 3, 6, 4,
unique
Sıralanmış bir containerda tekrar eden elemanları, teke indirir. remove() gibi container boyutunda bir değişiklik yapmaz.
vector<int> vec{3, 4, 8, 5, 5, 9, 0, 4, 5, 5, 6, 5, 0, 9, 7, 2, 3, 6, 4, 5};
pvec(vec);
sort(vec.begin(), vec.end());
pvec(vec);
auto it = unique(vec.begin(), vec.end());
pvec(vec);
vec.erase(it, vec.end());
pvec(vec);
// 3, 4, 8, 5, 5, 9, 0, 4, 5, 5, 6, 5, 0, 9, 7, 2, 3, 6, 4, 5,
//
// 0, 0, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 9,
// 0, 2, 3, 4, 5, 6, 7, 8, 9, 5, 5, 5, 5, 5, 6, 6, 7, 8, 9, 9,
//
// 0, 2, 3, 4, 5, 6, 7, 8, 9,
Transform Algorithm
verilen fonksiyonu istenilen aralığa uygular. 1 veya 2 container girdi olarak kullanılabilir. Çıktı ile girdi containerı aynı olabilir.
int main(){
vector<int> vec{ 3, 4, 8, 5, 5, 9 };
vector<int> vec2(vec.size());
vector<int> vec3;
cout << "to different container" << endl;
std::transform(vec.begin(), vec.end(), vec2.begin(), [](int& i) {return i * 3; });
cout << "vec : \t"; pvec(vec);
cout << "vec2: \t"; pvec(vec2);
cout << endl << endl;
cout << "to same container" << endl;
std::transform(vec.begin(), vec.end(), vec.begin(), [](int& i) {return i * 4; });
cout << "vec : \t"; pvec(vec);
cout << endl << endl;
cout << "back inserter" << endl;
std::transform(vec.begin(), vec.end(), back_inserter(vec3), [](int& i) {return i + 2; });
cout << "vec3: \t"; pvec(vec3);
cout << endl << endl;
cout << "With 3 container (2 input 1 output) " << endl;
std::transform(vec.begin(), vec.end(), vec2.begin(), vec3.begin(), [](int& a, int& b) { return a + b; });
cout << "vec : \t"; pvec(vec );
cout << "vec2: \t"; pvec(vec2);
cout << "vec3: \t"; pvec(vec3);
// to different container
// vec : 3, 4, 8, 5, 5, 9,
// vec2: 9, 12, 24, 15, 15, 27,
//
//
// to same container
// vec : 12, 16, 32, 20, 20, 36,
//
//
// back inserter
// vec3: 14, 18, 34, 22, 22, 38,
//
//
// With 3 container (2 input 1 output)
// vec : 12, 16, 32, 20, 20, 36,
// vec2: 9, 12, 24, 15, 15, 27,
// vec3: 21, 28, 56, 35, 35, 63,
}
Merging Algorithms
- merge: iki container’ı birleştirir.
- set_intersection: kesişim
- set_union: birleşim
int main(){
vector<int> vec0{ 3, 4, 8, 5, 5, 9 };
vector<int> vec1{ 8, 5, 5, 9, 10, 25, 20 };
vector<int> vec2, vec3, vec4;
sort(vec0.begin(), vec0.end());
sort(vec1.begin(), vec1.end());
pvec(vec0); // 3, 4, 5, 5, 8, 9,
pvec(vec1); // 5, 5, 8, 9, 10, 20, 25,
cout << endl;
merge(vec0.begin(), vec0.end(), vec1.begin(), vec1.end(), back_inserter(vec2));
pvec(vec2); // 3, 4, 5, 5, 5, 5, 8, 8, 9, 9, 10, 20, 25,
set_intersection(vec0.begin(), vec0.end(), vec1.begin(), vec1.end(), back_inserter(vec3));
pvec(vec3); // 5, 5, 8, 9,
set_union(vec0.begin(), vec0.end(), vec1.begin(), vec1.end(), back_inserter(vec4));
pvec(vec4); // 3, 4, 5, 5, 8, 9, 10, 20, 25,
}
Reordering Algorithms
vector<int> vec{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
reverse(vec.begin(), vec.end()); pvec(vec);
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
rotate(vec.begin(), vec.begin() + 2, vec.end()); pvec(vec);
// 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
// 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
// 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
// 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
// 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
Partitioning Algorithms
- partition() : verilen predicate’e göre containerı sağ/sol böler. bir tarafta true olanlar öteki tarafta false olanlar.
- stable_partition() : bölerken sıralama dikkat eder.
- is_partition() : Bölünmüş mü diye kontrol eder.
- partition_point() : bölünme noktasını forward iterator olarak verir.
int main(){
vector<int> vec1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<int> vec2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
partition(vec1.begin(), vec1.end(), [](int i) {return i % 2; });
pvec(vec1); // 9, 1, 7, 3, 5, 4, 6, 2, 8, 0,
stable_partition(vec2.begin(), vec2.end(), [](int i) {return i % 2; });
pvec(vec2); // 1, 3, 5, 7, 9, 0, 2, 4, 6, 8,
cout << is_partitioned(vec2.begin(), vec2.end(), [](int i) {return i % 2; }) << endl; // 1
auto it = partition_point(vec2.begin(), vec2.end(), [](int i) {return i % 2; });
cout << *it << endl; // 0
vector<int> vec3(vec2.begin(), it);
pvec(vec3); // 1, 3, 5, 7, 9,
}
Sorting Algorithms
- sort: verilen aralığı artan şekilde sıralar
- stable sort: sıralama yaparken, aynı elemanlarını sıralamasına dikkat eder. Örneğin bir kuyrukta genç olanlara öncelik verilecektir. Lakin bu sıralamayı yaparken aynı yaştaki insanların kendi aralarındaki sıralaması korumak istiyoruz. işte bu tip durumlarda stable sort kullanılabilir
- is_sorted: verilen aralığın sıralı olup olmadığını kontrol eder
- is_sorted_until: sıralamayı bozan ilk elemanın iteratörünü döndürür.
- partial_sort: Verilen aralıktaki ilk n elemanı sırala.
nth_element()
Rearranges the elements in the range [first,last)
, in such a way that the element at the nth position is the element that would be in that position in a sorted sequence.
The other elements are left without any specific order, except that none of the elements preceding nth are greater than it, and none of the elements following it are less.
The elements are compared using operator<
for the first version, and comp for the second.
https://cplusplus.com/reference/algorithm/nth_element
Permutation Algorithms
Olası tüm sıralama kombinasyonlarını verir.
int main(){
string str1{ "ABC" }, str2{ "CBA" };
do {
cout << str1 << endl;
} while (next_permutation(str1.begin(), str1.end()));
cout << str1 << endl;
// ABC
// ACB
// BAC
// BCA
// CAB
// CBA
// ABC
cout << endl;
do {
cout << str2 << endl;
} while (prev_permutation(str2.begin(), str2.end()));
cout << str2 << endl;
// CBA
// CAB
// BCA
// BAC
// ACB
// ABC
// CBA
}
If the function can determine the next higher permutation, it rearranges the elements as such and returns true
. If that was not possible (because it is already at the largest possible permutation), it rearranges the elements according to the first permutation (sorted in ascending order) and returns false
.
https://cplusplus.com/reference/algorithm/next_permutation
Min and Max Algorithms
int main(){
cout << min(10, 5) << endl; // 5
cout << max(10, 5) << endl; // 10
cout << min({1,4,6,2,3,6,8,9,4,10}) << endl; // 1
cout << max({1,4,6,2,3,6,8,9,4,10}) << endl; // 10
// min max returns a pair<>
auto mm0 = minmax(10, 5);
auto mm1 = minmax({ 1,4,6,2,3,6,8,9,4,10 });
cout << mm0.first << " " << mm0.second << endl; // 5 10
cout << mm1.first << " " << mm1.second << endl; // 1 10
// _element
vector<int> vec{1,4,6,2,3,6,8,9,4,10};
cout << *min_element(vec.begin(), vec.end()) << endl; // 1
cout << *max_element(vec.begin(), vec.end()) << endl; // 10
auto mm2 = minmax_element(vec.begin(), vec.end());
cout << *mm2.first << " " << *mm2.second << endl; // 1 10
// clamp
cout << clamp(-5, 0, 10) << endl; // 0
cout << clamp( 5, 0, 10) << endl; // 5
cout << clamp(15, 0, 10) << endl; // 10
}
Further Numeric Algorithms
int main(){
// vec (a,b,c,... )
// partial sum: (a, a+b, a+b+c, ... )
// adjacent difference (a, b-a, c-b, ... )
vector<int> vec{1,6,4,27,21,6,2,32};
pvec(vec); // 1, 6, 4, 27, 21, 6, 2, 32,
partial_sum(vec.begin(), vec.end(), vec.begin());
pvec(vec); // 1, 7, 11, 38, 59, 65, 67, 99,
adjacent_difference(vec.begin(), vec.end(), vec.begin());
pvec(vec); // 1, 6, 4, 27, 21, 6, 2, 32,
// vec1 (a1, b1, c1, ...)
// vec2 (a2, b2, c2, ...)
// inner product of vec1 and vec2: a1*a2 + b1*b2 + c1*c2 + ...
vector<int> vec1{ 1,6,4 };
vector<int> vec2{ 2,1,6 };
pvec(vec1);
pvec(vec2);
cout << inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0) << endl; // 32
}
https://en.cppreference.com/w/cpp/numeric/special_functions
Introduction to Random Numbers
Random Numbers in Older C++
rand()
srand(time(0)) // time(0) return the current time (value return by time() only changes once per second)
Random Numbers in Modern C++
default_random_number_engine eng;
eng() // call the functor to get the next number
mt19937 //mersenne twister
destributution types
- bernoulli, normal, poissiion
random_device
Random Number Algorithms
shuffle()
Leave a Reply