[英]Is it possible to get something similar to std::next_permutation, but doesn't always use all the letters in the string?
我目前有这个代码
void get_permutations(std::string s, std::vector<std::string>& vec)
{
std::sort(s.begin(), s.end());
do {
vec.push_back(s);
} while (std::next_permutation(s.begin(), s.end()));
}
它按预期工作,但是 next_permutation 使用s
中的每个字符,我想简单地获取字符串中每个字符的每个组合。 (没有重复)
例子:
输入:
abc
output:
a, b, c, ab, ac, abc, acb, etc
是否有另一种标准方法,或者我必须自己制作?
是的,或多或少有一种标准方法。
将使用计数和位掩码。
如果您有 3 个字母的排列,例如“abc”,那么我们将创建如下所示的位掩码:
1. 001 --> "--c"
2. 010 --> "-b-"
3. 011 --> "-bc"
4. 100 --> "a--"
5. 101 --> "a-c"
6. 110 --> "ab-"
7. 111 --> "abc"
你看,我们只是从 1 开始数到 2^(字符串的长度)。 然后,对于每个设置位,我们 select 来自字符串的原始当前排列一个字母。
由于您确实只需要唯一的组合,因此我们使用std::set
来消除重复项。
有点简单。 . .
许多可能的解决方案之一可能是:
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <set>
std::vector<std::string> get_permutation(std::string s) // Yes, pass by value, make a copy
{
std::set<std::string> result{}; // Here we will store the result as set
std::sort(s.begin(), s.end()); // Sort input string in order to get permutations
do {
for (size_t k = 1; k < (1 << s.length()); ++k) { // Count and mask
std::string combination = {}; // Here wewill stor all possible combinations
for (unsigned int m{1}, i{}; m < (1 << s.length()); m <<= 1, i++)
if (k & m) combination += s[i]; // Add letter, if bit mask is set
result.insert(combination); // Add new combination. Std::set will make it unique
}
} while (std::next_permutation(s.begin(), s.end())); // And the next 3 letter permutation
return { result.begin(), result.end() }; // Return result as vector
}
int main()
{
std::string s = "abc";
for (const std::string& c : get_permutation(s)) std::cout << c << '\n';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.