Pi=3.14159 26 535 8979323846 26 433...所以要重复的第一个2位数子字符串是26。
找到要重复的第一个20位数子串的有效方法是什么?
>
我有大约500千兆字节的Pi数字(每个数字1字节),大约500千兆字节的磁盘空间可用。
我有大约5GB的内存空闲。
这很好,直到我用完了内存。
为了扩展到更长的序列,我考虑过:
>
为从某个范围开始的所有子字符串生成哈希,然后继续搜索剩余的数字。这需要重新扫描每个范围的整个Pi序列,因此成为顺序n^2
Bucket将一组20位数的子字符串排序到多个文件,然后使用哈希表分别查找每个文件中的第一个重复。不幸的是,使用这种方法,我将耗尽磁盘空间,因此需要对数据进行20次传递。(如果我从1000个数字开始,那么我将得到1000个20个数字的子串。)
每字节存储2位圆周率以释放更多内存。
>
我尝试了Adrian McCarthy的qsort方法,但这似乎比散列查找重复项慢一点
我查看了Btilly的MapReduce的并行算法建议,但它在我的单机上被严重绑定了IO,所以不适合我(用我的单机磁盘驱动器)
我实现了Supercat的方法,在昨晚拆分文件并在前180亿位数中搜索19位数的子字符串。
非常感谢大家!
这是一个有趣的问题。
首先,让我们做一些信封后面的号码。任何20位数字的特定序列都将在1020中匹配一次。如果我们到第n个数字,我们大约有n2/2对20个数字序列。因此,为了有很好的几率找到匹配,我们可能需要n略高于1010。假设我们每条记录占用40字节,我们将需要大约400 GB的数据。(我们实际上需要比这更多的数据,所以我们应该为超过太字节的数据做好准备。)
这给了我们一个所需数据量的概念。几百亿位数。数百GB的数据。
现在问题来了。如果我们使用任何需要随机访问的数据结构,随机访问时间由磁盘速度设置。假设您的磁盘运行速度为6000转。每秒100次。平均而言,您需要的数据位于磁盘的一半。所以你平均每秒得到200次随机访问。(这可能因硬件而异。)访问它100亿次将需要5000万秒,这是一年多的时间。如果你读,然后写,最终需要200亿个数据点--你已经超过了你的硬盘的预期寿命。
另一种方法是以不随机访问的方式处理一批数据。经典的是做好外部排序,这样的合并排序。假设我们有1TB的数据,在排序过程中,我们读30次,写30次。(两个估计都比需要的要高,但我在这里画了一个最坏的情况。)假设我们的硬盘具有100 Mb/s的持续吞吐量。然后每一次通过需要10,000秒,为600,000秒,略低于一周。这是非常可行的!(实际上应该比这更快。)
以下是算法:
现在这是伟大的,但如果我们不想花一个星期呢?如果我们想向它扔多台机器呢?事实证明,这出奇地容易。有众所周知的分布式排序算法。如果我们将初始文件分成块,我们可以并行执行步骤1和步骤4。如果在第4步之后我们没有找到匹配项,那么我们可以从一开始就用更大的输入块重复。
事实上,这种模式很常见。真正不同的是将初始数据转换为要排序的数据,然后查看匹配的组。这是http://en.wikipedia.org/wiki/mapreduce算法。这对这个问题很有效。
一个显而易见的解决方案是: 这需要线性时间。我们能再快点吗? 这比线性时间快吗 还有哪些方法(效率是首要考虑的)<我见过这个,只是我只需要找到第一个数字。(还有,我不明白答案)。
是否有一种内置的方法来计算Python3十进制对象正确舍入的第n个根?
本文向大家介绍基础的十进制按位运算总结与在Python中的计算示例,包括了基础的十进制按位运算总结与在Python中的计算示例的使用技巧和注意事项,需要的朋友参考一下 与运算 & 举例: 3&5 解法:3的二进制补码是 11, 5的是101, 3&5也就是011&101,先看百位(其实不是百位,这样做只是便于理解) 一个0一个1,根据(1&1=1,1
我参考了这一点,并对值进行了四舍五入,然后我也得到了上述错误。请查找下面提到的代码。提前感谢:
其想法是通过HTTP实现RFC3091(“Pi数字生成协议”)。我一直很难找到一种流式(和/或插口)算法,它实际上可以产生正确的十进制扩展。 是的,有很多实现,但大多数都需要预先分配缓冲区,缓冲区的大小等于请求的位数。显然,这并不能产生无穷无尽的数字流。 用C/Py/PHP/etc实现是理想的。 谢谢
在我的代码中 当我运行程序时,它抛出一个数字格式异常 我做错了什么?这似乎相对简单,但不起作用。