为什么next_permutation会跳过一些排列?

时间:2015-07-07 01:43:55

标签: c++ permutation

为什么这个简单的函数不输出输入的5个字母串的所有排列?我认为应该有120,它只输出90.

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

// Creates permutation lists for strings
vector<string> createdcombos2(string letters)
{ 
    vector<string> lettercombos;    

    cout << "Letters are: " << letters << endl; //input string

    do 
        lettercombos.push_back(letters);        
    while(next_permutation(letters.begin(), letters.end()));    

    cout <<"Letter combos: " << endl;  //print out permutations 
    for (auto i : lettercombos)
        cout << i << endl;
    cout << endl << lettercombos.size() << endl; //number of permutations

    return lettercombos;
}


int main() 
{
    string letters = "gnary"; 
    vector<string> lettercombos;

    lettercombos = createdcombos2(letters);
}

4 个答案:

答案 0 :(得分:25)

要返回循环中的所有排列,直到next_permutation返回false,必须在循环开始之前对向量进行排序。 next_permutation按升序返回排列。因此,如果你从一个未排序的向量开始,它将从一系列排列开始。

localhost:8888/js

答案 1 :(得分:13)

正如之前提到的一些答案所述,如果您想使用bool的{​​{1}}返回值来停止迭代,则必须确保从#34;排序&#34;排列。否则,您的周期将提前终止。

但这并非绝对必要。

通过std::next_permutation枚举的排列形成一个没有开头或结尾的循环序列,这意味着您可以无限期地调用std::next_permutation并且它将循环通过相同的序列120次排列,一次又一次。这意味着您可以从该循环中的绝对任何排列开始。你只需要记住你的起始排列,并观察这个排列再次出现的那一刻。在你到达原始排列的那一刻,迭代就结束了。在您的情况下,预计会拨打120 std::next_permutation

例如,以下代码打印std::next_permutation集的所有5个字母的排列,即使它是从一个完全任意的

开始的

"abcde"

可以注意到,在周期的每次迭代中比较排列比使用std::string start = "cadeb", current = start; do std::cout << current << std::endl; while (std::next_permutation(current.begin(), current.end()), current != start); 的返回值(来自算法内部的#34;免费&#34;)更昂贵,因此,如果您对预先排序起始排列的解决方案感到满意,那么它确实是一种更有效的方法。

或者,如果你知道周期中的确切排列数(在这种情况下是120),你可以简单地调用std::next_permutation这个次数(如@ Potatoswatter的回答中所建议的那样)。

答案 2 :(得分:12)

您需要对输入进行排序,void ctlGrid_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { DataRowView item = (DataRowView)e.Row.DataItem; //get value of Color from the bound data string color = item["Color"].ToString(); //make sure that the casing (i.e., lower, upper or proper) of each checkbox ID matches what's in the DB ((CheckBox)e.Row.FindControl(color)).Checked = true; } } 将按字典顺序返回下一个排列。因为输入排列:“gnary”按字典顺序“大于”排列,例如“愤怒”,所以永远不会达到那些“较小”的排列。

您可以使用next_permutation

对字符串进行排序

答案 3 :(得分:6)

bool的返回next_permutation值类似于溢出条件或进位。当它从最后一个排列回到第一个排列时,它是false,按字典顺序排列。但它仍无条件地推进。

如果您知道正好有120个排列,您可以忽略返回值并盲目循环:

for ( int i = 0; i != 120; ++ i ) {
    lettercombos.push_back(letters);        
    next_permutation(letters.begin(), letters.end());
}