首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

字符串操作解法:求下一個不重複數 (相鄰位不同) - 字符串進位與模式填充

     編輯:關於C語言

同樣是求「大於 N 的最小不重複數」,本文採用**字符串模擬進位**思路:將數字轉為字符串,從低位向高位掃描相鄰重複,發現則進位並將低位填入 `0101...` 最小模式。代碼直觀、易理解、易移植至大整數庫。

演算法流程

  1. `N++` (因要求嚴格大於)。
  2. `sprintf` 轉字符串 `s`,反轉 (低位在前) 便於索引。
  3. 掃描 `s`,記錄前一字符 `prv`。若 `cur == prv` (相鄰重複):
  4. 從當前位開始 **進位傳播**:`*cur += carry`,處理 `'9'+1 → '0'` 進位。
  5. 進位結束後,將**所有較低位** (含當前位) 重置為交替模式 `0,1,0,1...` (最小不重複模式)。
  6. 反轉字符串,`sscanf` 回整數返回。

關鍵代碼片段

void str_reverse(unsigned char *s, unsigned len) {
    for (unsigned char *l=s, *r=s+len-1; l= s; cur--) {
        if (prv && *cur == *prv) {
            // 進位
            int carry = 1;
            for (unsigned char *p = cur; carry && p < s + len; p++) {
                *p += carry;
                carry = (*p - '0') / 10;
                *p = (*p - '0') % 10 + '0';
            }
            if (carry) { s[len++] = '0' + carry; }
            // 低位填 0101...
            int alt = 0;
            for (unsigned char *p = cur; p >= s; p--) {
                *p = '0' + alt;
                alt ^= 1;
            }
        }
        prv = cur;
    }
    str_reverse(s, len);
    unsigned res; sscanf((char*)s, "%u", &res);
    return res;
}

測試驗證

輸入: 1101 → 輸出: 1201
輸入: 1999 → 輸出: 2010
輸入: 989 → 輸出: 989 (本身不重複,但要求大於,故 1010)

優缺點對比

維度字符串法 (本文)數字陣列法 (前文)
直觀度高 (直接操作可見字符)中 (抽象數字陣列)
大整數擴展極易 (改用字符串大整數庫)需重寫進位邏輯
效能略低 (字符串轉換開銷)高 (純整數運算)
代碼長度較短中等

總結

字符串法以「進位 + 低位填最小模式」為核心,邏輯清晰,適合快速原型、教學演示、大整數場景。若追求極致效能 (如競賽)、固定位寬整數,前文的數字陣列法更優。兩者同屬「貪心構造」範疇,掌握任一即可觸類旁通。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved