【问题标题】:How can I iterate through multiple strings with multiple array values, in PHP?如何在 PHP 中遍历具有多个数组值的多个字符串?
【发布时间】:2016-11-27 00:22:07
【问题描述】:

* revo 回答中的更新问题

这是一个工作脚本,其中包含一组更好的示例字符串来显示我的意图-

$strings[] = 'seventy five yards out';
$strings[] = 'sixty yards out';
$strings[] = 'one hundred fifty yards out';

$inputString = 'seventy two yards out';
$inputWords = str_word_count($inputString, 1);

$foundWords = [];

foreach ($strings as $key => $string) {
    $stringWords = str_word_count($string, 1);
    $wordsCount = array_count_values($stringWords);
    $commonWords = array_intersect($inputWords, array_keys($wordsCount));
    if (count($commonWords) > 0) {
        foreach ($commonWords as $commonWord) {
            $foundWords[$key][$commonWord] = $wordsCount[$commonWord];
        }
    }
}

print_r($foundWords);

我如何让它打印出“七十五码”,因为它实际上是最接近文本的?我正在考虑将字数除以得到一个百分比,但现在认为现在可能可行..

【问题讨论】:

    标签: php arrays string loops preg-grep


    【解决方案1】:

    关键是对每个提供的字符串分别执行str_word_count()。这样我们就转化为数组,处理数组就更简单了。

    array_count_values() 计算导致出现单词次数的数组的值。

    $strings[] = 'seventy five yards out';
    $strings[] = 'sixty yards out';
    $strings[] = 'one hundred fifty yards out';
    
    $inputString = 'seventy two yards out';
    $inputWords = str_word_count($inputString, 1);
    
    $probabilities = [];
    
    foreach ($strings as $key => $string) {
        $stringWords = str_word_count($string, 1);
        $wordsCount = array_count_values($stringWords);
        $commonWords = array_intersect($inputWords, array_keys($wordsCount));
        if (count($commonWords) > 0) {
            foreach ($commonWords as $commonWord) {
                if (!isset($probabilities[$key])) $probabilities[$key] = 0;
                $probabilities[$key] += $wordsCount[$commonWord];
            }
            $probabilities[$key] /= count($stringWords);
        }
    }
    arsort($probabilities);
    echo $strings[key($probabilities)];
    

    输出:

    seventy five yards out
    

    概率print_r($probabilities);:

    Array
    (
        [0] => 0.75
        [1] => 0.66666666666667
        [2] => 0.4
    )
    

    Live demo

    【讨论】:

    • 不客气。此外,当您接受 jerdiggity 的回答时,您应该要求他进行修改,因为字符串中重复单词的数量没有在他的代码中考虑。 @RyanD
    • 是的,这就是我回复他的内容,我没有看到他们在哪里被考虑在内,以为我只是错过了一些东西..
    • 我将如何进一步打印获胜的句子?我不擅长数组
    • 胜诉的因素是什么? @RyanD
    • 我根据您上次的更新再次更新。此外,最好将您的编辑恢复到原来的问题,这是一个真正的问题。 @RyanD
    【解决方案2】:

    这样的事情应该可以工作:

    <?php
    
    $g = 'the weather is nice'; // strings to loop through
    $n = 'the water is blue';
    $b = 'that was a bad movie';
    
    $t = 'hows the weather';  // example input
    $test = (str_word_count($t, 1)); // breaks out each word into array
    
    // Comparisons
    $comps = array();
    // Array sums
    $sums = array();
    // Search each variable that's been set, as long as it's less that 't'
    // A "for" loop will accept letters in addition to numbers, so we'll start with the
    // letter "a" and loop through each letter up to "s" (which is one less than "t")
    for ($inc = 'a'; $inc < 't'; $inc++) {
      // Now, a variable assigned as $$inc will translate into $a, $b, $c ... $s
      // and if $a, $b, $c, etc, are set...
      if (isset($$inc)) {
        // ... assign them to the $comps array with a key of $$inc
        $comps[$$inc] = str_word_count($$inc, 1);
    
        // For example, when the "for" loop reaches "f", nothing will be added to the
        // $comps array because $f is not set above.
    
        // But when it gets to "g" it'll find that $g HAS been set, and that it has a
        // value of "the weather is nice". At this point the $comps array will now look
        // like this:
        // $comps['the weather is nice'] = array('the', 'weather', 'is', 'nice');
    
        // If you'd like to see this in action (since it might sound a little confusing),
        // remove the # from the beginning of each of the following lines that start with #
        // (there should be 10 total):
    
        #print "<pre>The loop has reached the letter <b>{$inc}</b> for the value of ";
        #print "<b>\$inc</b> and has found that <b>\${$inc}</b> HAS been set in the code.\n";
        #print "Adding another dollar sign to <b>\$inc</b> has had the following effects:\n";
        #print "- <b>\$inc</b> now looks like <b>\$\$inc</b> (from within the written part of the code)\n";
        #print "- <b>\$\$inc</b> translates into <b>\${$inc}</b> (the variable that is acually being evaluated)\n";
        #print "- <b>\${$inc}</b> evaluates to <b>{$$inc}</b>\n</pre>";
      }
      #else {
      #  print "<pre>The loop has reached the letter <b>{$inc}</b> for the value of <b>\$inc</b>";
      #  print " and has found that <b>\${$inc}</b> has NOT been set in the code, so it's being skipped.\n";
      #}
    }
    // Avoid errors by checking if empty or not
    if (!empty($comps)) {
      foreach ($comps as $key => $comp) {
        // Find intersections, if any
        $candidates[$key] = array_intersect($test, $comp);
        // Count the intersections
        $counts[$key] = array_count_values($candidates[$key]);
        // Add up the intersections
        $sums[$key] = array_sum($counts[$key]);
      }
    }
    $winner = '';
    if (!empty($sums)) {
      // Reverse sort $sums, putting the highest value first
      arsort($sums);
      // Flip $sums so we can extract the key
      $flipped = array_flip($sums);
      // Extract the first key off of $sums
      $winner = array_shift($flipped);
    }
    
    print $winner;
    

    【讨论】:

    • 是的,这很好用,但你有点搞不懂它是如何工作的,它在哪里循环 $g、$b 和 $n?抱歉,我是新手。。谢谢! @jerdiggity
    • @RyanD 它在 for 循环中搜索 $g、$b 和 $n。 for ($inc = 'a'; $inc &lt; 't'; $inc++) { if (isset($$inc)) { $comps[$$inc] = str_word_count($$inc, 1); } }。它被称为变量变量stackoverflow.com/questions/2715654/…
    • @RyanD 我用更多解释更新了我的答案......希望它能解决问题。 :)
    • 哇很好的解释!谢谢@jerdiggity
    【解决方案3】:

    首先,您的问题也是询问出现次数。但是当你显然走得更远时,我觉得我应该竞标另一种解决方案。

    similar_text() 函数!

    $strings[] = 'sixty yards out';
    $strings[] = 'seventy five yards out';
    $strings[] = 'one hundred fifty yards out';
    
    $inputString = 'seventy two yards out';
    
    $p = 0;
    $k = null;
    foreach ($strings as $key => $string) {
        similar_text($inputString, $string, $percent);
        if ($percent > $p) {
            $p = $percent;
            $k = $key;
        }
    }
    
    echo !is_null($k) ? $strings[$k] : "";
    

    输出:

    seventy five yards out
    

    Live demo

    【讨论】:

      猜你喜欢
      • 2019-04-29
      • 2018-03-07
      • 2015-03-26
      • 1970-01-01
      • 2020-12-27
      • 2021-07-18
      • 2021-07-15
      • 2012-06-19
      • 1970-01-01
      相关资源
      最近更新 更多