Permutations
std::prev_permutation
and std::next_permutation
return the previous smaller or next bigger permutation of the newly ordered range. If a smaller or bigger permutation is not available, the algorithms return false
. Both algorithms need bidirectional iterators. Per default the predefined sorting criterion std::less
is used. If you use your sorting criterion, it has to obey the strict weak ordering. If not, the program is undefined.
std::vector<int> myInts{1, 2, 3};
do{
for (auto i: myInts) std::cout << i;
std::cout << " ";
} while(std::next_permutation(myInts.begin(), myInts.end()));
// 123 132 213 231 312 321
std::reverse(myInts.begin(), myInts.end());
do{
for (auto i: myInts) std::cout << i;
std::cout << " ";
} while(std::prev_permutation(myInts.begin(), myInts.end()));
// 321 312 231 213 132 123
Min and Max
You can determine the minimum, the maximum and the minimum and maximum pair of a range with the algorithms std::min_element
, std::max_element
and std::minmax_element
. Each algorithm can be configured with a binary predicate.
int toInt(const std::string& s){
std::stringstream buff;
buff.str("");
buff << s;
int value;
buff >> value;
return value;
}
std::vector<std::string> myStrings{"94", "5", "39", "-4", "-49", "1001", "-77",
"23", "0", "84", "59", "96", "6", "-94"};
auto str= std::minmax_element(myStrings.begin(), myStrings.end());
std::cout << *str.first << ":" << *str.second; // -4:96
auto asInt= std::minmax_element(myStrings.begin(), myStrings.end(),
[](std::string a, std::string b){ return toInt(a) < toInt(b); });
std::cout << *asInt.first << ":" << *asInt.second; // -94:1001
Numeric
std::accumulate
without callable uses the following strategy
result = init;
result += *(first+0);
result += *(first+1);
...
std::adjacent_difference
without callable uses the following strategy:
*(result) = *first;
*(result+1) = *(first+1) - *(first);
*(result+2) = *(first+2) - *(first+1);
...
std::partial_sum
without callable uses the following strategy:
*(result) = *first;
*(result+1) = *first + *(first+1);
*(result+2) = *first + *(first+1) + *(first+2)
...
std::array<int, 9> arr{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::cout << std::accumulate(arr.begin(), arr.end(), 0); // 45
std::cout << std::accumulate(arr.begin(), arr.end(), 1,
[](int a, int b){ return a*b; } ); // 362880
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> myVec;
std::adjacent_difference(vec.begin(), vec.end(),
std::back_inserter(myVec), [](int a, int b){ return a*b; });
for (auto v: myVec) std::cout << v << " "; // 1 2 6 12 20 30 42 56 72
std::cout << std::inner_product(vec.begin(), vec.end(), arr.begin(), 0); // 285
myVec= {};
std::partial_sum(vec.begin(), vec.end(), std::back_inserter(myVec));
for (auto v: myVec) std::cout << v << " "; // 1 3 6 10 15 21 28 36 45
std::vector<int> myLongVec(10);
std::iota(myLongVec.begin(), myLongVec.end(), 2000);
for (auto v: myLongVec) std::cout << v << " ";
// 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009