給定任意一個正整數,求比這個數大且最小的“不重復數”,“不重復數”的含義是相鄰兩位不相同,例如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\n", find(num)); return 0; } void str_reverse(unsigned char *str,unsigned length) { unsigned char *prv = NULL; unsigned char *cur = NULL; unsigned char swap = '\0'; 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] = {'\0'}; 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; }
總結:
- find 函數定義不是很好,char * find(char *,int) 會更好。
- 不要直接處理字符傳,先處理成數組,再進行處理,等到處理完成時再處理字符串。
- 效率和可讀性優先 可讀,效率本來就不是個問題。
- 先感謝 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--
思路
- 加一
- 從高位找重復,如果存在記住重復出現的位置,該位置加一,再從進位影響的前一位開始重復這個操作。
- 在第一次找重復位置之后的數依次替換為 01。輸出結果。
最后,這個程序我簡單測試過,可能還會存在錯誤。