script (⏱,💰)

script (⏱,💰)

NG#2 - 二叉樹

沒有完成入門任務的參考安裝入門

Puzzling Pyramids 是 Cairo 的 數據結構與算法任務 Think Cairo 的第二篇,主要解決二叉樹問題,共有兩個小題。

中序 DFS#

pyramids_02_cd51837de0

如圖需要把二叉樹從左到右轉換為列表,稍微懂算法就知道是中序的 DFS (深度優先搜索),可以在互聯網上搜到很多解析。

在實際寫 cairo 代碼時,當遇到該如何定義空 array,如何索引等問題,可以參考 https://book.cairo-lang.org/ch03-01-arrays.html

lower_chambers 是 Option 類型,不知道如何操作 Option 類型可參考 https://book.cairo-lang.org/ch06-02-the-match-control-flow-construct.html?highlight=Option#matching-with-options

這個問題可用非遞歸的方式解決,也可用遞歸方式來解決。由於 cairo 的 array 內置函數不夠(寫上一個任務應該能感受到),實際寫起來會更麻煩。所以建議用遞歸來寫。

可先看看官方的 fib 的遞歸版本,道理是一樣的 https://github.com/starkware-libs/cairo/blob/main/examples/fib_array.cairo

遞歸函數實現每個節點執行 "判斷並遞歸左葉 -> 添加節點 -> 判斷並遞歸右葉" 的邏輯。

有幾個重點:

  • 遞歸需要把元素 append 到列表裡,該列表需要加上 ref 關鍵字,在遞歸中會引用同一個 array。
  • 遞歸函數也需要實現 Clone和 Drop,寫法和 PyramidIntoArray 中一樣。但 GitHub 庫裡的 cairo 新版本寫法有點不同。
  • chambers 先轉成 snapshot,就可以多次引用不會導致所有權問題。再用 clone 轉回原來的類型,append 進列表裡。
  • 如果測試不通過,可用 use debug::PrintTrait;[變量].print(); 去 debug

搜索路徑#

puzzling_pyramids_04_683fbd4b56

第二小題需要實現搜索路徑,同樣是 DFS,但比第一題要難寫得多。

測試用例如下,尋找 k,需要返回 [h,l,j,k]

         h
   d           l
 b    f     j     n
a c  e g   i k   m o

同樣還是遞歸解決,建一個列表用於存儲結果,調用遞歸函數,遞歸函數需要實現每個節點執行:

  1. 任意一個節點,如果值就是 key,就返回 index
  2. 如果值不是 key,就查 left 和 right,進行遞歸,返回 array,或者返回 None
  3. 拿到子葉遞歸返回的 array,append 上當前 index

例如上面測試用例的 j 進行遞歸,得到 Option::None[k].append(j),返回到 l 節點就是 [k,j].append(l)Option::None,返回到 h 就是 [k,j,l].append(h)。(以上都需要換成 index 操作,原因見下面的注意事項)

由於 cairo 不支持 append_front,只能往後面 append,最後寫個 loop 翻轉得到的路徑 array

注意事項:

總結#

ng3_result

如果算法基礎不好,任務還是挺難的。一開始我用的非遞歸方法,最終遇到了 ref array 的循環賦值語言層面報錯 bug。後來編寫遞歸,也遇到了很多語法問題,寫了很久才完成,收穫很大。希望以上思路對你有幫助。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。