C++ 中的重复数字

2025 年 5 月 22 日 | 阅读 7 分钟

引言

重复数字是一种特殊的数字类型,其中所有数字都相同。例如,像 111、22 和 7777 这样的数字是重复数字,因为它们由相同的数字重复多次构成。“重复数字”这个词来源于“重复”和“数字”的组合。

重复数字很简单,但处理起来很有趣,因为它们遵循独特的模式。即使是像 5 或 9 这样的个位数也被认为是重复数字,因为它们可以看作是同一个数字重复一次。

在编程中,尤其是在 C++ 中,检查一个数字是否为重复数字涉及到提取它的数字并验证每个数字是否与第一个数字匹配。这个概念在数学谜题、数论和编程挑战中很有用。

方法 1:使用简单方法

程序

让我们举一个例子来说明 C++ 中的重复数字。

输出

Enter a number: 4444 
4444 is a repdigit number.   

说明

  1. 输入数字
    • 程序开始时要求用户输入一个数字。
    • 输入数字存储在一个变量中,以便稍后处理。
  2. 检查负数
    • 由于重复数字通常是非负数(正数或零),因此程序包含一个检查来处理负输入。
    • 如果数字是负数,程序会打印一条消息,说明负数不是重复数字,并停止进一步处理。
  3. 提取数字
    • 为了检查数字中的所有数字是否相同,程序会逐个提取数字。
    • 该过程涉及重复地除以该数字
    • 最后一个数字是使用余数运算符 (%) 获得的。
    • 剩余的数字是通过将其除以 10 获得的(这会移除最后一个数字)。
  4. 存储第一个数字
    • 程序首先将最后一个数字(使用 % 获得)存储为参考。这被称为“第一个数字”,因为它将与所有其他数字进行比较。
  5. 比较每个数字
    • 程序进入一个循环,直到所有数字都被提取和检查为止
    • 它使用余数运算符 (%) 提取下一个数字。
    • 它将提取的数字与第一个数字(之前存储的)进行比较。
    • 如果任何数字与第一个数字不同,程序就会得出结论,该数字不是重复数字。
  6. 所有数字都相同
    • 如果循环完成并且所有数字都与第一个数字匹配,程序就会确定该数字是重复数字。
  7. 显示结果
    • 根据循环中执行的检查
    • 如果所有数字都相同,程序将打印一条消息,确认该数字是重复数字。
    • 如果任何数字不同,它会打印一条消息,说明该数字不是重复数字。
  8. 循环如何工作
    • 想象一个数字,比如 4444
    • 最后一个数字(4)被提取并存储为第一个数字。
    • 循环继续移除最后一个数字,留下 444。
    • 该过程重复进行,直到数字变为 0,并且提取的每个数字都与第一个数字进行检查。
    • 如果所有数字都是 4,程序会确认它是一个重复数字。

现在考虑 123

  • 最后一个数字(3)首先被提取。
  • 当提取下一个数字(2)时,它与 3 不匹配,因此程序停止检查并得出结论,它不是重复数字。

复杂度分析

时间复杂度

该程序的时间复杂度为 O(d),其中 d 是输入数字中的位数。

为什么是 O(d)?

  • 程序逐个提取和处理数字的每一位。
  • 这是在一个循环中完成的,每个迭代都会移除最后一个数字(使用 / 10)并将其与第一个数字进行比较。

迭代次数

  • 对于一个有 d 位数的数字,循环恰好运行 d 次,因为每次迭代都会处理一位数字。

例如

  • 对于 4444(4 位),循环运行 4 次。
  • 对于 12345(5 位),循环运行 5 次。

结论

  • 循环的运行时间与数字中的位数成正比,因此时间复杂度为 O(d)。

空间复杂度

该程序的空间复杂度为 O(1),这意味着它使用的内存量是恒定的,与输入大小无关。

为什么是 O(1)?

  • 程序使用了固定数量的变量
  • 一个用于存储输入数字。
  • 一个用于存储最后一个数字。
  • 一个用于比较数字。
  • 没有使用额外 数据结构(如 数组向量)。

