1、不重复数的实现
如果一个数字十进制表达时,不存在连续两位相同,则称之为“不重复数”。例如,105、164和198都是“不重复数”,而11、100和122不是。
下面用一个long类型( long类型数字A),实现返回大于A的最小“不重复数”。
解答:
如1223445,从左往右找到第1个重复的数,将后面重复的那个数加1,然后将重复数后面的数设置为0101...,
1223445 -> 1230101
特殊的是重复的数是9的情况,如1099446,此时
将重复之前的那位加1,如果认为重复数,
循环。
1099446 -> 1101010
-> 1201010
#include <stdio.h> #include <stdlib.h> #define _DEBUG 1 #define MAXN 65 int check(int *arr,int n){//寻找重复数位置 int i,pos=-1; for(i=n-1;i>=0;i--){ if(arr[i]==arr[i-1]) return i; } return -1;//不存在重复数 } void set0or1(int *arr,int startPos){ int flag=0; for(int i=startPos;i>=0;i--){ arr[i]=flag; flag=1-flag; } } long GetNotRepeatNum(long num){ int arr[MAXN]={0}; int count=0; while(num){//将数字存到数组中 arr[count++]=num%10; num/=10; } int pos;//重复数的位置 while((pos=check(arr,count))!=-1){ if(arr[pos]==9){ arr[pos+1]++; if(pos+1==count){//需要进位1 count++; } set0or1(arr,pos); }else{ arr[pos-1]++; set0or1(arr,pos-2); } } long nnum=0; for(int i=count-1;i>=0;i--){ nnum=nnum*10+arr[i]; } return nnum; } int main(){ int num; while(scanf("%d",&num)!=EOF){ printf("%d\n",GetNotRepeatNum(num+1)); } } |
这道题的思路与按字典需生成全排列的思路很相似,只不过在生成全排列中,
从右往左寻找的是第1个按字典序升序的一对字符
2、按字典需生成全排列
寻找下一个按字典序的排列:
从右往左寻找的是第1个按字典序升序的一对元素(ij,i<j),如果不存在,则说明所有排列都查找完毕,否则,从右往左寻找第一个大于i的元素记为k,将i和k交换,然后从j开始到结束的位置子序列反序。如 359872,找到升序的一对元素(i、j分别为5、9),找到大于i的第一个元素为7,交换5、7得379852,将j开始到结束的子序列反序得到372589.
#include <algorithm> using namespace std; template <typename T> void CalcAllPermutation(T perm[], int num) { if (num < 1) return; while (true) { int i; for (i = num - 2; i >= 0; --i) { if (perm[i] < perm[i + 1]) break; } if (i < 0) break; // 已经找到所有排列 int k; for (k = num - 1; k > i; --k) { if (perm[k] > perm[i]) break; } swap(perm[i], perm[k]); reverse(perm + i + 1, perm + num); } } int main() { const int NUM = 12; char perm[NUM]; for (int i = 0; i < NUM; ++i) perm[i] = 'a' + i; CalcAllPermutation(perm, NUM); } |
全排列算法更常见的另一中实现使用递归实现。
3、全排列算法的递归实现
从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而
得到所有元素的全排列
得到所有元素的全排列
#include <iostream> #include <algorithm> using namespace std; template <typename T> void CalcAllPermutation_R(T perm[], int first, int num) { if (num <= 1) { return; } for (int i = first; i < first + num; ++i) { swap(perm[i], perm[first]); CalcAllPermutation_R(perm, first + 1, num - 1); swap(perm[i], perm[first]); } } int main() { const int NUM = 12; char perm[NUM]; for (int i = 0; i < NUM; ++i) perm[i] = 'a' + i; CalcAllPermutation_R(perm, 0, NUM); } |