2017-01-20 4 views
0

Я пишу простую функцию PHP, которая будет обращаться к word-list.txt и вытаскивать случайное слово (слова разделяются новой строкой). Это слово должно иметь максимальную длину $ 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); 
... 

Обновление: теперь я проверил это и работает.

Смежные вопросы