Уникальный генератор строк генерирует дубликаты, даже если существует уникальная проверка

Я делаю небольшой класс, который использует списки слов gfycat для генерации уникальных строк.

<?php

namespace Jamosaur\Randstring;

class Randstring
{
private $adjectives;
private $animals;

private $min;
private $max;
private $case;
private $maxLength;

private $string;

public $combinations = [];

private $first;
private $second;

public $adjective;
public $animal;
public $number;

/**
* Randstring constructor.
* @param null $case (ucwords, ucfirst)
* @param int $maxLength
* @param int $min
* @param int $max
*/
public function __construct($case = null, $maxLength = 100, $min = 1, $max = 99)
{
$this->case         = $case;
$this->maxLength    = $maxLength;
$this->min          = $min;
$this->max          = $max;
$this->adjectives   = explode(PHP_EOL, file_get_contents(__DIR__.'/dictionaries/adjectives.txt'));
$this->animals      = explode(PHP_EOL, file_get_contents(__DIR__.'/dictionaries/animals.txt'));
}

/**
* @param null $first
* @param null $second
*/
public function generateNumbers($first = null, $second = null)
{
$this->first    = ($first) ? $first : mt_rand(0, count($this->adjectives) - 1);
$this->second   = ($second) ? $second : mt_rand(0, count($this->animals) - 1);
$this->number   = mt_rand($this->min, $this->max);
if (isset($this->combinations[$this->first.'.'.$this->second.$this->number])) {
$this->generateNumbers($this->first, $this->second);
}
$this->combinations[$this->first.'.'.$this->second.$this->number] = 1;
}

/**
* Generate a string.
*/
public function generateString()
{
$this->generateNumbers();
$this->adjective    = $this->adjectives[$this->first];
$this->animal       = $this->animals[$this->second];
switch ($this->case) {
case 'ucfirst':
$this->string   = ucfirst($this->adjective.$this->animal.$this->number);
break;
case 'ucwords':
$this->string   = ucfirst($this->adjective).ucfirst($this->animal).ucfirst($this->number);
break;
default:
$this->string   = $this->adjective.$this->animal.$this->number;
break;
}
}

/**
* @return mixed
*/
public function generate()
{
$this->generateString();
if (strlen($this->string) > $this->maxLength) {
return $this->generate();
}

return $this->string;
}
}

Я добавил регистрацию для регистрации каждой комбинации, которая была создана в generateNumbers() который должен хранить каждую комбинацию в массиве.

Я настроил небольшой тест для генерации 10000 уникальных строк только для тестирования производительности, что делается с помощью этого фрагмента:

$rand = new Jamosaur\Randstring\Randstring(null, 10);
for ($i=0; $i < 10000; $i++) {
$t[$i] = $rand->generate();
}
echo 'Unique Strings: '.count(array_unique($t)).'<br>';
echo 'Combinations: '.count($rand->combinations).'<br>';

Ожидается, что при выполнении этого будет 10000 уникальных строк.

Я выполнил тест 10 раз, и это были результаты:

Уникальные строки: 9998
Комбинации: 527879

Уникальные строки: 9999
Комбинации: 518899

Уникальные строки: 9999
Комбинации: 515290

Уникальные строки: 9999
Комбинации: 516193

Уникальные строки: 10000
Комбинации: 526652

Уникальные строки: 10000
Комбинации: 516049

Уникальные строки: 10000
Комбинации: 523217

Уникальные строки: 10000
Сочетания: 509729

Уникальные строки: 10000
Комбинации: 517236

Уникальные строки: 10000
Комбинации: 512270

Есть ли здесь какая-то ошибка в логике? Тест ограничен 10-символьной строкой, но тесты показывают, что существует не менее 10000 уникальных строк.

0

Решение

Несколько проблем в вашем коде:

а) Запоминание использованных комбинаций имеет недостатки

$this->combinations[$this->first.'.'.$this->second.$this->number] = 1;

Для данного $ this-> first это будет конфликтовать для

$ this-> second = 10, $ this-> number = 11 (= 1011)

$ this-> second = 101, $ this-> number = 1 (= 1011)

Добавьте разделитель между $ this-> second и $ this-> number

б) возможно, есть дубликаты в ваших списках слов
Я скачал файлы и, например, слово «зеленый» является дубликатом в прилагательных

c) Тщательно отлаживайте рекурсивный (самоссылающийся) символ вашего кода.

г) Какова цель аргументов в функции generateNumbers ($ first = null, $ second = null)?

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector