我有一个Test类,其中包含两个Letter类的向量,这是一个用户定义的类型,已实现了小于运算符(<)。如何最好地生成Test的所有可能排列?
class Test
{
vector<Letter> letter_box_a;
vector<Letter> letter_box_b;
}
因此,如果letter_box_a包含字母A和B,而letter_box_b包含字母C和D,则Test的有效排列为(AB)(CD),(BA)(CD),(AB)(DC)和(BA)( DC)。
尽管我能够蛮力,但是我试图编写一个更好的(更优雅/更有效)的函数,该函数在底层容器上内部调用std :: next_permutation
Test test;
while (test.set_next_permutation())
{
// Do the stuff
}
,但似乎比我最初预期的要复杂一些。我不一定需要STL解决方案,但想要一个优雅的解决方案。
答案 0 :(得分:0)
如果要使用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()));
输出:
abcd
bacd
abdc
badc
而且,在班上:
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;
}
答案 1 :(得分:0)
我认为您可以做类似的事情
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());
}
(当然,while
循环在任何情况下都会跳过初始排列。您希望使用do
... while
循环。)