c++求无重复元素的全排列——三种方法实现
程序员文章站
2022-06-28 12:54:36
...
废话:
这里前两种是处理无重复元素的全排列,最后一种是都可以处理,哈哈,如果不想看前两种,直接看最后一种吧,但还是建议读者学会前两种,有益无害,本蒟蒻的思路来自我的老师 ,听老师的培训来写的 老师博客
1交换法
#include <iostream>
using namespace std;
int n=3 ;
int cnt = 0;
void Permutation(char *s,int p)//从数组s的第p个位置开始全排列
{
if(p==n)
{
printf("%s\n",s);
cnt++;
return ;
}
for(int i=p;i<n;i++)
{
swap(s[i],s[p]);//每个字符都有成为当前起始字符的机会
Permutation(s,p+1);
swap(s[i],s[p]);//返回初始状态,才能保证后面的交换是正确的, 回溯
}
}
int main()
{
char s[5] = "abc";
Permutation(s,0);
cout<<cnt<<endl;
return 0;
}
2抽取法(dfs实现)
这种方法想必学过dfs都知道,哈哈哈哈
#include <iostream>
using namespace std;
int n=3 ;
int cnt = 0;//统计全排列种类数
char tmp[5]="";//定义一个临时数组来保存抽取到的元素
char s[5] = "abc";
int used[5];//used[i]判断抽取过第i个元素
void dfs(int p)
{
if(p==n)
{
printf("%s\n",tmp);
cnt++;
return ;
}
for(int i=0;i<n;i++)
{
if(!used[i])//没有使用过
{
tmp[p] = s[i];
used[i] = 1;//标记为使用过
dfs(p+1);
used[i] = 0;//回溯
}
}
}
int main()
{
dfs(0);
cout<<cnt<<endl;
return 0;
}
STL 大杀器(一定要看)
next_permutation:数组元素初始必须是升序的,
输出也是按字典序升序的
prev_permutation:数组元素初始必须是降序的,
输出也是按字典序降序的
头文件:#include<algorithm>
优点:自动排序,自动去重, 代码少, 不容易犯错,推荐使用,这里本蒟弱推荐大家都使用这个
next_permutation:
#include <iostream>
#include<algorithm>//头文件
using namespace std;
int main()
{
char s[5] = "abc";
int cnt = 0;
do
{
cout<<s<<endl;
cnt++;
}while(next_permutation(s,s+3));//起始位置,左闭右开
cout<<"总共有:"<<cnt<<" 种排列"<<endl;
return 0;
}
升序排
:prev_permutation
#include <iostream>
#include<algorithm>//头文件
using namespace std;
int main()
{
char s[5] = "cba";
int cnt = 0;
do
{
cout<<s<<endl;
cnt++;
}while(prev_permutation(s,s+3));//起始位置,左闭右开
cout<<"总共有:"<<cnt<<" 种排列"<<endl;
return 0;
}
按降序排的
上一篇: 工具吧-互联网人的工具箱
下一篇: IIS安装以及发布