我有一个字符串$raw="aabbcdfghmnejaachto"
和一个数组$word_array=array('cat','rat','goat','total','egg')
。
我的程序需要检查是否可以使用字符串中的字母来生成数组中的单词。有一个额外的条件;如果单词包含多于一次的字母,则该字母必须至少在字符串中出现相同的次数。
E.g。 egg
。有两个g
。如果字符串$raw
不包含两个g
,则无法生成此单词。
这是我的预期结果:
Array([cat]=>'Yes',[rat]=>'No',[goat]=>'Yes',[total]=>'No',[egg]=>'No')
我尝试了以下操作,但它没有输出预期的结果:
$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);
编辑:最初发布的代码缺少字符串e
中的字母$raw
,因此egg
示例实际上会返回{{1} }}。我已更新问题和所有答案以反映这一点。 - robinCTS
答案 0 :(得分:9)
$words
数组中的每个单词/元素,然后再循环遍历每个单词的每个字符。Yes
。array_count_values()
) *作为性能优化的问题,在内循环上使用array_count_values()
以避免$word
中重复字母的任何不必要的迭代。 $count
变量保存了必须在if语句中进行两次substr_count()
调用。
代码:(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);
这是输出:
array (
'cat' => 'Yes',
'rat' => 'No',
'goat' => 'Yes',
'total' => 'No',
'egg' => 'No',
)
BIG THANKYOU 至mickmackusa 劫持显着增强了这个答案。
答案 1 :(得分:2)
您的问题是您没有计算$raw
数组中每个字符出现的次数,您只需检查每个字中的每个字符,以查看$raw
中是否存在该字符。除非你进行某种形式的计数,否则为每个单词复制$raw
并删除使用中的字母,否则你将无法做到这一点。
答案 2 :(得分:2)
我已计算字符串中出现的字符数并比较该出现次数!你可以找到这个答案!
$res=array();
$raw="aabbcdfghmnejaachto"; //tgrel -- to make all yes
$res=array();
$word_array=array('cat','rat','goat','total','egg');
$raw_array= str_split($raw);
$count_raw = array_count_values($raw_array);
foreach($word_array as $value)
{
$word_value= str_split($value);
$newArray = array_count_values($word_value);
$res[$value]='yes';
foreach($newArray as $char=>$number){
if(!isset($count_raw[$char]) || $count_raw[$char]<$number){
$res[$value]='No';
break;
}
}
}
print_r($res);
答案 3 :(得分:1)
你的错误很明显,你决定在单个字符测试中是否接受一个单词的值,而它应该基于单词的所有字母,你不需要同时精确数组的键和值,如果只需要它的值 如在
foreach($word_array as $value)
然后我发现使用函数in_array(),使代码更清晰
$res=array();
$raw="aabbcdfghmnejaachto";
$res=array();
$word_array=array('cat','rat','goat','total','egg');
$raw_array= str_split($raw);
foreach($word_array as $value)
{
$word_value= str_split($value);
$res[$value]='yes';
foreach($word_value as $w_value)
{
if (!in_array($w_value,$raw_array))
$res[$value]='No';
}
}
print_r($res);
答案 4 :(得分:1)
让我们尝试使用w / o循环,但使用闭包:
$raw = "aabbcdfghmnejaachto";
$word_array = ['cat', 'rat', 'goat', 'total', 'egg'];
$result = [];
$map = count_chars($raw, 1);
array_walk(
$word_array,
function ($word) use ($map, &$result) {
$result[$word] = !array_udiff_assoc(
count_chars($word, 1), $map, function ($i, $j) { return $i > $j; }
) ? 'Yes' : 'No';
}
);
count_chars($raw, 1)
的原始字符串中使用,所以它看起来像这样。 $map:
[
97 => 4, // "97" is a code for "a"; and "4" - occurrence number.
98 => 2,
...
]
array_walk
会翻译单词并将其中的每一个添加到最终$result
中,其中Yes
或No
值来自与地图的比较,这是为一个单词而构建的。
array_udiff_assoc
比较两张地图,丢弃那些具有相同关键字的元素和较大的原始地图值(与单词的地图比较)。此外, array_udiff_assoc()返回一个数组,其中包含来自array1的所有值,这些值在任何其他参数中都不存在,因此最后一步是array_udiff_assoc
之前的否定操作。
答案 5 :(得分:0)
试试这个
$res=array();
$word_array=array('cat','rat','goat','total','egg');
$raw="aabbcrdfghmnejaachtol";
foreach($word_array as $word=>$value)
{
$raw_array= str_split($raw);
$res[$value]='Yes';
$word_value= str_split($value);
foreach($word_value as $w=>$w_value)
{
if(!in_array($w_value,$raw_array))
{
$res[$value]='No';
}
else
{
unset($raw_array[array_search($w_value, $raw_array)]);
}
}
}
如果使用一次,则不会再允许使用字符。如“total”。
答案 6 :(得分:0)
我们可以查看每个单词的每个字母是否都在给出的字母内,然后在我们去的时候找出字母。
如果找不到信件,下面的功能会短路。
<?php
function can_form_word_from_letters($word, $letters) {
$letters = str_split($letters);
$word_letters = str_split($word);
foreach($word_letters as $letter) {
$key = array_search($letter, $letters);
if($key === false) return;
unset($letters[$key]); // Letter found, now remove it from letters.
}
return true;
}
$letters = "aabbcdfghmnejaachto";
$words = array('cat','rat','goat','total','egg');
foreach($words as $word) {
$result[$word] = can_form_word_from_letters($word, $letters) ? 'Yes' : 'No';
}
var_dump($result);
输出:
array (size=5)
'cat' => string 'Yes' (length=3)
'rat' => string 'No' (length=2)
'goat' => string 'Yes' (length=3)
'total' => string 'No' (length=2)
'egg' => string 'No' (length=2)