About next_permutation
来源:互联网 发布:淘宝定向投放 编辑:程序博客网 时间:2024/06/05 00:16
对于“下一个排列”,一开始不懂子集与搜索的概念,就穷举了好多种情况,发现了其中的规律
算法如下:
1. 对给定的排列,从右到左扫描各个字符,如果这些字符从右到左是按字典序递增的,该排列就是最后一个,没有下一个排列。
2. 从右到左扫描各个字符,如果第k个字符不是按字典序递增的,下一个排列可以将第k个字符增加一位后修改得到。
3.将第k个字符增加一位后,可能与该字符前缀中的字符重复,那就再增加一位,直到与前缀中的字符不重。
4.若第k个字符增加一位后,仅与该字符后缀中的字符重复,那就与后缀中重复的字符互换。
5.执行第4步后,保留前缀和新的第k个字符,将后缀的字符按字典序重新排列就得到原排列紧接的排列。
以下是代码实现:
char* next_permutation(char *str){ int t,m,temp; int l=strlen(str); for(int i=l-1; i>=0; i--) { if(str[i-1]<str[i]) { t=i; break; } } if(t==0) return NULL; else { for(int i=l-1; i>=0; i--) { if(str[i]>str[t-1]) { m=i; break; } } temp=str[t-1]; str[t-1]=str[m]; str[m]=temp; for(int i=0; i<l-t; i++) { for(int j=l-1-i; j<l-1; j++) { if(str[j]>str[j+1]) { temp=str[j]; str[j]=str[j+1]; str[j+1]=temp; } } } return str; }}当然,也可以直接用STL库里的next_permutation函数,需要加头文件<algorithm>
附:题目
POJ 1731 - Orders(全排列)
#include <iostream>#include <cstring>#include <algorithm>using namespace std;int main(){ char a[10000]; while(cin>>a) { sort(a,a+strlen(a)); cout<<a<<endl; while(next_permutation(a,a+strlen(a))) { cout<<a<<endl; } } return 0;}
#include <iostream>#include <cstring>#include <algorithm>using namespace std;char* next_permutation(char *str){ int t,m,temp; int l=strlen(str); for(int i=l-1; i>=0; i--) { if(str[i-1]<str[i]) { t=i; break; } } if(t==0) return NULL; else { for(int i=l-1; i>=0; i--) { if(str[i]>str[t-1]) { m=i; break; } } temp=str[t-1]; str[t-1]=str[m]; str[m]=temp; for(int i=0; i<l-t; i++) { for(int j=l-1-i; j<l-1; j++) { if(str[j]>str[j+1]) { temp=str[j]; str[j]=str[j+1]; str[j+1]=temp; } } } cout<<str<<endl; next_permutation(str); }}int main(){ char a[10000]; while(cin>>a) { sort(a,a+strlen(a)); cout<<a<<endl; next_permutation(a); } return 0;}
UVa 10098 - Generating Fast
同样是全排列,只需注意输出换行,代码就不给出了
UVa 146 - ID Codes(下一个排列)
#include <iostream>#include <cstring>#include <algorithm>using namespace std;int main(){ char a[10000]; while(gets(a)!=NULL) { if(strcmp(s,"#")==0)break; next_permutation(a,a+strlen(a)); cout<<a<<endl; } return 0;}
UVa 729 - The Hamming Distance Problem(二进制全排列)
#include <cstring>#include <algorithm>using namespace std;int main(){ char a[100]; int ncase,n,b; cin>>ncase; while(ncase--) { cin>>n>>b; for(int i=0;i<n-b;i++)a[i]='0'; for(int i=n-b;i<n;i++)a[i]='1'; a[n]='\0'; while(next_permutation(a,a+strlen(a)) cout<<a<<endl; if(ncase)cout<<endl; } return 0;}
#include <stdio.h>#include <stdlib.h>#include <string.h>void next(char *str){ int i,j,l,t,m,temp; l=strlen(str); for(i=l-1; i>=0; i--) { if(str[i-1]<str[i]) { t=i; break; } } if(t==0) return; else { for(i=l-1; i>=0; i--) { if(str[i]>str[t-1]) { m=i; break; } } temp=str[t-1]; str[t-1]=str[m]; str[m]=temp; for(i=0; i<l-t; i++) { for(j=l-1-i; j<l-1; j++) { if(str[j]>str[j+1]) { temp=str[j]; str[j]=str[j+1]; str[j+1]=temp; } } } printf("%s\n",str); next(str); }}int main(){ char a[100]; int e,i,j,l,t,Case,n; scanf("%d",&Case); for(e=0; e<Case; e++) { scanf("%d%d",&l,&n); for(i=0; i<l; i++) a[i]='0'; for(i=l-1,j=0; j<n; j++,i--) a[i]='1'; a[l]='\0'; puts(a); next(a); if(e<Case-1) putchar('\n'); } return 0;}
- About next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- next_permutation
- oracle截取字符串
- 程序员怎样学数学
- C语言的一个奇怪的问题?
- session和cookie详解
- MTK笔试面试题集锦
- About next_permutation
- 栈和队列的问题
- WMI编程之一:在VC中使用WMI
- 获取JScript对象的expando属性的方法
- (读书笔记)关于innodb IO调优
- TD插件无法自动下载成功
- MATLAB Products--MATLAB 产品
- 为什么使用RTP协议?
- jquery实现简单的页签切换