我正在做一个项目,我需要一个非常快速的算法来检查提供的数字是否是泛数字的。尽管逻辑看起来很合理,但我对下面描述的方法的性能并不特别满意。
我可以分别在大约 520 毫秒、600 毫秒和 1600 毫秒内检查多达 100 万个 9 位数字。我正在开发一个低延迟的应用程序,在生产中我将拥有一个大约 9 或 95 亿个 7 到 9 位数字的数据集,我需要检查这些数字。
我现在有三个候选人(嗯,真的有两个)使用以下逻辑:
方法 1:我将一个 inputN
拆分为一个包含其组成数字的字节数组,使用函数对其进行排序,并使用循环检查元素与计数器的一致性Array.Sort
来遍历数组:for
byte[] Digits = SplitDigits(N);
int len = NumberLength(N);
Array.Sort(Digits);
for (int i = 0; i <= len - 1; i++)
{
if (i + 1 != Digits[i])
return false;
}
方法 2:这种方法基于有点可疑的逻辑,但我将输入拆分N
为组成数字的字节数组,然后进行以下测试:
if (N * (N + 1) * 0.5 == DigitSum(N) && Factorial(len) == DigitProduct(N))
return true;
方法 3:我不喜欢这种方法,因此不是真正的候选者,但我将 int 转换为字符串,然后用于String.Contains
确定所需的字符串是否为 pandigital。
第二种和第三种方法具有相当稳定的运行时间,尽管第一种方法反弹很多 - 它有时可以高达 620 毫秒。
所以理想情况下,我真的很想将百万 9 位标记的运行时间减少到 10 毫秒以下。有什么想法吗?
我在 2GHz 的 Pentium 6100 笔记本电脑上运行它。
PS - 第二种方法的数学逻辑合理吗?