Fork me on GitHub

简单的字母全排列问题—递归法和STL法

问题描述:求全由小写字母组成的不超过200个字符序列的全排列
如输入序列bbjd,排列结果为:
bbdj
bbjd
bdbj
bdjb
bjbd
bjdb
dbbj
dbjb
djbb
jbbd
jbdb
jdbb
 
方法一:递归法
 
代码如下:
 
复制代码
#include <stdio.h>

int t[200];
char s[200];
int n = 0;

void permutation(int i)
{
    int k;

    // a~z的ASCII码在97到122之间
    for(k = 97; k < 123; k++)
    {
        if(t[k])
        {
            t[s[i] = k]--;
            permutation(i + 1);
            t[k]++;
        }
    }

    // 只有n个字母全部排好了才输出
    n - i || puts(s);
}

int main()
{    
    int i;

    puts("Please Input letter sequence: ");
    gets(s);

    // t[]记录每个字母的出现频率
    // n为待排序列的长度
    for(i = 0; s[i] != '\0'; i++)
    {
        t[s[i]]++;
        n++;
    }

    puts("Permutation result: ");
    permutation(0);

    return 0;
}
复制代码

运行结果如下:

 

方法二:STL法

C++的STL有一个函数可以方便地生成全排列,这就是next_permutation

在C++ Reference中查看了一下next_permutation的函数声明:

#include <algorithm>
bool next_permutation( iterator start, iterator end );

The next_permutation() function attempts to transform the given range of elements [start,end) into the next lexicographically greater permutation of elements. If it succeeds, it returns true, otherwise, it returns false.

 

从说明中可以看到 next_permutation 的返回值是布尔类型。按照提示写了一个标准C++程序:

其中用到了 sort 函数,如果不先排序,则完成不了全排列。

 

复制代码
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    string str;

    cout << "Please Input letter sequence: \n";
    cin >> str;
    
    // 必须先排序
    sort(str.begin(), str.end());
    cout << str << endl;

    cout << "Permutation result: \n";

    while(next_permutation(str.begin(), str.end()))
    {
        cout << str << endl;
    }

    return 0;
}
复制代码

运行结果如下:

 

在使用稍大数据测试的时候,发现标准C++的效率很差,换成C函数写一下,效率提升了许多倍,比如我用字符序列“aabbddef”作为测试,上面C++代码用了6s,而下面的C代码只用了0.918s。所以,平时写代码时能用C就用C。

 

复制代码
#include <stdio.h>
#include <algorithm>

using namespace std;

int main()
{
    char str[200];
    int len;

    puts("Please Input letter sequence: ");
    gets(str);

    len = strlen(str);
    
    // 必须先排序
    sort(str, str + len);

    puts("Permutation result: ");
    puts(str);

    while(next_permutation(str, str + len))
    {
        puts(str);
    }

    return 0;
}
复制代码

 

posted @   Alexia(minmin)  阅读(5401)  评论(5编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
无觅关联推荐,快速提升流量
点击右上角即可分享
微信分享提示