C++:列出字符串的排列

C++: Listing the permutations of a string

本文关键字:排列 字符串 C++      更新时间:2023-10-16

我想问问我所有的程序员同事,只关于效率。我目前正在解决在求职面试中可能提出的问题,并且我遇到了著名的字符串排列。我在下面编写的代码可能是编程历史上最常见的代码,但是,我不知道它的状态,因为我没有检查任何解决方案。

长话短说,我在下面编写的程序会是一个合适的解决方案吗?或者可以提高效率。问,因为如果我有一天遇到,我想确保我已经为这个问题实施了最佳方法之一。

#include <iostream>
using namespace std;
int fac(int num)
{
    int result=1;
    for(int i=1;i<=num;i++)
        result*=i;
    return result;
}
int main(int argc, const char * argv[])
{
    string str="abcd";
    int limit=fac(str.size());
    int mod=str.size();
    for(int i=0;i<limit;i++){
        swap(str[i%mod],str[(i+1)%mod]);
        cout<<str<<endl;
    }
    return 0;
}

不处理字符串中的重复字母,例如 "aaabbb" .

你可以使用递归:

#include <iostream>
#include <tchar.h>
#include <string>
using namespace std;
void swap(char &first, char &second) {
    char tmp = first;
    first = second;
    second = tmp;
}
void enumPermutations(string &p, int m)
{
    if (m == p.size() - 1)
        cout << p << endl;
    else
        for (int j = m; j < p.size(); j++) {
            swap(p[j], p[m]);
            enumPermutations(p, m+1);
            swap(p[j], p[m]);
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
    string str = "abcd";
    enumPermutations(str, 0);
    getchar();
    return 0;
}

(在Visual Studio中编译和测试)。

我已经通过使用std::map找到了解决方案。不要认为它效率低下;

#include <iostream>
#include <map>
#include <vector>
using namespace std;
int fac(int num)
{
    int result=1;
    for(int i=1;i<=num;i++)
        result*=i;
    return result;
}
int main(int argc, const char * argv[])
{
    string str="aabb";
    int limit=fac(str.size());
    int mod=str.size();
    std::map<string,bool>T;
    vector<string>permutations;
    for(int i=0;i<limit;i++){
        if(T[str]==0){
            permutations.push_back(str);
            T[str]=1;
        }
        swap(str[i%mod],str[(i+1)%mod]);
    }
    for(int i=0;i<permutations.size();i++)
        cout<<permutations[i]<<endl;
    return 0;
}

您的问题的答案是否定的。在知道任何建议的解决方案有效之前,您不必担心它的效率。 而这个不起作用。

下面说明这一事实。

ben-tillys-macbook-pro:ton btilly$ cat foo.cc
#include <iostream>
using namespace std;
int fac(int num)
{
    int result=1;
    for(int i=1;i<=num;i++)
        result*=i;
    return result;
}
int main(int argc, const char * argv[])
{
    string str="abcd";
    int limit=fac(str.size());
    int mod=str.size();
    for(int i=0;i<limit;i++){
        swap(str[i%mod],str[(i+1)%mod]);
        cout<<str<<endl;
    }
    return 0;
}
ben-tillys-macbook-pro:ton btilly$ g++ foo.cc
ben-tillys-macbook-pro:ton btilly$ ./a.out | wc
      24      24     120
ben-tillys-macbook-pro:ton btilly$ ./a.out | sort -u | wc
      12      12      60
ben-tillys-macbook-pro:ton btilly$ ./a.out | grep bdc
ben-tillys-macbook-pro:ton btilly$