【问题标题】:Does "break continue" exist in PHP?PHP中是否存在“中断继续”?
【发布时间】:2016-07-25 16:54:41
【问题描述】:

有关此问题的上下文,请参阅我的recent post。在下面的函数中,break continue 将允许我省略最后一个 if 条件。 (参见内部 for 循环中的注释)

function strposHypothetical($haystack, $needle) {

    $haystackLength = strlen($haystack);
    $needleLength   = strlen($needle);//for this question let's assume > 0

    $pos = false;

    for($i = 0; $i < $haystackLength; $i++) {
        for($j = 0; $j < $needleLength; $j++) {
            $thisSum = $i + $j;
            if (($thisSum > $haystackLength) || 
                ($needle[$j] !== $haystack[$thisSum])) 
                  break; 
            // if I could "break continue" I could omit the 
            // if ($j === $needleLength) 
            // below and just write $pos = $i; break;       
        }
        if ($j === $needleLength) {
            $pos = $i;
            break;
        }
    }
    return $pos;
}

我看到了一些类似的帖子,例如 this 一个并不能完全回答我的问题。我不想重构上面的函数。我不需要break 2 也不需要continue 2。注意 break 2 在内部循环中不起作用,因为外部 for 循环中的必要迭代将被遗漏。 continue 2 也失败了,因为内部 for 循环需要迭代到针的末尾。 break continue 可以在 PHP 中使用吗?

注意我已经尝试过这个并得到了一个致命错误,所以我假设答案是“否”或者我没有正确地实现它。

注意 2 “break continue”是指中断内部循环,然后继续外部循环

【问题讨论】:

  • 您希望break continue 实际做什么?有点矛盾
  • 突破内部并进入外部的下一次迭代,继续跳过 $pos 并打破它,这是我想做的
  • @self 能不能多展示一些,PHP 手册中没有提到
  • 原谅我的迟钝,但break为什么不突破内在,继续外在?
  • 没什么问题 - 我只是有一个庞大的应用程序,我正试图以任何可能的方式精简(字面意思)。 “中断继续”将允许循环跳过外部循环中的最终 if 条件。如果外部循环有数万次迭代,跳过最后一个 if 将意味着什么(尽管仍然不多:))我的问题是一个合理的问题,根据回复,我假设答案是“否”

标签: php break continue


【解决方案1】:

有继续(跳过)

<?php
  while (list($key, $value) = each($arr)) {
    if (!($key % 2)) { // skip even members
       continue;
    }
    do_something_odd($value);
}

?>

http://php.net/manual/en/control-structures.continue.php

for($i = 0; $i < $haystackLength; $i++) {
    for($j = 0; $j < $needleLength; $j++) {
        $thisSum = $i + $j;
        if (($thisSum > $haystackLength) || 
            ($needle[$j] !== $haystack[$thisSum])) 
            continue;   
    }
    if ($j === $needleLength) {
        $pos = $i;
        break;
    }
}

【讨论】:

  • 哈哈,不,我的意思是我的评论被我删除了,因为我提出的问题不再出现在答案中。因为这是一件好事:-)
  • @Martin 无论如何感谢您的提示,这是一个有趣的情况
  • @scaisEdge 这与我最初的重构有同样的问题,它增加了额外的比较,因为当针不匹配时内部 for 循环不再退出,但现在继续。它也不再起作用,因为退出内部循环的唯一东西是 $j 最大化。
  • @ReidJohnson Mine 只是一个例子和一个建议.. 我不会深入讨论应用程序问题或 OP 应用程序逻辑的优点
  • 注意到,只是注意到你建议的代码根本不起作用,不管原始代码的优点。
【解决方案2】:

不幸的是,在 PHP 中没有“break continue”这样的构造,但是,通过将所有逻辑移到内部循环中,您可以完全避免标志和“break continue”的需要。根本没有真正简化逻辑,想,所以 YMMV。

function strposHypothetical( $haystack, $needle ){
    $haystackLength = strlen( $haystack );
    $needleLength = strlen( $needle );

    $pos = false;

    for( $i = 0; $i < $haystackLength; $i++ ){
        for( $j = 0; $j < $needleLength; $j++ ){
            $thisSum = $i + $j;
            if( ( $thisSum > $haystackLength )
                || ( $needle[ $j ] !== $haystack[ $thisSum ] ) )
                break;
            else if( $j === $needleLength ){
                $pos = $i;
                break 2;
            }
        }
    }

    return $pos;
}

为了解决性能问题,您甚至可以将其重构为,通过不将 $i + $j 的结果存储在变量中来增加一点性能,但确实摆脱了那个额外的变量并使 $pos 类似于标志:

function strposHypothetical( $haystack, $needle ){
    $haystackLength = strlen( $haystack );
    $needleLength = strlen( $needle );

    $pos = false;

    for($i = 0; $i < $haystackLength; $i++) {
        $pos = $i;
        for($j = 0; $j < $needleLength; $j++) {
            if(
                ( $pos + $j > $haystackLength )
                || ( $needle[ $j ] !== $haystack[ $pos + $j ] )
            ){
                $pos = false;
                break;
            }
        }

        if( $pos !== false )
            break;
    }

    return $pos;
}

昨晚有时间思考,这个重构应该通过强制比较来获得最大的性能,并分配 for 循环已经在执行大部分工作。它还大大缩短了代码;

function strposHypothetical( $haystack, $needle ){
    $haystackLength = strlen( $haystack );
    $needleLength = strlen( $needle );

    for( $i = $haystackLength, $pos = false; $i >= 1 && $pos === false; $i-- ){
        for( $j = $needleLength - 1, $pos = $i - 1; $j >= 0 && $pos !== false; $j-- ){
            $pos--;
            if( $pos < 0 || $needle[ $j ] !== $haystack[ $pos ] )
                $pos = false;
        }
    }

    return $pos;
}

【讨论】:

  • 感谢您的回复,但恕我直言,这实际上更糟,因为现在 if($j === $needleLength) 比较不是 $haystackLength times (max),而是 $haystackLength * $ needleLength 次(最大)。
  • 我知道。这就是我放 YMMV 的原因。但是,它确实从代码中获得了 break continue 的概念。在没有完全重构的情况下,您对构建的代码实际上无能为力,并且您说您不希望这样做。认为一些代码比仅仅说没有中断继续或进行令人讨厌的重构(删除所有代码并只放return strpos( $haystack, $needle);)要好
  • 好的...感谢。我确实理解对 SO 的流行回应是如何只说“你的代码很糟糕 - 你应该做的是这个......”。对您的评论和回复投票(因为您的代码确实有效)。
  • 对于第二个函数,返回的位置不应该是$i + $j,位置是$i,因为这是大海捞针的位置。 $i + $j 用于在你锁定到 haystack 上的 $i 位置后将针与 haystack 匹配
  • 它确实可以在那里完美运行,而且我也发现自己希望 PHP(和许多其他语言)中不存在的东西。我添加了第二个示例,它删除了性能问题,并且作为额外的奖励,摆脱了一个变量。并没有真正删除任何逻辑,但可以说,确实让事情变得更紧凑。
猜你喜欢
  • 2019-01-05
  • 2012-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
相关资源
最近更新 更多