2016-07-25 75 views
1

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

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在内循环中不起作用,因为外循环中的必要迭代将被忽略。 continue 2也失败,因为内循环需要迭代到针的末端。在PHP中可以使用break continue吗?

我已经试过这一点,得到了一个致命错误,所以我认为无论答案是“没有”,我实现它不正确。

注2通过 “中断继续” 我的意思打破则内循环继续外

+2

你期望'break continue'实际上能做什么?它有点矛盾 –

+0

打破内在和外面的下一个迭代,继续跳过$ POS并在它下面突破,这是我想要做的 –

+0

@self你可以展示更多这个,它不是在PHP手册 – Martin

回答

3

有继续(跳过)

<?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; 
    } 
} 
+0

@Martin谢谢回答更正 – scaisEdge

+0

@马丁..不由我..我不能删除评论.. – scaisEdge

+0

哈哈,不,我的意思是我的评论被删除,因为我提出的问题不再存在于答案。在这是一件好事':-)' – Martin

1

不幸的是,在PHP中没有像“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; 
} 
+1

谢谢你的回应,但是恭敬地说,这实际上更糟,因为现在if($ j === $ needleLength)比较没有完成$ haystackLength时间(max),而是$ haystackLength * $ needleLength时间(最大值)。 –

+1

我知道。这就是为什么我把YMMV。但是,它确实会从代码中获得中断的概念。如果没有完全重构就可以删除这个概念,并且你说你不需要这些代码,那么你可以用代码做的事情不多。认为一些代码比仅仅说没有休息继续或给予讨厌的重构去除所有代码并且只是放入'返回strpos($ haystack,$ needle)好;' –

+1

OK ...赞赏。我确实了解SO上的流行反应是如何说“你的代码不好 - 你应该做的是这个......”。对您的评论和回复进行投票(因为您的代码确实有效)。 –