2024-03-08 15:25:16 +08:00

94 lines
3.2 KiB
C++

#include "ABasic.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <vector>
/*
详细解释一下 next_permutation:
该函数接受两个迭代器参数,表示排列的范围 [first, last),其中 [first, last)
是一个升序排列。 next_permutation
会尝试重新排列范围中的元素,使其变为下一个字典序更大的排列,如果成功返回
true,否则返回 false。
cppreference 解释:
变换范围 [first, last) 为来自所有按相对于 operator< 或 comp
的字典序的下个排列。若这种排列存在则返回 true ,
否则变换范围为首个排列(如同用 std::sort(first, last) )并返回 false 。
字典序是一种排序方式,类似于英文字典中的单词排序。对于数字排列,字典序就是数字的递增顺序。例如,数字
123 在字典序中排在数字 132 的前面。
对于一个给定范围的排列,next_permutation
将会重新排列这些元素,生成下一个字典序更大的排列。
如果当前排列已经是最大字典序的排列(即已经是升序排列),那么
next_permutation 将重新排列成最小字典序的排列, 然后返回
false,表示没有下一个更大的排列了。
*/
// 生成 N 个不同元素的全排列
void generatePermutations()
{
int elements[] = {1, 2, 3, 4};
const size_t N = sizeof(elements) / sizeof(elements[0]);
std::vector<int> vec(elements, elements + N);
int count = 0;
do {
std::cout << ++count << ": ";
// 打印写法
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl;
} while (next_permutation(vec.begin(), vec.end()));
}
/*
组合
输出从 7 个不同元素中取出 3 个元素的所有组合。
思路:对序列 { 1, 1, 1, 0, 0, 0, 0 } 做全排列。
对于每个排列,输出数字 1 对应的位置上的元素。
*/
void combinationDemo()
{
int values[] = {1, 2, 3, 4, 5, 6, 7};
int elements[] = {1, 1, 1, 0, 0, 0, 0};
const size_t N = sizeof(elements) / sizeof(elements[0]);
assert(N == sizeof(values) / sizeof(values[0]));
std::vector<int> selectors(elements, elements + N);
int count = 0;
do {
std::cout << ++count << ": ";
for (size_t i = 0; i < selectors.size(); ++i) {
if (selectors[i]) {
std::cout << values[i] << ", ";
}
}
std::cout << std::endl;
} while (prev_permutation(selectors.begin(), selectors.end()));
}
// 这里写一个仿函数 或者 使用 lambda 表达式都可以
struct AreBothSpaces {
bool operator()(char x, char y) const { return x == ' ' && y == ' '; }
};
// 移除连续空格
void removeContinuousSpaces(std::string& str)
{
std::cout << "PreString:" << str << std::endl;
// std::string::iterator last =
// std::unique(str.begin(), str.end(), AreBothSpaces());
std::string::iterator last2 =
std::unique(str.begin(), str.end(),
[](char x, char y) { return x == ' ' && y == ' '; });
str.erase(last2, str.end());
std::cout << "AfterString:" << str << std::endl;
}