C++ 中的圣埃克絮佩里数

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

引言

当涉及数学家或程序员时,他们常常发现数字具有令人愉悦的特性。其中一类数字,可以被称为圣埃克苏佩里数,这是向《小王子》及许多其他儿童读物的作者安托万·德·圣埃克苏佩里的奇思妙想和深刻想象力致敬。这些数字有一个有趣的定义,使其成为编程探索的良好候选者。

在本文中,我们将探讨圣埃克苏佩里数这类数字的定义,陈述一般性问题,并用 C++ 编写代码,以便为编程目的提取这类数字。

问题陈述

圣埃克苏佩里数是一个满足以下属性的正整数:

该数各位数字之和的立方等于该数本身。

例如

对于 n=81

各位数字之和 = 8+1=9,所以对和求平方得到:81

平方 = 81。

因此,81 是一个圣埃克苏佩里数。

我们的任务是编写一个 C++ 程序,它将在某个 n 的范围内找到所有的圣埃克苏佩里数。

算法与方法

为了解决这个问题,算法包括:

  • 对于给定范围 [start, end] 内的每个数字,计算其各位数字之和。如果数字之和的平方等于原始数字,则将该数字打印为圣埃克苏佩里数。采用线性范围可以确保高效处理。
  • 为了遍历一个数字中的各位数,使用模 10 运算来保留最后一位数字,同时将数字除以 10。

问题陈述

圣埃克苏佩里数是满足以下条件的正整数:

  • 当一个数的各位数字相加,然后将所得的和平方,结果等于原始数字。

例如

  • 对于 n=81
    • 各位数字之和 = 8+1=9,
    • 对和求平方 = 9^2 = 81,
    • 因此,81 是一个圣埃克苏佩里数。

示例 1

让我们举一个例子来说明 C++ 中的圣埃克苏佩里数。

输出

Enter the start of the range: 1
Enter the end of the range: 100
Saint-Exupéry Numbers in the range [1, 100] are: 1 81   

代码解释

  1. sumOfDigits 函数: 该函数通过迭代计算一个数有多少位数字。
  2. findSaintExuperyNumbers 函数: 在范围内只取两个数,并且只检查两个条件。这两个特定条件用于获取圣埃克苏佩里数的集合。
  3. 函数
    • 它首先从用户处获取输入以及设定的范围。
    • 它列出被调用的函数以从集合中获取所需的数字。
    • 它产生所做计算的结果。

示例 2

让我们再举一个例子来说明 C++ 中的圣埃克苏佩里数。

输出

Enter the start of the range: 1
Enter the end of the range: 100000
Enter the number of threads to use: 4
Saint-Exupéry Numbers in the range [1, 100000] are:
1 81 6724 ...

Execution Time: 15 ms   

此代码的特点

  1. 多线程: 我们的代码可以以多线程方式实现,这有助于在速度方面实现负载均衡,尤其是在处理较大范围(例如 1 到 100 万)时。
  2. 动态范围分割: 所发明的方法将正常范围分割成大小近似相等的线程,以期在未来平衡线程。
  3. 线程安全的结果收集: 使用 std::mutex,可以安全地将不同线程收集的输出整合在一起,而不会重复和过度嵌入其余输出。
  4. 计时执行: 为了演示,还测量了单线程输出和执行时间,以显示使用多线程的效率。

示例 3

让我们再举一个例子来说明 C++ 中的圣埃克苏佩里数。

输出

Enter the start of the range: 1
Enter the end of the range: 200
Saint-Exupéry Numbers in the range [1, 200] are:
1 81   

说明

  1. 数字和预计算 (precomputeDigitSums)
    • 需要注意的是,已经实现了对从 1 到最大标准值的所有数字的各位数字之和的预计算。
    • 利用恒等式: n 的各位数字之和 = (n / 10) 的各位数字之和 + (n % 10)
    • 这样,数字和就不必多次重新计算,从而提高了处理速度。
  2. 查找圣埃克苏佩里数 (findSaintExuperyNumbers)
    • 它扫描指定边界内的数字。
    • 对于每个数字,它获取缓存的数字和,并确定其平方是否等于该数字。
  3. 主函数
    • 它从用户处接收一个区间作为输入。
    • 通过检查区间是否为非负且下限小于或等于上限来验证其有效性。
    • 它调用方法来计算圣埃克苏佩里数并呈现它们。

结论

总之,圣埃克苏佩里数是一个迷人而有趣的概念,它展示了数学的优雅和将其转化为代码的艺术。在 C++ 中寻找它们的整个想法很简单,但对于获得算法思维过程和数学逻辑具有重要意义。