Search code examples
phparraysstringloopswords

How to check if words can be created from list of letters?


I have a string $raw="aabbcdfghmnejaachto" and an array $word_array=array('cat','rat','goat','total','egg').

My program needs to check whether it is possible to make the words in the array with letters from the string. There is one extra condition; if the word contains a letter occurring more than once, that letter must occur at least the same number of times in the string.

E.g. egg. There are two g's. If the string $raw doesn't contain two g's, then it's not possible to make this word.

This is my expected result:

Array([cat]=>'Yes',[rat]=>'No',[goat]=>'Yes',[total]=>'No',[egg]=>'No')

I tried the following, but it doesn't output the expected result:

$res=array();
$raw="aabbcdfghmnejaachto";
$word_array=array('cat','rat','goat','total','egg');
$raw_array= str_split($raw);
foreach($word_array as $word=>$value)
{
    $word_value= str_split($value);
    foreach($word_value as $w=>$w_value)
    {
        foreach($raw_array as $raw=>$raw_value)
        {
            if(strcmp($w_value,$raw_value)==0)
            {
                $res[$value]='Yes';
            }
            else
            {
                $res[$value]='No';
            }
        }
    }
}
print_r($res);

EDIT: The code, as originally posted, was missing the letter e from the string $raw so the egg example would actually return No. I have updated the Question and all the Answers to reflect this. - robinCTS


Solution

    • You must loop through each word/element in the $words array, then loop again through each character of each word.
    • Upon each iteration of the outer loop, set the default result value to Yes.
    • Then you must iterate each unique character of the current word. (array_count_values())
    • Check if the number of occurrences of the current character in the word is greater than the number of occurrences of the current character in the string of letters.

    *As a matter of performance optimization, array_count_values() is used on the inner loop to avoid any unnecessary iterations of duplicate letters in $word. The $count variable saves having to make two substr_count() calls in the if statement.

    Code: (Demo)

    $string = "aabbcdfghmnejaachto";
    $words = array('cat','rat','goat','total','egg');
    foreach ($words as $word) {  // iterate each word
        $result[$word]='Yes';  // set default result value
        foreach (array_count_values(str_split($word)) as $char=>$count) {  // iterate each unique letter in word
            if ($count > substr_count($string, $char)) {  // compare current char's count vs same char's count in $string
                $result[$word]='No';  // if more of the character in word than available in $string, set No
                break;  // make early exit from inner loop, to avoid unnecessary iterations
            }
        }    
    }
    var_export($result);
    

    This is the output :

    array (
      'cat' => 'Yes',
      'rat' => 'No',
      'goat' => 'Yes',
      'total' => 'No',
      'egg' => 'No',
    )
    

    BIG THANKYOU to mickmackusa for hijacking significantly enhancing this answer.