I have a set of functions that retrieve words from some arbitrary dictionary based on what letters they have. For example, this function gets words that use only the specified letters:
function getWordsWithOnlySpecifiedLetters(array $dictionary, string $letters)
{
foreach ($dictionary as $key => $value) {
if(mb_strlen($value) > mb_strlen($letters)) unset($dictionary[$key]);
}
$step = 0;
$strSplit = preg_split('//u', $letters, null, PREG_SPLIT_NO_EMPTY);
$result = [];
foreach ($dictionary as $word) {
$step++;
$wordSplit = preg_split('//u', $word, null, PREG_SPLIT_NO_EMPTY);
sort($wordSplit);
sort($strSplit);
if (array_map('mb_strtolower', $wordSplit) === array_map('mb_strtolower', $strSplit)) {
//echo "All specified letters from $letters are in $word | Step $step<hr>" . PHP_EOL;
$result[] = $word;
}
}
return $result;
}
Example usage:
$dictionary = ['apple', 'sample', 'api', 'pia', 'тоҷик'];
getWordsWithOnlySpecifiedLetters($dictionary, "aip");
This would return the words api
and pia
.
getWordsWithOnlySpecifiedLetters($dictionary, "leamps");
This one would return the word sample
.
I also have a function that doesn't require that they exclusively use the selected letters, but rather that they use all of the specified letters (and any other letters).
function getWordsWithSpecifiedLetters(array $dictionary, string $letters)
{
$step = 0;
mb_internal_encoding("UTF-8");
$result = [];
foreach ($dictionary as $word) {
$step++;
$wordSplit = preg_split('//u', $word, null, PREG_SPLIT_NO_EMPTY);
$strSplit = preg_split('//u', $letters, null, PREG_SPLIT_NO_EMPTY);
$wordSplit = array_filter($wordSplit, function($x) use (&$strSplit) {
if (in_array(strtolower($x), array_map('strtolower', $strSplit), true)) {
$pos = array_search(strtolower($x), array_map('strtolower', $strSplit), true);
unset($strSplit[$pos]);
return false;
}
return true;
});
if (count(array_diff($strSplit,$wordSplit)) === 0) {
//echo "$word contains all letters of $letters | Step $step<hr>" . PHP_EOL;
$result[] = $word;
}
}
return $result;
}
Example usage:
$dictionary = ['apple', 'sample', 'api', 'pia', 'тоҷик'];
getWordsWithSpecifiedLetters($dictionary, "ple");
This returns the words sample
and apple
.
I have more 90000 words in my dictionary (UTF-8). This results in a very slow program; if I'm trying to find something from the full dictionary it may take tens of thousands of loops. How can I improve the performance of these functions?
You can download my dictionary from here and testing your code using dictionary words.