2017-01-20 8 views
0

word-list.txtにアクセスし、ランダムな単語を引く(単語は改行で区切られます)、簡単なPHP関数を書いています。この単語の最大長は$ maxlengthである必要があります。私がそれを書いた方法は、それは単語を引き出し、長さが長すぎる場合、$ maxlength以下になるまで新しい単語を取得し続けます。私が実行している問題は、スクリプトが最大実行時間に致命的なエラーを返すことです。ここでは、コードは次のようになります。単語リストから特定の長さのランダムな単語を取得

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; 
} 

私はデータベースに単語リストを置くと、対応する各単語の長さの列を持っていると考えることができる唯一の選択肢。それは私の長さに基づいて単語の選択肢を選択することができます。しかし、私はデータベースを使用することを避けようとしています。だから、私のスクリプトに何が間違っているかを知りたいのです。どんな助けでも大歓迎です。ありがとう!

+0

私が言及しておかなければならないことは、このファイルがかなり大きく、9000以上の行を含んでいることです。これにより、指定された提案の一部がまだタイムアウトしています。 – bigbluehouse

答えて

0

私は問題が過度に複雑なものから来ていると思います。

あなたはコンテンツ

$content_array = explode("\n", $file_content); 

が配列

shuffle($content_array) 

をシャッフルし、その後、所定の長さの最初の単語を検索爆発する可能性があります。

foreach($content_array as $word) { 
    if(strlen($word) == $word_length) 
     return $word; 
} 

個人的にはすべてをデータベースに入れます。

0

ランダムインデックスを使用して再試行することは、むしろ非効率的です。

有効な行だけが残るように、行を長さ条件でフィルタリングしてから、その行を反転してキーにすることができます。その後、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; 
     }))); 
} 
0

次のクラスは、いくつかの並べ替えを行いますが、その後ランダムな単語ごとの検索は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); 
... 

アップデート:今、私はそれと作品をテストしています。

関連する問題