代码之家  ›  专栏  ›  技术社区  ›  VirtuosiMedia

PHP中递归方法的优化

  •  2
  • VirtuosiMedia  · 技术社区  · 14 年前

    我正在编写一个文本标记分析器,目前我正在使用此递归方法创建 n 话。有没有一种方法可以做到非递归或至少是优化?假设$this->dataarray可能是一个非常大的数组。

    /**
     * A recursive function to add phrases to the tagTracker array
     * @param string $data
     * @param int $currentIndex
     * @param int $depth
     */ 
    protected function compilePhrase($data, $currentIndex, $depth){
        if (!empty($data)){
            if ($depth >= $this->phraseStart){
                $this->addDataCount($data, $depth);
            }
            if ($depth < $this->phraseDepth){
                $currentIndex = $currentIndex + 1;
                //$this->dataArray is an array containing all words in the text
                $data .= ' '.$this->dataArray[$currentIndex]; 
                $depth += 1;
                $this->compilePhrase($data, $currentIndex, $depth);
            }
        }
    }
    
    1 回复  |  直到 14 年前
        1
  •  3
  •   Aiden Bell    14 年前

    看看你能不能用 tail recursion 而不是基于调用的递归。可能需要进行一些重写,但粗略地看一下就可以了。

    尾部递归对于递归函数的一个子集来说是很好的,并且很好的实践是发现循环何时可以替换递归,以及如何重写。

    这么说,我不知道PHP内部调用的开销是什么。可能只是一个返回指针类型的设置,而不是真正的堆栈风。

    结果差不多。PHP优化tail递归调用本身吗?

    这是我的重写本,但请注意,我的大脑目前睡眠不足!

    protected function compilePhrase($data, $currentIndex, $depth){
        /* Loop until break condition */
        while(true) {
            if (!empty($data)){
                if ($depth >= $this->phraseStart){
                    $this->addDataCount($data, $depth);
                }
                if ($depth < $this->phraseDepth){
                    $currentIndex = $currentIndex + 1;
                    // A test here might be better than the !empty($data)
                    // in the IF condition. Check array bounds, assuming
                    // array is not threaded or anything
                    $data .= ' '.$this->dataArray[$currentIndex]; 
                    $depth += 1;
                }else{
                   break;
                }
            }else{
               break;
            }
        }
        /* Finish up here */
        return($this->dataArray);
    }