![]() |
1
13
在这个例子中,该算法没有以非常好和清晰的方式实现。一些更好地解释它的伪代码是:
如您所见,其思想是读取文件中的每一行,并计算该行应该是所选行的概率。读第一行后概率为100%,读第二行后概率为50%,以此类推。 通过将数组的大小保留为n而不是单个变量,可以将其扩展为选择n个项,并计算一行替换数组中当前某一行的概率:
编辑:
我通过运行100000次方法进行了测试,从20行中选出5行,并计算了这些行的发生次数。结果是:
正如你所看到的,这种分布是你想要的最好的。:)
(我移动了
注:
编辑2:
|
![]() |
2
1
现在,我的Perl不再是以前的样子,而是相信您引用的隐式声明(这样选择的行号分布是一致的),它似乎可以工作:
就像最初的算法一样,这是一次通过和恒定内存。 编辑 我刚意识到你需要N,而不是2。如果事先知道n,可以重复或ed表达式n次。 |
![]() |
3
1
我第一次看到Perl代码…这是难以置信的不可读…但这不重要。你为什么不把这条神秘的线重复N次呢? 如果要写这个,我只需要在文件中寻找一个随机位置,读到行的末尾(下一行),然后读到下一行。如果您刚刚看到最后一行,请添加一些错误处理,重复这n次,然后就完成了。我猜
是Perl完成这一步的方法。您还可以从初始位置向后读取到priviouse新行或文件开头,然后再向前读取一行。但这并不重要。 更新 我不得不承认,在文件中寻找某个位置不会产生完美的均匀分布,因为行长度不同。当然,如果这种波动很重要,取决于使用场景。 如果您需要一个完美的统一分布,您需要阅读整个文件至少一次,以获得行数。在这种情况下,Guffa给出的算法可能是最聪明的解决方案,因为它需要读取文件一次。 |
![]() |
5
0
又快又脏的重击
|
![]() |
6
0
在文件中选择一个随机点,向后查找以前的EOL,向前搜索当前的EOL,然后返回该行。
其中有很多一次性错误和垃圾,糟糕的内存管理和其他恐怖。如果这真的可以编译,你就得到一个镍币。(请寄上自定地址的有邮票的信封和5美元的手续费,以便收到免费的镍币。) 但你应该明白这个想法。 从统计上看,长线比短线更有可能被选中。但不管文件大小如何,它的运行时间实际上是恒定的。如果你有很多长度差不多的词,统计学家就不会高兴了(反正他们也不会高兴),但在实践中,它就足够接近了。 |
![]() |
7
-1
我会说:
您只需使用一个小数组,然后读取整个文件一次+2行。 |
![]() |
8
-2
你可以做一个二次通过的算法。首先得到每条新行的位置,将这些位置推到一个向量中。然后选取向量中的随机项,称之为i。 从位置v[i]到v[i+1]的文件中读取您的行。 在第一次传递过程中,您使用一个小的缓冲区读取文件,以免同时将其全部读取到RAM中。 |
![]() |
feasega · 聚合物模拟-2个节点之间的最短路线,适用于所有节点 6 月前 |
![]() |
Alisa Petrova · 在有向图中更改一对顶点以创建循环 6 月前 |
![]() |
b39b332d · 使用C++标准库实现高效间隔存储 10 月前 |
![]() |
Paul C · 在维基百科上,将二叉搜索树转换为排序链表的算法是否存在错误? 11 月前 |
![]() |
ABGR · 二叉树的直径——当最长路径不通过根时的失败案例 11 月前 |
![]() |
EpicAshman · 数独棋盘程序中同一列和同一行出现两次的数字 11 月前 |