ACM零起点2017-7-26(全排列问题)
来源:互联网 发布:聚宝盆软件官方下载 编辑:程序博客网 时间:2024/06/06 02:54
今天学习了全排列问题,搜索了网上了很多代码,作此总结!
总体上,全排列常用的算法实现有两种,一种是很简单的STL,另一种则是递归实现,递归实现的过程中,要特别注意题目是否要求去除重复的排列!但是注意一点,目前我还没有找到可以满足题目要求的递归算法,因为普通的递归全排列虽然可以去除重复的排列,但是不能保证按照字典序输出!!!另外,该递归算法的理解可能有些困难,可以自己在稿纸上进行书写,递归的反复自我调用,和回返调用比较麻烦的!!!下面结合实例进行代码总结!
给出一个字符串S(可能有重复的字符),按照字典序从小到大,输出S包括的字符组成的所有排列,可能有前导零,且不可忽视,比如001的全排列则是:001,010,100。例如:S = "1312",
输出为:
1123
1132
1213
1231
1312
1321
2113
2131
2311
3112
3121
3211
AC代码:
代码一(STL实现):
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char s[100];
cin>>s;
sort(s,s+strlen(s));
char *first=s;
char *last=s+strlen(s);
do
{
cout<<s<<endl;
}while(next_permutation(first,last));
return 0;
}
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
char s[100];
cin>>s;
sort(s,s+strlen(s));
char *first=s;
char *last=s+strlen(s);
do
{
cout<<s<<endl;
}while(next_permutation(first,last));
return 0;
}
延伸学习:如果题目要求从大到小输出的话,可以如下修改代码哦!!!
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
bool cmp(char a,char b)
{
return a>b;
}
int main()
{
char s[100];
cin>>s;
sort(s,s+strlen(s),cmp);
char *first=s;
char *last=s+strlen(s);
do
{
cout<<s<<endl;
}while(prev_permutation(first,last));
return 0;
}
上面用到了prev_permutation求的是上一个排列,next_permutation求的是下一个排列。注意要先排序!!!
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
bool cmp(char a,char b)
{
return a>b;
}
int main()
{
char s[100];
cin>>s;
sort(s,s+strlen(s),cmp);
char *first=s;
char *last=s+strlen(s);
do
{
cout<<s<<endl;
}while(prev_permutation(first,last));
return 0;
}
上面用到了prev_permutation求的是上一个排列,next_permutation求的是下一个排列。注意要先排序!!!
bool next_permutation(BidIt first, BidIt last, Pred pr);
代码二(STL实现):
代码二(STL实现):
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int main()
{
string str;
cin>>str;
sort(str.begin(),str.end());
do
{
cout<<str<<endl;
}while(next_permutation(str.begin(),str.end()));
return 0;
}
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int main()
{
string str;
cin>>str;
sort(str.begin(),str.end());
do
{
cout<<str<<endl;
}while(next_permutation(str.begin(),str.end()));
return 0;
}
代码三(非该题代码!!!递归实现,可去除重复,但不能按照字典序输出,该题过不了)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
static int num;//记录排列数
bool is_swap(char str[],int st,int k)
{
for(int i=st;i<k;i++)
if(str[i]==str[k])
return false;
return true;
}
void full_permutation(char str[],int st,int en)
{
if(st==en)
{
num++;//记录排列数
for(int i=0;i<=en;i++)
printf("%c",str[i]);
printf("\n");
}
else
{
for(int i=st;i<=en;i++)//递归比较复杂,可自己画递归图
{
if(is_swap(str,st,i))//去除重复的排列
{
swap(str[i],str[st]);
full_permutation(str,st+1,en);
swap(str[i],str[st]);
}
}
}
}
int main()
{
char str[1000];
scanf("%s",str);
full_permutation(str,0,strlen(str)-1);
printf("排列总数:%d\n",num);
return 0;
}
#include<cstring>
#include<algorithm>
using namespace std;
static int num;//记录排列数
bool is_swap(char str[],int st,int k)
{
for(int i=st;i<k;i++)
if(str[i]==str[k])
return false;
return true;
}
void full_permutation(char str[],int st,int en)
{
if(st==en)
{
num++;//记录排列数
for(int i=0;i<=en;i++)
printf("%c",str[i]);
printf("\n");
}
else
{
for(int i=st;i<=en;i++)//递归比较复杂,可自己画递归图
{
if(is_swap(str,st,i))//去除重复的排列
{
swap(str[i],str[st]);
full_permutation(str,st+1,en);
swap(str[i],str[st]);
}
}
}
}
int main()
{
char str[1000];
scanf("%s",str);
full_permutation(str,0,strlen(str)-1);
printf("排列总数:%d\n",num);
return 0;
}
阅读全文
0 0
- ACM零起点2017-7-26(全排列问题)
- ACM零起点2017-7-24(刷题)
- ACM零起点2017-7-25(随机数产生方法)
- ACM零起点2017-7-28(贪心算法)
- ACM零起点2017-7-25(C++ STL in ACM)
- ACM零起点2017-7-25(sort用重载运算符对结构体排序)
- ACM零起点2017-7-25(二叉搜索树概念)
- ACM零起点2017-7-27(查找算法之------尺取法、二分法、三分法)
- ACM零起点2017-7-27(C++中string的基本用法)
- ACM零起点2017-7-25(sort对结构体排序 PK 自创C语言对结构体快排)
- 全排列问题(STL)
- acm练习 零起点学算法78——牛牛 2017 02 24
- 全排列算法(c语言实现)acm练习
- 3D计算机图形学零起点全攻略
- 3D计算机图形学零起点全攻略
- 3D计算机图形学零起点全攻略
- 2017华为机试题--全排列问题
- 哈理工 2005 排列问题(STL中的全排列)
- Spinner与Gallery
- ajax参数详解
- BigDecimal的问题
- 变量交换
- ubuntu安装jdk1.8
- ACM零起点2017-7-26(全排列问题)
- [C#]Application
- 基于微信红包插件的原理实现android任何APP自动发送评论(已开源)
- 安装office2010常见的提示错误解决办法
- background-position用法详解
- springmvc结合freemarker配置url访问的根路径
- JAVA外观模式
- The Grove bfs+射线思想
- SpringMVC学习(六) 关于mvc:annotation-driven标签