从单词列表中获取特定长度的随机单词
Get random word of specific length from wordlist
我正在编写一个简单的 PHP 函数,它将访问 word-list.txt 并提取一个随机单词(单词之间用新行分隔)。这个词的最大长度需要为 $maxlength。按照我写的方式,它会拉出单词,如果长度太长,那么它会不断获取一个新单词,直到它小于或等于 $maxlength。我 运行 遇到的问题是脚本 returns 最大执行时间的致命错误。这是代码:
function GetWord($maxlength) {
$file_content = file('word-list.txt');
$nword = $file_content[array_rand($file_content)];
while(mb_strlen($nword) > $maxlength) {
$nword = $file_content[array_rand($file_content)];
}
return $nword;
}
我能想到的唯一替代方法是将单词列表放入数据库中,并在一列中包含每个对应单词的长度。这样我就可以 select 根据长度选择单词。但是,我试图避免必须使用数据库,所以我想找出我的脚本有什么问题。任何帮助是极大的赞赏。谢谢!
我认为问题出在过于复杂的事情上。
你可以爆炸内容
$content_array = explode("\n", $file_content);
随机排列数组
shuffle($content_array)
然后搜索给定长度的第一个单词。
foreach($content_array as $word) {
if(strlen($word) == $word_length)
return $word;
}
虽然我个人会把所有东西都放在数据库中。
使用随机索引重试确实效率很低。
您可以根据长度条件过滤行,这样您就只剩下有效的行,然后翻转这些行,使它们成为键。然后 array_rand
可用于从中选择一个随机密钥。所有这些都可以通过 函数式编程 方式完成:
function GetWord($maxlength) {
return array_rand(array_flip(array_filter(file('word-list.txt'),
function($line) use ($maxlength) {
return mb_strlen($line) <= $maxlength;
})));
}
以下 class 在实例化时会进行一些排序,但随后每次查找随机单词只需要 O(1) 时间:
class RandomWord {
private $words;
private $boundaries;
private static function sort($a, $b){
return strlen($a) - strlen($b);
}
function __construct($file_name) {
$this->words = file($file_name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Sort the words by their lenghts
usort($this->words, array('RandomWord', 'sort'));
// Mark the length boundaries
$last = strlen($this->words[0]);
foreach($this->words as $key => $word) {
$length = strlen($word);
if ($length > $last) {
for($i = $last; $i < $length; $i++) {
// In case the lengths are not continuous
// we need to mark the intermediate values as well
$this->boundaries[$i] = $key - 1;
}
$last = $length;
}
}
}
public function get($max_length) {
if (isset($this->boundaries[$max_length])) {
return $this->words[rand(0, $this->boundaries[$max_length])];
}
return $this->words[array_rand($this->words)];
}
}
像这样使用它:
$r = new RandomWord("word-list.txt");
$word1 = $r->get(6);
$word2 = $r->get(3);
$word3 = $r->get(7);
...
更新:现在我已经对其进行了测试并且可以正常工作。
我正在编写一个简单的 PHP 函数,它将访问 word-list.txt 并提取一个随机单词(单词之间用新行分隔)。这个词的最大长度需要为 $maxlength。按照我写的方式,它会拉出单词,如果长度太长,那么它会不断获取一个新单词,直到它小于或等于 $maxlength。我 运行 遇到的问题是脚本 returns 最大执行时间的致命错误。这是代码:
function GetWord($maxlength) {
$file_content = file('word-list.txt');
$nword = $file_content[array_rand($file_content)];
while(mb_strlen($nword) > $maxlength) {
$nword = $file_content[array_rand($file_content)];
}
return $nword;
}
我能想到的唯一替代方法是将单词列表放入数据库中,并在一列中包含每个对应单词的长度。这样我就可以 select 根据长度选择单词。但是,我试图避免必须使用数据库,所以我想找出我的脚本有什么问题。任何帮助是极大的赞赏。谢谢!
我认为问题出在过于复杂的事情上。
你可以爆炸内容
$content_array = explode("\n", $file_content);
随机排列数组
shuffle($content_array)
然后搜索给定长度的第一个单词。
foreach($content_array as $word) {
if(strlen($word) == $word_length)
return $word;
}
虽然我个人会把所有东西都放在数据库中。
使用随机索引重试确实效率很低。
您可以根据长度条件过滤行,这样您就只剩下有效的行,然后翻转这些行,使它们成为键。然后 array_rand
可用于从中选择一个随机密钥。所有这些都可以通过 函数式编程 方式完成:
function GetWord($maxlength) {
return array_rand(array_flip(array_filter(file('word-list.txt'),
function($line) use ($maxlength) {
return mb_strlen($line) <= $maxlength;
})));
}
以下 class 在实例化时会进行一些排序,但随后每次查找随机单词只需要 O(1) 时间:
class RandomWord {
private $words;
private $boundaries;
private static function sort($a, $b){
return strlen($a) - strlen($b);
}
function __construct($file_name) {
$this->words = file($file_name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Sort the words by their lenghts
usort($this->words, array('RandomWord', 'sort'));
// Mark the length boundaries
$last = strlen($this->words[0]);
foreach($this->words as $key => $word) {
$length = strlen($word);
if ($length > $last) {
for($i = $last; $i < $length; $i++) {
// In case the lengths are not continuous
// we need to mark the intermediate values as well
$this->boundaries[$i] = $key - 1;
}
$last = $length;
}
}
}
public function get($max_length) {
if (isset($this->boundaries[$max_length])) {
return $this->words[rand(0, $this->boundaries[$max_length])];
}
return $this->words[array_rand($this->words)];
}
}
像这样使用它:
$r = new RandomWord("word-list.txt");
$word1 = $r->get(6);
$word2 = $r->get(3);
$word3 = $r->get(7);
...
更新:现在我已经对其进行了测试并且可以正常工作。