C++ 中的泛盘乘积

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

全数字数 (Pandigital numbers) 是数学家们感兴趣的主题,因为它们的构造一方面受到限制,另一方面又具有简化的结构。所谓全数字数,是指在给定的数字范围内恰好使用一次所有数字的数。例如,一个9位数的全数字数使用数字1-9。另一方面,10位全数字数包含0到9的所有数字。这是一个引人入胜的特性,可以为孩子们提供良好的数字基础,并允许探索“全数字乘积 (Pandigital product)”这一数学术语是如何得出的。全数字乘积涉及三个元素的组合:被乘数、乘数和它们的积。然而,这种组合的特殊之处在于,这三个元素的连接可以形成一个全数字数。

为此,让我们以三个很多人都知道的计算为例:39 × 186 = 7254。当我们连接被乘数(39)、乘数(186)和积时,就得到了一个9位数的全数字数,即391867254。

1到9之间的每个数字都恰好出现一次,而且这些数字都没有重复使用。这些例子展示了什么是全数字乘积,以及它们的数学对称性是如何固有的。尝试找出在明确定义的数字范围内存在的所有此类组合,不仅仅是计算的兴趣,而确实是一项有价值的智力推理练习。

这就是为什么阅读全数字数很有趣,因为它们在随机性中带有一点秩序。首先,数字必须恰好出现一次,并且以某种特定的顺序出现。另一方面,可以产生有效乘积的数字似乎呈现出非常随机的模式,它们的生成既有趣又令人兴奋。这种平衡促使数学家和程序员努力寻找找出全数字乘积的最佳方法。

全数字数和全数字乘积在数学上很有趣,但除此之外,它们还有实际的应用。它们体现的独特性和完整性特征与加密系统、数据验证和组合优化问题相关。此外,研究全数字乘积可以用来理解分拆和排列的数量。正如经典数学家所认为的,这些技能在计算数学中是很有价值的。

问题陈述

全数字乘积问题 (Pandigital Product problem) 是一个引人入胜的计算挑战,它引导我们找出被乘数、乘数及其积的所有组合,这些组合代表了全数字属性。这个问题可以简洁地表述如下:给定一个指定的数字范围,例如1到9或0到9,我们想要找到所有被乘数、乘数和积连接起来形成一个全数字数的乘积。

这个任务的本质是尝试找到一组数字,当集体组合时,能够恰好使用提供范围内的所有数字一次,不重复也不遗漏。例如,假设数字范围是1到9。那么,任何有效的解决方案都应确保这三个数字的连接包含所有这些数字一次。让我们再看看39 × 186 = 7254。在这种情况下,391867254是一个有效all数字乘积,它包含了1到9的所有数字,没有任何重复。

事实上,这个问题隐含了使其有趣和具有挑战性的约束。例如,假设我们不想要123 × 456 = 789,因为它连接的数字是123456789,并且有一个数字零不在1-9的范围内。第二个是连接字符串的长度应等于数字范围。对于9位全数字乘积,连接结果必须恰好有九位数字。

解决这个问题的关键在于,我们需要探索被乘数和乘数的所有可能组合,并确保所得的乘积满足全数字属性。这通常需要生成数字范围的排列,并尝试将它们分成三部分:被乘数、乘数和积。这些分割的顺序会产生很大的不同。它决定了生成的数字是否构成有效的算术方程。

还需要考虑数字范围包含0时的情况。一个很好的例子是数字范围为0到9的整数;因为零永远不能作为数字的开头数字,所以问题变得更加复杂。这只是在已经很难生成的组合并进行验证的问题之上增加了一个额外的层次。

这样的挑战使得全数字乘积问题成为一个非常有价值的解决问题。它结合了组合学、算术和逻辑的元素,因此是数学家和程序员的绝佳练习。这个问题也很适合优化,因为可以提前排除有效的组合,并通过利用乘法的性质来避免冗余计算。

算法设计

全数字乘积 (Pandigital Product) 问题不允许像解决数独或数独那样应用相同的非结构化方法,所以我们必须找到解决它的最佳方法。这个问题的关键在于考虑数字的排列,并表达被乘数、乘数或积的数字值以获得全数字意义。

