国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

遞歸算法造成的問題分析與解決

gekylin / 1773人閱讀

摘要:整理一下,形成今天的內(nèi)容算法中的遞歸算法。解決來看一下,最終形態(tài)的遞歸方法是什么樣子遞歸運(yùn)算創(chuàng)建樹結(jié)構(gòu)聲明靜態(tài)變量給靜態(tài)變量累加值賦值閉合標(biāo)簽這樣就可以解決了。所以,在之后的遞歸算法中,應(yīng)該小心謹(jǐn)慎,避免出現(xiàn)問題。

原文是在我自己博客中,小伙伴也可以點(diǎn)閱讀原文進(jìn)行跳轉(zhuǎn)查看,還有好聽的背景音樂噢~

????遞歸,在編碼中應(yīng)該算是一種很常見的算法了。之前在學(xué)習(xí)C語言的時(shí)候,也同樣了解過一些基本的算法,比如斐波那契。在學(xué)習(xí)的時(shí)候,對(duì)算法這種編程技巧就有了一種濃濃的敬畏之心,因?yàn)橛X得會(huì)算法的人就很厲害了,可以把很長(zhǎng)的代碼塊通過一段簡(jiǎn)短的算法解決并得到想要的結(jié)果。

今天在實(shí)際工作中也遇到了算法中一些問題。整理一下,形成今天的內(nèi)容【算法中的遞歸算法】。

什么是遞歸

借用百科的一段話來表述就是:

一個(gè)過程或函數(shù)在其定義或說明中有直接或間接調(diào)用自身的一種方法。
遞歸的能力

同樣引用百科的一句話,個(gè)人覺得非常經(jīng)典:

用有限的語句來定義對(duì)象的無限集合;

這句話什么意思呢,通俗點(diǎn)來理解就是,我程序只有一套,但是我可以通過遞歸(自身調(diào)用自身)的特性,不管你有多少個(gè)值,我都能妥妥的給你按照特定的程序邏輯處理嘍。(就是這么強(qiáng)勢(shì),嘿嘿!)

自己之前對(duì)遞歸的理解就是自己調(diào)用自己,通過多次的自己調(diào)用自身,通過同一套程序方法,來達(dá)到解決問題的目的;這種方法可以明顯的減少代碼量,而且靈活,尤其是在多重循環(huán)的時(shí)候,可以采用遞歸來替代。但是這種方法也有缺點(diǎn),就是增加了程序了運(yùn)行速度,而且有時(shí)候可能會(huì)因?yàn)榫幋a不當(dāng),造成死循環(huán)、棧溢出等問題。但是只要用好,解決問題還是不差的;

問題所在

今天在工作中,遇到一個(gè)把無限分類的多維數(shù)組轉(zhuǎn)換成html樹的時(shí)候,就遇到了點(diǎn)小麻煩,可能是因?yàn)橐粫r(shí)馬虎,當(dāng)局者迷的緣故,自己就像掉進(jìn)死循環(huán)里,一直出不來,后來,也是在請(qǐng)教身邊的朋友后,才得到解決,下面我們來看一下出現(xiàn)了什么問題(其實(shí)問題已經(jīng)提在了SF社區(qū)上,問題標(biāo)題是多維數(shù)組分類樹 組合html樹的問題?(遞歸),有興趣的小伙伴可以去看下):

數(shù)組結(jié)構(gòu)

最初的數(shù)組結(jié)構(gòu)是一個(gè)無限分類的多維數(shù)組:

由上圖可以看到,這個(gè)數(shù)組的childs下標(biāo)里面對(duì)應(yīng)的就是子分類,分類可以有無限個(gè)。我們要把它組裝成下圖的理想形態(tài):

雖然看著很簡(jiǎn)單,但是實(shí)際上走了不少彎路,最后卡在了一個(gè)點(diǎn)上,始終沒出來。我最開始的遞歸方法是:

