Algorithm 高效地计算Pi十进制展开中要重复的前20位子字符串 问题
Pi=3.1415926535897932384626433。。。所以要重复的第一个2位数子串是26 找到要重复的前20位子字符串的有效方法是什么 约束条件Algorithm 高效地计算Pi十进制展开中要重复的前20位子字符串 问题,algorithm,Algorithm,Pi=3.1415926535897932384626433。。。所以要重复的第一个2位数子串是26 找到要重复的前20位子字符串的有效方法是什么 约束条件 我有大约500 GB的Pi数字(每个数字1字节),还有大约500 GB的可用磁盘空间 我有大约5千兆字节的可用内存 我感兴趣的是一种有效的算法,它可以处理任意序列,而不是Pi本身的具体答案。换句话说,我对“print 123…456”格式的解决方案不感兴趣,即使它打印的数字是正确的 我试过的 我将每个子字符串放入一个哈希表并报告第一次冲
- 我有大约500 GB的Pi数字(每个数字1字节),还有大约500 GB的可用磁盘空间
- 我有大约5千兆字节的可用内存
- 我感兴趣的是一种有效的算法,它可以处理任意序列,而不是Pi本身的具体答案。换句话说,我对“print 123…456”格式的解决方案不感兴趣,即使它打印的数字是正确的
- 为特定范围内的所有子字符串生成哈希,然后继续搜索剩余的数字。这需要为每个范围重新扫描Pi的整个序列,因此变成N^2阶
- Bucket将一组20位的子字符串排序为多个文件,然后使用哈希表分别查找每个文件中的第一个重复项。不幸的是,使用此方法时,磁盘空间不足,因此需要20次数据传递。(如果我以1000位数字开始,那么我将以1000个20位的子字符串结束。)
- 每字节存储2位Pi以释放更多内存
- 将基于磁盘的备份存储添加到我的哈希表中。我担心这会表现得非常糟糕,因为没有明显的参考位置
谢谢大家 也许类似的方法会奏效:
qsort(array, number_of_digits, sizeof(array[0]), strcmp);
当qsort结束时,指针数组中类似的子字符串将相邻。因此,对于每个指针,可以将该字符串与下一个指针指向的字符串进行有限的字符串比较。同样,在C中:
for (int i = 1; i < number_of_digits; ++i) {
if (strncmp(array[i - 1], array[i], 20) == 0) {
// found two substrings that match for at least 20 digits
// the pointers point to the last digits in the common substrings
}
}
for(int i=1;i
排序(通常)是O(n log_2n),之后的搜索是O(n)
这种方法的灵感来源于。您的数据集相当大,因此需要某种“分而治之”的方法。我建议作为第一步,将问题细分为若干部分(例如100)。首先查看文件是否有任何重复的以00开头的20位序列,然后查看是否有任何以01开头的序列,等等,直到99为止。通过将所有以正确数字开头的20位序列写入文件,开始这些“主要过程”。如果前两位是常量,则只需写出最后18位;由于一个18位的十进制数字将适合8字节的“long”,因此输出文件可能包含大约5000000000个数字,占用40GB的磁盘空间。请注意,一次生成多个输出文件可能是值得的,这样可以避免必须读取源文件的每个字节100次,但如果只读取一个文件并写入一个文件,磁盘性能可能会更好 生成特定“主通道”的数据文件后,必须确定其中是否存在任何重复项。细分