2009-08-25 63 views
2

我有一个函数,我用PHP编写的问题。正如你所看到的,函数使用它自己来返回值的数组。函数变成无限循环

public function getRepeat($day = "array") 
{ 
    if ($day == 'array') 
    {//Return an array with the repeated days as values 
     foreach (array(1,2,3,4,5,6,0) as $value) 
     { 
      if ($this->getRepeat($value)) 
      { 
       $returnArray[] = $value; 
      } 
     } 
     return $returnArray; 
    } 
    else if (in_array($day, array(1,2,3,4,5,6,0))) 
    { 
     if ($day == 1) 
      return $this->repeat1; 
     if ($day == 2) 
      return $this->repeat2; 
     if ($day == 3) 
      return $this->repeat3; 
     if ($day == 4) 
      return $this->repeat4; 
     if ($day == 5) 
      return $this->repeat5; 
     if ($day == 6) 
      return $this->repeat6; 
     if ($day == 0) 
      return $this->repeat0; 
    } 
} 

只要它自己调用以获得每个变量,它就会变成一个无限循环。

这是什么原因造成的?

+0

这不是真的递归 - 它只是一种砍死允许你可以调用一种方法来做两件事。 – pjp 2009-08-25 21:24:11

+0

编辑出递归部分。谢谢你的启发。 – 2009-08-25 21:33:41

回答

5

你必须总是分为两个部分觉得写一个递归函数:

  1. 基本情况 - 此时你停止递归并返回一个值(即是在列表为空)
  2. 递归案例 - 你如何再次调用函数,以及输入与以前的调用有什么不同(例如,你发送列表的尾部)

确保这两个规则保持应该导致递归函数终止因为输入是有效的。

这里有一个递归解决方案 - 但它是一个Java :)

public static void main(String[] args) { 

    List<Integer> testVals = new ArrayList<Integer>(); 
    testVals.add(0); 
    testVals.add(1); 
    testVals.add(2); 
    testVals.add(3); 
    testVals.add(4); 
    testVals.add(5); 

    List<Integer> toMatch = new ArrayList<Integer>(testVals); 

    List<Integer> matches = new ArrayList<Integer>(); 

    repeatRec(testVals, matches, toMatch); 

    System.out.println("Matches " + matches); 
} 

public static void repeatRec(List<Integer> toTest, List<Integer> matches, List<Integer> toMatch) { 


    if (toTest.isEmpty()) { 
     //we are done 
     return; 
    } else { 

     Integer head = toTest.get(0); 

     if (toMatch.contains(head)) { 
      matches.add(head); 

     } 

     //could have else here if we're only interested in the first match 
     repeatRec(toTest.subList(1, toTest.size()), matches, toMatch); 
    } 
} 
0

我可以建议也许是一个更好的解决方案是:

public function getRepeat($day = "array") 
{ 
    foreach (array(1,2,3,4,5,6,0) as $value) 
    { 
     $tmp = "repeat".$value; 
     if ($this->$tmp) 
     { 
      $returnArray[] = $value; 
     } 
    } 
    return $returnArray; 
} 

至于为什么你的函数没有结束,我我不确定。一般情况下我做你有两个单独的函数试图什么叫虽然,如:

public function getRepeat() 
{ 
       foreach (array(1,2,3,4,5,6,0) as $value) 
       { 
         if ($this->getRepeat_r($value)) 
         { 
           $returnArray[] = $value; 
         } 
       } 
       return $returnArray; 
} 
private function getRepeat_r($day) 
{ 
     if (in_array($day, array(1,2,3,4,5,6,0))) 
     { 
       if ($day == 1) 
         return $this->repeat1; 
       if ($day == 2) 
         return $this->repeat2; 
       if ($day == 3) 
         return $this->repeat3; 
       if ($day == 4) 
         return $this->repeat4; 
       if ($day == 5) 
         return $this->repeat5; 
       if ($day == 6) 
         return $this->repeat6; 
       if ($day == 0) 
         return $this->repeat0; 
     } 
} 

这使事情变得更容易阅读,除了更加稳定,只是柜面PHP解释的东西作为"array"当它不应该。

+1

事实上,这样的调用显然不是递归函数,除非repeat1/etc调用它,在这种情况下,我们确实需要查看该代码。 – 2009-08-25 21:23:27

+0

它不是递归的 – pjp 2009-08-25 21:24:46

+0

当您请求一天中的字符串回复时,您的第一个示例将不起作用。第二个例子还需要重写一天中的调用代码,除了带有_r的函数名称不是描述性的,这是可以的。 – OIS 2009-08-25 23:36:16

3

它真的很简单,当你想到它。

0 == 'any text which does not start with a number' 

您的最后一位数字0将导致无限循环。所以,你需要将其更改为

if ($day === 'array') 

编辑

我也冒昧地修复了代码:

/** 
* @obsolete 
*/ 
public function getRepeat($day = "array") 
{ 
    if ($day === 'array') { 
    return $this->getAllRepeat(); 
} 
    return $this->getRepeatByDay($day); 

} 

public function __construct() 
{ 
    $this->repeat = array_fill(0, 7, ''); 
} 

public function getAllRepeat() 
{ 
    return $this->repeat; 
} 

public function __get($value) { 
    switch ($value) { 
     case 'repeat0': 
     case 'repeat1': 
     case 'repeat2': 
     case 'repeat3': 
     case 'repeat4': 
     case 'repeat5': 
     case 'repeat6': 
      return $this->getRepeatByDay(intval(substr($value, -1, 1))); 
    } 
} 

public function getRepeatByDay($day) 
{ 
    if (!isset($this->repeat[$day])) { 
     return null; 
    } 
    return $this->repeat[$day]; 
} 
+0

哇,这是一个棘手的“功能”。 OIS为+1,PHP为-1 – 2009-08-26 19:15:35