• 求比指定数大且最小的“不重复数”问题


    给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数.

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    
    #define NUMBER_STR_MAX_LENGTH (128)
    unsigned find(unsigned);
    
    int main(void)
    {
        unsigned num = 0;
    
        printf("Please input Unsigned Number : ");
        if (scanf("%u", &num) != 1) {
            perror("input error!");
            return 1;
        }
    
        printf("%u
    ", find(num));
        return 0;    
    }
    
    void str_reverse(unsigned char *str,unsigned length)
    {
        unsigned char *prv = NULL;
        unsigned char *cur = NULL;
        unsigned char swap = '';
    
        for (prv = str, cur = str + (length-1)
                ; prv < cur; ++prv, --cur){
            swap = *prv;
            *prv = *cur;
            *cur = swap;
        }
    }
    
    unsigned find(unsigned number)
    {
        unsigned char number_str[NUMBER_STR_MAX_LENGTH] = {''};
        unsigned char *prv = NULL;
        unsigned char *cur = NULL;
        unsigned char *finded = NULL;
        unsigned int number_length = 0;
        unsigned int result = 0;  
        int carry = 0;
    
        ++number;
        number_length = sprintf(number_str, "%u", number);
        str_reverse(number_str, number_length);
    
        for (cur = number_str + (number_length-1), finded = number_str
                ; cur > finded - 1 ; --cur ){
        
            if (prv != NULL && *prv == *cur){
                finded = cur;
                carry = 1;
                do {
                    *cur += carry;
                    carry = (*cur - '0') / 10u;
                    *cur = (*cur-'0') % 10u + '0';
                    ++cur;
                } while (carry != 0 && cur < (number_str + number_length));
                if (carry > 0){
                    *cur = '0' + carry ;
                    ++number_length;
                }
            }
            prv = cur;
        }
    
        /* set rests as 010101 */
        for (carry = 0; cur > number_str - 1; --cur){
            *cur = carry + '0';
            carry ^= 1u;
        }
        str_reverse(number_str, number_length);
        sscanf(number_str,"%u",&result);
        return result;
    }
    

    总结:

    1. find 函数定义不是很好,char * find(char *,int) 会更好。
    2. 不要直接处理字符传,先处理成数组,再进行处理,等到处理完成时再处理字符串。
    3. 效率和可读性优先 可读,效率本来就不是个问题。 
    4. 先感谢 garbageMan对Alexia(minmin)网友代码的评论及对“求比指定数大且最小的‘不重复数’问题”代码的改进 中的指点。由于 finded -1  和 number_str -1 属于 ansi c 中 关于 指针加法运算的结果 不指向 数组内或数组最后一个元素的下一个元素 的行为 没有定义 。 把相应源码做以下修改即可。
        for (cur = number_str + number_length, finded = number_str
                ; cur > finded;){
            cur --
    
        for (carry = 0; cur > number_str ;){
            cur--
    

       

    思路

    1.  加一
    2.  从高位找重复,如果存在记住重复出现的位置,该位置加一,再从进位影响的前一位开始重复这个操作。
    3. 在第一次找重复位置之后的数依次替换为 01。输出结果。

    最后,这个程序我简单测试过,可能还会存在错误。

  • 相关阅读:
    jquery ajax你会了吗?
    JS写Cookie
    [活动通知]Nanjing GDG 2013年4月活动
    UITableView刷新数据reLoadData
    FMS4.0 客户端访问服务器脚本文件 main.asc
    关于IOS6屏幕旋转
    Windows平台下Makefile学习笔记(二)
    编译MapWindowGis源码出现的重定义的问题及解决办法
    你的 mixin 兼容 ECMAScript 5 吗?
    有点坑爹的gdal库
  • 原文地址:https://www.cnblogs.com/playerc/p/3355595.html
Copyright © 2020-2023  润新知