实际上,这个问题被问了一个采访,我不知道确切的答案,你能详细解释一下吗?
如何从100万个文件中选择100个随机行 行呢?无法将文件读入内存。
答案 0 :(得分:4)
通常情况下,在这种情况下,您提前不知道输入文件中的项目数(并且您希望避免要求对数据进行两次传递,以检查可用项目的数量第一)。在这种情况下,@ radoh和其他人提出的解决方案,你将创建索引以供选择,将无法正常工作。
在这种情况下,您可以使用reservoir sampling:您只需要知道要选择的项目数(k
如下)并迭代输入数据({{1} })。下面是从维基百科中获取的伪代码,我将把它转换为一种有效的Java方法(该方法通常看起来像S[1..n]
):
List<X> sample(Stream<X> data, int k)
请注意,虽然代码明确提到/*
S has items to sample, R will contain the result
*/
ReservoirSample(S[1..n], R[1..k])
// fill the reservoir array
for i = 1 to k
R[i] := S[i]
// replace elements with gradually decreasing probability
for i = k+1 to n
j := random(1, i) // important: inclusive range
if j <= k
R[j] := S[i]
(即输入项的数量),但您不需要在计算之前知道该值。您可以简单地遍历n
或Iterator
(表示您的文件中的行),只需要将结果数组或集合Stream
保留在内存中。您甚至可以对连续流进行采样,并且在每个时间点(至少,您已经看到R
样本的时候),您随机k
选择的项目。
答案 1 :(得分:2)
生成100个随机(唯一)数字(范围从0..1000000-1)到列表中,然后浏览文件,读取列表中带有索引的行。理想情况下,数字列表应为Set
。
伪代码:
int i = 0;
List<String> myLines = new ArrayList();
while (fileScanner.hasNext()) {
String line = fileScanner.nextLine();
if (myRandomNumbers.contains(i)) {
myLines.add(line);
}
i++;
}
答案 2 :(得分:1)
这是一种非常有效的方法:
function rotate ( center, distance ) {
var axis = center.axis;
center.model.rotateOnAxis ( axis, distance );
applyStatesToMatrixDirectly ( center.model );
for ( var stickerIndex in center.stickers ) {
center.stickers[stickerIndex].rotateOnAxis ( axis, distance );
applyStatesToMatrixDirectly ( center.stickers[stickerIndex] );
}
for ( var childIndex in center.children ) {
center.children[childIndex].model.rotateOnAxis ( axis, distance );
applyStatesToMatrixDirectly ( center.children[childIndex].model );
for ( var childStickerIndex in center.children[childIndex].stickers ) {
center.children[childIndex].stickers[childStickerIndex].rotateOnAxis ( axis, distance );
applyStatesToMatrixDirectly ( center.children[childIndex].stickers[childStickerIndex] );
}
}
}
function applyStatesToMatrixDirectly ( model ) {
model.updateMatrix();
model.geometry.applyMatrix( model.matrix );
model.position.set( 0, 0, 0 );
model.rotation.set( 0, 0, 0 );
model.scale.set( 1, 1, 1 )
model.updateMatrix();
}
我有一段时间没用Java编写代码,因此您可能希望将其视为伪代码。
该算法基于以下事实:任何给定行的概率(假设我们在总共n行中均匀地选择k个不同的行)将以概率k / n包含在集合中。这是从
开始的1)选择k个不同行(n行中)的数字集合(n,k),
2)选择包含特定行的k个不同行(n行中)的集合数(n-1,k-1)和
3)选择(n-1,k-1)/选择(n,k)= k / n
请注意,此处的k和n分别对应代码中的Iterator<String> linesIter = ...
List<String> selectedLines = new ArrayList();
Random rng = new Random(seed);
int linesStillNeeded = 100;
int linesRemaining = 1000000;
while (linesStillNeeded > 0) {
String line = linesIter.next();
linesRemaining--;
if (rng.nextInt(linesRemaining) < linesStillNeeded) {
selectedLines.add(line);
linesStillNeeded--;
}
}
和linesStillNeeded
。