[英]Elegant Way To Generate Composite Permutations in C++
I have a class Test which contains two vectors of a Letter class, a user defined type for which the less-than operator (<) has been implemented. 我有一个Test类,其中包含两个Letter类的向量,这是一个用户定义的类型,已经实现了小于运算符(<)。 How can I best generate all possible permutations of Test?
如何最好地生成Test的所有可能排列?
class Test
{
vector<Letter> letter_box_a;
vector<Letter> letter_box_b;
}
So if letter_box_a contains the letters A and B and letter_box_b contains C and D the valid permutations of Test would be (AB)(CD), (BA)(CD), (AB)(DC) and (BA)(DC). 因此,如果letter_box_a包含字母A和B,而letter_box_b包含字母C和D,则Test的有效排列将为(AB)(CD),(BA)(CD),(AB)(DC)和(BA)(DC)。
Although I am able to brute force it, I was trying to write a better (more elegant/efficient) function which would internally call std::next_permutation on the underlying containers allowing me to do 虽然我可以蛮力,但是我试图编写一个更好的(更优雅/更有效)的函数,该函数在底层容器上内部调用std :: next_permutation,使我能够
Test test;
while (test.set_next_permutation())
{
// Do the stuff
}
but it appears to be a bit trickier than I first anticipated. 但这似乎比我最初预期的要复杂。 I don't necessarily need an STL solution but would like an elegant solution.
我不一定需要STL解决方案,但想要一个优雅的解决方案。
If you want to use std::next_permutation
, you need a nested loop for each vector you are permuting: 如果要使用
std::next_permutation
,则需要对要排列的每个向量进行嵌套循环:
std::string s0 = "ab";
std::string s1 = "cd";
do
{
do
{
cout << s0 << "" << s1 << endl;
} while (std::next_permutation(s0.begin(), s0.end()));
} while (std::next_permutation(s1.begin(), s1.end()));
Output: 输出:
abcd
bacd
abdc
badc
And, in the class: 并且,在课堂上:
class Foo
{
public:
Foo(std::string_view arg_a, std::string_view arg_b)
: a(arg_a)
, b(arg_b)
, last(false)
{ }
void reset_permutations()
{
last = false;
}
bool next_permutation(std::string& r)
{
if (last)
return false;
if (not std::next_permutation(a.begin(), a.end()))
if (not std::next_permutation(b.begin(), b.end()))
last = true;
r = a + b;
return true;
}
private:
std::string a, b;
bool last;
};
int main(int argc, const char *argv[])
{
Foo foo("ab", "cd");
string s;
while (foo.next_permutation(s))
cout << s << endl;
return 0;
}
I would think you could do something like 我想你可以做些类似的事情
bool Test::set_next_permutation() {
auto &a = letter_box_a, &b = letter_box_b; // entirely to shorten the next line
return std::next_permutation(a.start(), a.end()) || std::next_permutation(b.start(), b.end());
}
(Of course, a while
loop will skip the initial permutation in any case. You want a do
... while
loop instead.) (当然,在任何情况下,
while
循环都会跳过初始排列。您需要使用do
... while
循环。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.