94 lines
3.2 KiB
C++
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;
|
||
|
}
|