然而,它有巨大的状态数,使得解决方案成为一个计算问题,但它有一个系统性的方法来避免无休止地检查所有可能的排列和逻辑。

  • 在设计所需算法之前的第一步是生成提供的数字范围的可能排列列表。例如,如果范围是1到9,则有9!,即362,880个排列。每个排列代表数字的一种潜在排序,可以将其分成三部分:被乘数、乘数和积。这些部分必须选择得当,使得它们的组合创建一个真正的全数字数,并且可以使用等号来表示乘法过程,其中被乘数 × 乘数 = 积。
  • 然而,为了进一步限制搜索空间,有必要为被乘数、乘数和积的大小设定合理的界限。这是因为三个4位数的连接就达到了9位全数字数的限制,更不用说其中两个数的乘积了。此外,出于同样的原因,被乘数和乘数都不能超过四位数字,因为它们与乘积的组合超出了9位数的限制。通过这些观察,我们可以对车辆的三个部分施加约束,并避免创建不存在的模型。
  • 接下来是将生成的排列分成三个组件:被乘数、乘数和积。但对于每一次分割,都会进行测试,以了解给定的被乘数和乘数是否能提供积。有各种方法可以执行此验证步骤,但我们只允许数值信息组合通过非常简单的数学运算,如加法、减法等。如果获得有效的组合,它将成为解决方案列表的一部分。
  • 最终工作中存在出现重复项的问题。因此,算法需要考虑乘法的交换律问题。例如,39 x 186 = 7254 或 186 x 39 = 7254 代表一个特定的全数字乘积。因此,这两种数字组合中只有一种应该被打印出来。这可以通过实现一个排序约束来实现。例如,被乘数小于乘数。
  • 为了进一步提高算法的性能,可以进行单独的修改,例如剪枝,它允许提前排除不可行的选项。例如,如果乘数和积的长度之积大于数字范围,字符串,则没有理由继续进行算术检查。同样,如果一个数字,乘以或被乘以,在重复或缺失方面具有相同或不同的数字,则可以丢弃这种组合。这些剪枝步骤减少了必须搜索的排列数量,极大地减小了搜索空间。

优化技术

解决这个问题的第一个方法是生成数字范围的每个排列,然后使用全数字乘积中使用的Guardiande条件测试每个排列。这种类型的方法只适用于相对较小的数字范围,因为随着数字范围的增加,排列的数量会增加几千倍。可以应用许多优化启发式方法来提高算法的性能,并实施搜索空间排除策略,这些策略可以排除搜索空间的某些部分,从而避免额外的计算。

最受欢迎的优化是利用乘法的性质来为被乘数、乘数和结果的长度添加额外的约束。例如,如果一个数字的乘积是4位数字,那么被乘数和乘数加起来需要不超过五位数字。这个见解使我们能够专注于满足这些约束的特定排列子空间,从而排除大多数不想要的组合。

然而,另一种强大的优化技术是使用集合或布尔数组来跟踪已使用的数字。这种数据结构可以快速确定单个字符串是否是全数字的,而无需迭代数字的排列。因此,跟踪哪些数字已经被使用是很有用的。它允许由于所谓的“全数字属性”的失败而立即排除许多候选组合。

示例

让我们以一个例子来说明 C++ 中的全数字乘积 (Pandigital Product)

输出

12 x 483 = 5796 is a pandigital product.
18 x 297 = 5346 is a pandigital product.
27 x 198 = 5346 is a pandigital product.
28 x 157 = 4396 is a pandigital product.
39 x 186 = 7254 is a pandigital product.
42 x 138 = 5796 is a pandigital product.
48 x 159 = 7632 is a pandigital product.
Sum of all unique pandigital products: 45228   

代码解释

全数字检查函数

  • isPandigitalProduct 函数将所有数字(初始数、乘数和结果)组合成一个单一的字符串。
  • 之后,它发现连接后的字符串在长度上等于9个字符,并且包含所有数字1 2 3 4 5 6 7 8 9。

主逻辑

  • 程序提供了一个针对被乘数和乘数的循环,增加它们的值,以确保它们的乘积是合理的。
  • 对于每个零基计数器值,它将乘数、乘数和积连接起来,形成一个有效的全数字数,该计数器值会导致一个有效的三个数字被乘数、两位数字乘数以及两个数字乘积的组合。
  • 唯一的乘积存储在一个集合中,以确保我们的集合中没有重复的乘积。

优化

  • 外层和内层循环控制确保被乘数始终小于乘数,以节省计算操作。
  • 第四个元素,即乘数的上限,主要受到调控,以使乘积结果保持在四位数字以下,以符合被乘数的位数。

结论

总之,全数字乘积 (Pandigital Product) 问题可以被认为是一个有趣的组合和算术任务与编程相结合。通过研究被乘数、乘数和积的不同值,这个问题强调了其背后优雅的数学对称性和思维,并在计算阶段显示出与需要全数字属性等附加条件相关的潜在困难。然而,当涉及到特定的排列时,我们必须手动生成它们,验证候选数和素数之间的算术关系,并应用剪枝技术来找到所有有效的全数字乘积。

这个问题是优雅的,因为它的解决方案纯粹依赖于逻辑,而没有其他数学知识,尽管它在展示了理论和计算之后才呈现。它规定了如何最好地搜索搜索空间的规则,并重申了使用约束的有效性,以及禁止计算所有先前已计算过的活动。此外,使用集合来确定和跟踪新产品可确保解决方案是充分且正确的。

在寻找该问题的解决方案时,我们将发现数字之间有趣的模式和依赖关系,这些数字已经是必需的全数字,这使得寻找新数学模式的过程特别有吸引力。从更广阔的视角来看,全数字乘积问题是一项有益的努力,为数学家和程序员提供了启发式和教学效益。