【问题标题】:doesn't while loop work correctly in PHP?在 PHP 中,while 循环不能正常工作吗?
【发布时间】:2012-01-21 09:03:40
【问题描述】:

我想从字符串中的以下单词中获取字符数。例如,如果我的输入是I am John,那么输出必须是这样的:

1 // count of 'I'
4 // count of 'I am'
9 // count of 'I am John'

我在 PHP 中使用这样的代码来处理这个过程:

$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);

$i =0;
while ($i<=$count_words){
    $word_length =0;
    $k=0;
    while($k<=$i){
        $word_length = strlen($words[$k-1]);
        $word_length = $word_length + strlen($words[$k]);
        $k++;
    }
    $word_length = $word_length + $i; // there is "$i" means "space"
    echo $word_length.'<br/>';
    $i++;

}

但它会像这样返回输出:

1
4
8
7

为什么?我的错误在哪里?我的代码必须是什么样的?
提前致谢!

【问题讨论】:

  • Re title: 不,您不仅在迄今为止最流行的语言之一的最基本、广泛使用的语言结构中发现了一个错误。 :o)
  • ok :) 你建议什么标题? :)
  • 这是一个免费赠品:codepad.viper-7.com/3R02TK 但说真的,要学会调试自己的代码,否则你将无法在编程中完成任何工作。调试只是意味着逐步检查代码以找出问题所在。经常使用var_dump()

标签: php algorithm loops while-loop


【解决方案1】:
<?php
$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);
$i =0;
while ($i<$count_words){
    if($i==0) {
    $wordsc[$i] = strlen($words[$i]);
    } else {
    $wordsc[$i] = strlen($words[$i])+1+$wordsc[$i-1];
    }
    echo $wordsc[$i]."<br>";
    $i++;
}
?>

【讨论】:

    【解决方案2】:

    你的错误在这里:

    $i =0;
    while ($i<=$count_words){
       //....
    }
    

    $count_words3,但由于 &lt;=,您重复了 4 次。请改用&lt;

    【讨论】:

    • 好的,谢谢。但现在它返回 1 4 8 。为什么最后是'8'?但必须有 '9' 而不是 '8'。
    • @John 代码有更多问题 - 第一次迭代时的 $words[$k-1] 将是 $words[-1] 。我测试了代码,它没有打印出你所说的内容。
    • 那么,你有什么建议?我必须使用什么来代替 $words[$k-1] ?
    • @John 我建议你重新考虑你的算法。我们可以帮助解决特定问题,而不是为您重新编写代码以使其正常工作。你试过调试吗?
    • 没有,我没有(其实我不知道怎么调试PHP脚本,现在正在找,你觉得调试对我有帮助吗?
    【解决方案3】:
    1. 您正在循环播放许多单词。当您使用 count 时,它会返回数组中元素的数量。记住一个数组从 0 开始。
    2. $word_length + strlen($words[$k - 1]); // 你在减 1 我认为你是在试图满足计数的需求,但你从 0 中减去 -1 导致第一个单词被遗漏。

    代码片段开始

    //Set up the words
    
    $string = 'I am John';
    
    $words = explode(' ',$string);
    
    $count_words = count($words);
    
    //Loop through the words
    $i =0;
    
    while ($i<$count_words){
    
    $word_length =0;
    $k=0;
    
    $debugString = '';
    
    //Loop through all the previous words to the current
    while($k<= $i){
    
        //dont really need this since were adding the word length later
        //$word_length = strlen($words[$k]);
    
        //if you -1 from 0 you will get an undefined offest notice. You
        //want to look at your current word
        $word_length = $word_length + strlen($words[$k]);
    
        //A bit of debugging you can delete this once you have seen the results
        $debugString = $debugString ." ".$words[$k];
    
        $k++;
    }
    
    $word_length = $word_length + $i ; // there is "$i" means "space"
    
    //Added the debugString for debugging so remove it once you have seen the results
    echo $word_length." " .$debugString.' <br/>';
    $i++;
    
    }
    

    代码片段结束

    【讨论】:

      【解决方案4】:

      我很高兴为您提供一种完全不同的方法,以非常直接的方式生成所需的数据。 (Demo of what is to follow)

      var_export(preg_match_all('/ |$/','I am John',$out,PREG_OFFSET_CAPTURE)?array_column($out[0],1):'failure');
      

      输出:

      array (
        0 => 1,
        1 => 4,
        2 => 9,
      )
      

      确定每个单词递增子字符串的长度实际上与确定每个尾随空格的offset 或最后一个单词 - 完整字符串长度相同。

      preg_match_all() 有一个内置的“标志”:PREG_OFFSET_CAPTURE

      preg_match_all() 在任何数组操作之前都会输出:

      array (
        0 => 
        array (
          0 => 
          array (
            0 => ' ',   // <-- the space after 'I' matched by ' '
            1 => 1,
          ),
          1 => 
          array (
            0 => ' ',  // <-- the space after 'am' matched by ' '
            1 => 4,
          ),
          2 => 
          array (
            0 => '',  // <-- the end of the string (after 'John') matched by '$'
            1 => 9,
          ),
        ),
      )
      

      array_column() 用于$out[0] 仅提取偏移值(省略无用的空白和空字符串)。


      这是另一种完全不同的方法:

      array_reduce(preg_split('/(?= )/',$string),function($carry,$item){echo $carry+=strlen($item)," "; return $carry;},0);
      output: 1 4 9 
      

      这会将字符串拆分为“零宽度”字符串,后跟一个空格。这意味着在爆炸过程中,空格不会丢失——这样可以保持字符串和子字符串的长度,以便于简单相加。

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 2015-05-14
        • 1970-01-01
        • 2012-11-04
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多