在c ++中查找字符串的所有排列

时间:2013-06-09 05:40:53

标签: c++ string

以下是打印给定字符串的所有排列的代码。代码编译但不打印任何内容。

using namespace std;

void RecPermute(string, string);

int main() {
    RecPermute("", "abc");
    return 0;
}

void RecPermute(string soFar, string rest) {
    if (rest == " ") {
        cout << soFar << endl;
    } else {
        for(int i=0; i<rest.length(); i++) {
            string next = soFar + rest[i];
            string remaining = rest.substr(0, i) + rest.substr(i+1);
            RecPermute(next, remaining);
    }
    }
}

需要修复什么?

2 个答案:

答案 0 :(得分:13)

您的方法有效(使用greedybuddha提供的正确条件),但可以更简单地实现(如Chris所建议的那样)。

#include <algorithm>
#include <iostream>
#include <string>

int main()
{
    std::string s("abcdefg");
    do
    {
        std::cout << s << "\n";
    }
    while ( std::next_permutation(s.begin(), s.end()) );
}

那它做了什么? std::next_permutation需要两个迭代器,一个是字符串的开头,第二个是结尾,所以基本上你说的是“考虑整个字符串”。它会置换字符串s,以便在调用之后,s包含将在s的上一个值之后直接出现在词典顺序中的唯一排列。如果s是最后一个这样的排列(即输入“abcdefg”的“gfedcba”),std::next_permutation会返回false,因此您知道自己已完成。

由于您没有使用此代码创建任何新的(临时)字符串,因此它不仅更具可读性,而且更快。在我的机器上,对于“abcdefghij”,您的算法大约需要5秒钟,使用std::next_permutation的算法在不到一秒的时间内完成。对于另一个角色,它变得更糟,到54秒对6.8秒。

请注意,如果初始字符串未排序,则将提供完整的排列列表。但当然有一个简单的解决方案:在置换之前执行std::sort(s.begin(), s.end());

答案 1 :(得分:1)

所以你真是太诱人了。您只需要匹配空字符串而不是空格。您可以通过匹配空字符串""来完成此操作。

更改

if (rest == " ") { ... }

if (rest == "") { ... }

你忘了rest.substr(i + 1)的长度,它应该是(i + 1,i-3);