内存使用

  • 程序一次只处理一位数字,因此它不会同时存储所有数字。

方法 2:使用字符串检查重复数字

确定一个数字是否为重复数字的另一种方法是将数字转换为字符串,并检查字符串中的所有字符(数字)是否相同。这种方法简化了比较过程,因为字符串允许直接将每个数字作为字符访问。

此方法的优点

  • 简单性:通过使用字符串,代码变得更容易阅读和理解,因为数字提取和比较都很直接。
  • 直接比较:整个数字被视为字符序列,无需进行模 (%) 或除 (/) 等算术运算。

程序

输出

Enter a number: 1234
1234 is not a repdigit number.   

说明

  1. 处理负数
    • 程序的第一步是检查输入数字是否为负数。
    • 由于重复数字通常是非负数,因此任何负输入都会立即被识别为不是重复数字。
    • 如果数字是负数,程序会停止进一步处理。
  2. 将数字转换为字符串
    • 数字被转换为字符串。
    • 以字符串形式,数字的每个数字都变成一个单独的字符。
    • 例如,数字 4444 变成“4444”(四个字符的字符串)。
    • 数字 123 变成“123”。
  3. 识别第一个数字
    • 字符串的第一个字符单独存储。
    • 此字符将用作参考,用于比较字符串中的所有其他字符。
  4. 比较所有字符
    • 程序遍历字符串中的每个字符
    • 对于每个字符,它会检查它是否与第一个字符相同。
    • 如果任何字符与第一个字符不同,程序就会得出结论,该数字不是重复数字。
    • 如果所有字符都相同,则确认该数字是重复数字。
  5. 输出结果
    • 检查完所有字符后
    • 如果所有字符都与第一个字符匹配,程序将打印该数字是重复数字。
    • 如果任何字符不同,程序将打印该数字不是重复数字。

示例演练

让我们看几个例子来理解这个过程

输入:4444

数字被转换为字符串“4444”。

第一个字符('4')被存储为参考。

字符串中的每个字符都与 '4' 进行比较

  • '4' == '4':匹配。
  • '4' == '4':匹配。
  • '4' == '4':匹配。
  • '4' == '4':匹配。

由于所有字符都匹配,程序确定 4444 是一个重复数字。

输入:123

数字被转换为字符串“123”。

第一个字符('1')被存储为参考。

字符串中的每个字符都与 '1' 进行比较

  • '1' == '1':匹配。
  • '2' != '1':不匹配。

由于存在不匹配,程序得出结论,123 不是重复数字。

输入:7

数字被转换为字符串“7”。

第一个字符('7')被存储为参考。

由于字符串只有一个字符,因此自动匹配。

程序确定 7 是一个重复数字。

复杂度分析

时间复杂度

  • O(d),其中 d 是输入数字中的位数。
  • 程序将数字转换为字符串,这需要 O(d) 时间。
  • 然后,它检查字符串中的每个字符,这也需要 O(d) 时间。
  • 总的来说,时间复杂度与数字的位数成正比。

空间复杂度

  • O(d),其中 d 是输入数字中的位数。
  • 空间用于存储数字的字符串表示。由于字符串包含 d 个字符(每个数字一个),因此所需的空间与数字的位数成正比。

性质

  1. 所有数字都相同
    • 重复数字被定义为每个数字都相同的数字。例如,111、2222、55555 都是重复数字的例子。
    • 这些数字的核心特征是每个数字都相同,这使它们区别于其他数字。
    • 示例: 444 是一个重复数字,因为它的所有数字都相同(4),而 123 不是,因为它的数字不同。
  2. 与基数相关
    重复数字不限于十进制。它们可以存在于任何数字系统中(基数-N)。
    例如
    • 在基数 2(二进制)中,111 是一个重复数字,但它的十进制等值为 7。
    • 在基数 3 中,222 是一个重复数字,但它的十进制等值为 26。
    因此,重复数字的概念是与基数无关的,这意味着一个数字在一个基数中可能是重复数字,但在另一个基数中具有完全不同的值。

下一个主题Repunit-numbers-in-cpp