問題代碼
function creatHtmlTree($tree)
{
    // 生命一個(gè)靜態(tài)變量
    static $htmlTree;
    $htmlTree .= "
    "; foreach ($tree as $key => $value) { $htmlTree .= "
  • {$value["name"]} Goes somewhere"; if (isset($value["childs"]) && is_array($value["childs"])) { // 每次的結(jié)果累加到靜態(tài)變量上 $html = creatHtmlTree($value["childs"]); $htmlTree .= $html; } $htmlTree .= "
  • "; } $htmlTree .= "
"; return $htmlTree; }

通過測(cè)試得到了下圖的錯(cuò)誤內(nèi)容:

問題分析

我們可以看到,它給$htmlTree這個(gè)變量給了多余的值,通過求教才明白,我的代碼中

static $htmlTree;
$htmlTree .= "
    ";

以及if里的

$html = creatHtmlTree($value["childs"]);
$htmlTree .= $html;

代碼邏輯寫的有問題,問題在于,既然設(shè)定了$htmlTree為靜態(tài)變量,那么在遞歸中的每一次計(jì)算中,都默認(rèn)已經(jīng)$htmlTree賦予了最后的計(jì)算結(jié)果,我在if里又把結(jié)果加了一次,所以才造成了輸出出現(xiàn)問題的情況,那么如何改成呢?只需把:

$html = creatHtmlTree($value["childs"]);
$htmlTree .= $html;

改為:

creatHtmlTree($value["childs"]);

即可。這樣,他在遞歸運(yùn)算的時(shí)候就可以通過

$htmlTree .= "
    "; $htmlTree .= "
  • {$value["name"]} Goes somewhere"; $htmlTree .= "
  • "; $htmlTree .= "
";

這四行代碼來給$htmlTree累加數(shù)值就可以了。

解決

來看一下,最終形態(tài)的遞歸方法是什么樣子:

// 遞歸運(yùn)算創(chuàng)建html樹結(jié)構(gòu)
function creatHtmlTree($tree)
{
    // 聲明靜態(tài)變量
    static $htmlTree;
    $htmlTree .= "
    "; foreach ($tree as $key => $value) { // 給靜態(tài)$htmlTree變量累加值 $htmlTree .= "
  • {$value["name"]} Goes somewhere"; if (isset($value["childs"]) && is_array($value["childs"])) { creatHtmlTree($value["childs"]); } $htmlTree .= "
  • "; } // 賦值ul閉合標(biāo)簽 $htmlTree .= "
"; return $htmlTree; }

這樣就可以解決了。同樣還有另外一種方式,那就是通過返回值的方式,來進(jìn)行遞歸運(yùn)算:

// 遞歸運(yùn)算創(chuàng)建html樹結(jié)構(gòu)
function creatHtmlTree($tree)
{
    // $htmlTree為普通局部變量;
    $htmlTree .= "
    "; foreach ($tree as $key => $value) { // 給變量$htmlTree累加值 $htmlTree .= "
  • {$value["name"]} Goes somewhere"; if (isset($value["childs"]) && is_array($value["childs"])) { // 遞歸中每次的結(jié)果累加到$htmlTree $htmlTree .= creatHtmlTree($value["childs"]); } $htmlTree .= "
  • "; } // 賦值ul閉合標(biāo)簽 $htmlTree .= "
"; return $htmlTree; }

通過這種返回值累加的算法,也同樣可以得到想要的結(jié)果。

測(cè)試

今天為了測(cè)試和解決遞歸算法帶來的問題,特意找了段代碼進(jìn)行測(cè)試,也是我下午一直在實(shí)驗(yàn)的demo,手癢癢的小伙伴,可以立馬copy到本地親自體驗(yàn)一下:

1,"parentid"=>0,"name"=>"中國"],
    ["id"=>2,"parentid"=>0,"name"=>"美國"],
    ["id"=>3,"parentid"=>0,"name"=>"韓國"],
    ["id"=>4,"parentid"=>1,"name"=>"北京"],
    ["id"=>5,"parentid"=>1,"name"=>"上海"],
    ["id"=>6,"parentid"=>1,"name"=>"廣西"],
    ["id"=>7,"parentid"=>6,"name"=>"桂林"],
    ["id"=>8,"parentid"=>6,"name"=>"南寧"],
    ["id"=>9,"parentid"=>6,"name"=>"柳州"],
    ["id"=>10,"parentid"=>2,"name"=>"紐約"],
    ["id"=>11,"parentid"=>2,"name"=>"華盛頓"],
    ["id"=>12,"parentid"=>3,"name"=>"首爾"],
];


 /**格式化數(shù)組輸出**/
function p($arr)
{
    echo "
";
    echo "========================開始========================";
    echo "
"; if( $arr ){ print_r($arr); } else { echo "此值為空"; } echo "
"; echo "========================結(jié)束========================"; echo "
"; } /** * 多維數(shù)組樹形結(jié)構(gòu) */ function tree($data, $pid = 0) { $children = []; foreach ($data as $key => $value) { if ($value["parentid"] == $pid) { $children[] = $value; } } if (empty($children)) { return null; } foreach ($children as $key => $value) { $chid = tree($data, $value["id"]); if ($chid != null) { $children[$key]["childs"] = $chid; } } return $children; } // 遞歸運(yùn)算創(chuàng)建html樹結(jié)構(gòu) function creatHtmlTree($tree) { // $htmlTree為普通局部變量; $htmlTree .= "
    "; foreach ($tree as $key => $value) { // 給$htmlTree變量累加值 $htmlTree .= "
  • {$value["name"]} Goes somewhere"; if (isset($value["childs"]) && is_array($value["childs"])) { // 遞歸中每次的結(jié)果累加到$htmlTree $htmlTree .= creatHtmlTree($value["childs"]); } $htmlTree .= "
  • "; } // 賦值ul閉合標(biāo)簽 $htmlTree .= "
"; return $htmlTree; } $tree = tree($data); $htmlTree = creatHtmlTree($tree); p($tree); p($htmlTree);
總結(jié)

算法,這門技巧,是我向往的高級(jí)玩意兒。覺得它挺炫的,在開頭我就有提到,可以用極短的代碼解決復(fù)雜的業(yè)務(wù)程序,大大減少的代碼量。但它同樣也像一顆隱形炸彈一樣,也充滿著威脅。所以,在之后的遞歸算法中,應(yīng)該小心謹(jǐn)慎,避免出現(xiàn)問題。

好了,今天就分享到這里,以上。

補(bǔ)充

在百科里看到遞歸解釋的兩句話,也同樣經(jīng)典,奉上:

遞歸需要有邊界條件、遞歸前進(jìn)段和遞歸返回段

當(dāng)邊界條件不滿足時(shí),遞歸前進(jìn);當(dāng)邊界條件滿足時(shí),遞歸返回

這大概說的就是遞歸的運(yùn)行條件吧。
完。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/26306.html

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)和算法類面試題javascript代碼實(shí)現(xiàn)

    摘要:正文面試題重建二叉樹題目輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果,請(qǐng)重建出該二叉樹。前序遍歷序列為,中序遍歷序列,。確定了左右子樹后遞歸處理。方法方法面試題在時(shí)間刪除鏈表結(jié)點(diǎn)。 寫在前面 本文的題目均來自于劍指offer中的題目,題目序號(hào)保持了書中的題目序號(hào),由于某些題目并不適合于javascript這種語言,所以這些題目就沒有寫在本篇博客中,因此會(huì)出現(xiàn)題目序號(hào)的中斷。 正文 面試題6:...

    Dean 評(píng)論0 收藏0
  • 數(shù)據(jù)結(jié)構(gòu)算法之精講「遞歸系列」

    摘要:終止條件遞推公式遞歸的分類通過做大量的題,根據(jù)遞歸解決不同的問題,引申出來的幾種解決和思考的方式。我們通過層與層之間的計(jì)算關(guān)系用遞推公式表達(dá)出來做計(jì)算,經(jīng)過層層的遞歸,最終得到結(jié)果值。 showImg(https://segmentfault.com/img/remote/1460000019222330); 前言 幾個(gè)月之前就想寫這樣一篇文章分享給大家,由于自己有心而力不足,沒有把真...

    zhichangterry 評(píng)論0 收藏0
  • 算法系列——JavaScript中廣度優(yōu)先搜索思想實(shí)現(xiàn)

    摘要:散列表上面的地圖向我們展示了如何用廣度優(yōu)先搜索的思想找到北京到廣州的最短路線。在廣度優(yōu)先搜索中,我們需要用到隊(duì)列的這種思想來實(shí)現(xiàn)查找。建立了下面這個(gè)模型武漢廣州西藏上海上海武漢廣州代碼完整實(shí)現(xiàn),利用遞歸和廣度優(yōu)先搜索的思想實(shí)現(xiàn)。 什么是廣度優(yōu)先搜索? 如果只是是背概念,幼兒園的小朋友都能背下來念給你聽。 假設(shè)看這篇文章的都和我一樣是個(gè)前端工程師,我們要從廣度優(yōu)先搜索(BFS)中學(xué)到什么...

    everfly 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<