实现返回大于A的最小“不重复数” 百度2014校招笔试题

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); 
}   


发布了27 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/hysfwjr/article/details/12167861