【问题标题】:How to write a function to output unconstant loop如何编写一个函数来输出非恒定循环
【发布时间】:2011-02-07 07:01:48
【问题描述】:

这里是功能说明

test($argv)

$argv是一个数组,例如$argv=array($from1,$to1,$from2,$to2.....); 数组项必须是偶数。

$argv=array(1,3,4,5) :这将输出如下值:

1_4
1_5
2_4
2_5
3_4
3_5

伪代码就像

while($from1<=$to1){
   while($from2<=$to2){
         echo $from1."_".$from2."<br/>";
        $from2++;
   }
   $from1++;
}

$argv=array(1,2,3,4,5,6) :这将输出如下值:

1_3_5
1_3_6
1_4_5
1_4_6
2_3_5
2_3_6
2_4_5
2_4_6

伪代码就像

while($from1<=$to1){
   while($from2<=$to2){
        while($from3<=$to3){
             echo $from1."_".$from2."_".$from3."<br/>";
             $from3++;
        }
        $from2++;
   }
   $from1++;
}

数组 $argv 的数量不是恒定的。 可能会输出 3 或 4 级循环。

我只是听说会使用尾部递归或迭代,但我不知道具体如何编码。

【问题讨论】:

  • 你能概括一下这个函数应该做什么吗? AFAIU 它应该输出$from 值和$to 值的所有可能组合..?
  • @deceze 问题已被编辑以更准确地描述。
  • 对不起,这更不清楚。为什么在第一个示例中有2 输出,而输入中没有2?请尝试将逻辑转化为文字,这也会对您有所帮助。
  • @deceze:最后一句话+1。似乎每个 'from','to' 对代表了 'from' 和 'to' (含)之间的一系列值
  • 做这个递归比迭代更难......为什么你需要它递归?

标签: php loops recursion


【解决方案1】:

这样的?

test("1", "2", "4", "5", "6", "7", "8", "9");

function test(){
    $args = func_get_args();
    $cnt = func_num_args();
    //echo "cnt :: " . ($cnt % 2) . "\n";

    if(($cnt % 2) > 0) return false;

    $split = $cnt / 2;
    list($list1, $list2) = array_chunk($args, ($cnt / 2));
foreach($list1 as $idx=>$val){
    foreach($list2 as $idx2=>$val2){
        echo $list1[$idx] . "_" . $list2[$idx] . "\n";
    }
}       
}

这是输出:

1_6
1_6
1_6
1_6
2_7
2_7
2_7
2_7
4_8
4_8
4_8
4_8
5_9
5_9
5_9
5_9

【讨论】:

  • @silent 不,不是这样,伙计。必须使用递归来输出我需要的内容。
  • @tunpishuang 为什么要坚持递归?您可以在这里做的最好的事情是尾递归,它与循环相同。
  • 我认为这是来自学校的任务。
【解决方案2】:

这里有一些功能:

    header("Content-type: text/plain");

    function testFromTo($args) {
        echo "***** testFromTo *****\n";
        // uses indexes parity to walk the array
        foreach ($args as $k1=>$v1) {
            if (($k1 + 1) % 2 == 1) {
                foreach ($args as $k2=>$v2) {
                    if (($k2 + 1) % 2 == 0) {
                        echo $v1 . "_" . $v2 . "\n";
                    }
                }
            }
        }
    }

    function testHalf($args) {
        echo "***** testHalf *****\n";
        // cuts $args in two parts
        $args1 = array_slice($args, 0, count($args) / 2);
        $args2 = array_slice($args, count($args) / 2);

        foreach ($args1 as $v1) {
            foreach ($args2 as $v2) {
                echo $v1 . "_" . $v2 . "\n";
            }
        }
    }


    $argv = array(1, 2, 3, 4, 5, 6);
    testFromTo($argv);
    testHalf($argv);

    exit;
?>

和相关的输出:

***** testFromTo *****
1_2
1_4
1_6
3_2
3_4
3_6
5_2
5_4
5_6
***** testHalf *****
1_4
1_5
1_6
2_4
2_5
2_6
3_4
3_5
3_6

【讨论】:

    【解决方案3】:

    下面的函数应该做你想做的事。它不打印结果,而是返回一个数组,其中包含您可以迭代并打印的结果。

    $testArray = array('1', '3', '4', '5');
    $testArray2 = array('1', '2', '3', '4', '5', '6');
    
    function test($a) {
      $from1 = array_shift($a);
      $to1 = array_shift($a);
    
      $result = array();
    
      while ($from1 <= $to1) {
        if (sizeof($a) > 0) {
          $rest = test($a);
          foreach ($rest as $b) {
            $result[] = $from1.'_'.$b;
          }
    
        } else {
          $result[] = $from1;
        }
        $from1++;
      }
      return $result;
    }
    
    print_r(test($testArray));
    print_r(test($testArray2));
    

    作为阅读递归的建议,因为它是一种非常有用的技术。有时很难理解它,但值得付出努力。如果我没记错的话,来自麻省理工学院的This book 有一个关于递归的精彩章节,而且它是免费的。玩得开心。

    【讨论】:

    • 修复它以做正确的事情(我希望)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多