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

Posted

技术标签:

【中文标题】C++:列出字符串的排列【英文标题】:C++: Listing the permutations of a string 【发布时间】:2012-05-25 20:21:51 【问题描述】:

我想就效率问我所有的程序员同事。我目前正在解决工作面试中可能会问到的问题,并且遇到了著名的 string 排列。我在下面写的代码可能是编程历史上最常见的东西,但是我不知道它的状态,因为我没有检查任何解决方案。

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

#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;

【问题讨论】:

你知道std::next_permutation,对吧? 是的,我愿意。但没有提到它,因为它是一个标准库,而不是我想出的解决方案 如果你对人们正确地告诉你不要重新发明***不感兴趣,那么这属于CodeReview.SE 而不是 SO。 我非常感谢我从来没有经历过这些采访,以及他们可能会问的疯狂问题。这是咨询和/或教学历史的优势。你的名声在你之前。 【参考方案1】:

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

【讨论】:

感谢您的反馈。我会检查的!顺便说一句,有什么建议吗:D?【参考方案2】:

你可以使用递归:

#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 中编译和测试)。

【讨论】:

可能速度较慢但很好了解选项(尤其是面试准备)【参考方案3】:

我通过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;

【讨论】:

如果你愿意使用标准库,那为什么不使用std::next_permutation呢?我不明白。 实施自己的解决方案很有价值,这是一种很好的做法。当然,如果您想“完成工作”并提高工作效率,请使用标准库。【参考方案4】:

您的问题的答案是。在您知道它有效之前,您不应该担心任何提议的解决方案的效率。而这个不行。

以下内容证明了这一事实。

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$ 

【讨论】:

我已经更正了代码。检查我的答案并感谢您的贡献

以上是关于C++:列出字符串的排列的主要内容,如果未能解决你的问题,请参考以下文章

c++编程 全排列

LeetCode1528. 重新排列字符串(C++)

在 C++ 中生成字符串的排列

查找并列出字符串 C++ 中的所有字符簇

在 C++ 中检查一个字符串是不是是另一个字符串的排列

华为OD机试 2023最新 字符串重新排列字符串重新排序(C++ 100%)