我见过how to get a random line from a text file,但那里所说的方法(接受的答案)运行速度非常慢。它在我的598KB文本文件上运行得非常慢,并且在我的一个文本文件版本上仍然很慢,该文本文件只有20行中每20行中有一行。我从未超越“a”部分(这是一个单词表)。
原始文件有64141行;缩短的有2138行。为了生成这些文件,我使用Linux Mint 11 /usr/share/dict/american-english
wordlist并使用grep
删除任何带有大写或撇号(grep -v [[:upper:]] | grep -v \'
)的内容。
我正在使用的代码是
String result = null;
final Random rand = new Random();
int n = 0;
for (final Scanner sc = new Scanner(wordList); sc.hasNext();) {
n++;
if (rand.nextInt(n) == 0) {
final String line = sc.nextLine();
boolean isOK = true;
for (final char c : line.toCharArray()) {
if (!(constraints.isAllowed(c))) {
isOK = false;
break;
}
}
if (isOK) {
result = line;
}
System.out.println(result);
}
}
return result;
略微改编自Itay's answer。
对象constraints
是KeyboardConstraints
,基本上有一种方法isAllowed(char)
:
public boolean isAllowed(final char key) {
if (allAllowed) {
return true;
} else {
return allowedKeys.contains(key);
}
}
其中allowedKeys
和allAllowed
在构造函数中提供。此处使用的constraints
变量"aeouhtns".toCharArray()
为allowedKeys
且allAllowed
关闭。
基本上,我希望方法做的是选择满足约束的随机词(例如,对于这些约束,“outvote”会起作用,但不是“worker”,因为“w” “不在"aeouhtns".toCharArray()
)。
我该怎么做?
答案 0 :(得分:3)
您的实施中存在错误。您应该在选择随机数之前阅读该行。改变这个:
n++;
if (rand.nextInt(n) == 0) {
final String line = sc.nextLine();
对此(如original answer):
n++;
final String line = sc.nextLine();
if (rand.nextInt(n) == 0) {
您还应该在绘制随机数之前检查约束。如果一行不通过约束,则应忽略它,如下所示:
n++;
String line;
do {
if (!sc.hasNext()) { return result; }
line = sc.nextLine();
} while (!meetsConstraints(line));
if (rand.nextInt(n) == 0) {
result = line;
}
答案 1 :(得分:2)
我会阅读所有行,将它们保存在某处,然后从中选择一条随机行。这需要花费大量的时间,因为这些天小于1 MB的单个文件很小。
public class Main {
public static void main(String... args) throws IOException {
long start = System.nanoTime();
RandomDict dict = RandomDict.load("/usr/share/dict/american-english");
final int count = 1000000;
for (int i = 0; i < count; i++)
dict.nextWord();
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds to load and find %,d random words.", time / 1e9, count);
}
}
class RandomDict {
public static final String[] NO_STRINGS = {};
final Random random = new Random();
final String[] words;
public RandomDict(String[] words) {
this.words = words;
}
public static RandomDict load(String filename) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filename));
Set<String> words = new LinkedHashSet<String>();
try {
for (String line; (line = br.readLine()) != null; ) {
if (line.indexOf('\'') >= 0) continue;
words.add(line.toLowerCase());
}
} finally {
br.close();
}
return new RandomDict(words.toArray(NO_STRINGS));
}
public String nextWord() {
return words[random.nextInt(words.length)];
}
}
打印
Took 0.091 seconds to load and find 1,000,000 random words.