1. 程式人生 > >'24點'編碼小感

'24點'編碼小感

此處的’24點’並不指午夜,而是一種遊戲~

引子

之前看到了一道四則運算相關的程式題,遂而想到了24點遊戲,覺得有趣,就想自己隨手編寫了一個,起初覺得應該比較簡單,但實際的路途卻並不平坦~

過程

最開始要解決的就是算式的求解問題(輸入字串形式的四則算式,返回算式結果),對於很多指令碼語言,都有內建的機制可以使用:
譬如 JS 中 eval, Lua 中的 load 等等,不過還是自己編碼開發一下更有趣味些,所以使用傳統的雙棧(運算元棧和運算子棧)演算法實現了一番,這裡有了第一點感悟:

  • 雖然可以完成基本的四則運算功能,但雙棧演算法卻缺乏錯誤檢測和處理的能力
    ,目前的實現中,對於某些非法輸入(譬如”6+(4-13-)9”),仍然可以正常運算並返回結果
  • 雙棧演算法的侷限性也很大,功能擴充套件比較困難(譬如擴充套件支援數學函式)
  • 更好的做法還是需要使用語法分析

可以解析求解四則運算之後,接下來的工作就是24點遊戲的”業務邏輯”了,首先要解決的一個問題是:
給定四個數字,判斷是否可以計算得到24(每個數字使用一次並僅使用一次)

窮舉四個數字間所有的四則運算方式就可以解決這個問題,由於問題規模較小,一般我們手寫幾個巢狀迴圈就能完成列舉,但是自己還是嘗試一般化了這裡的窮舉邏輯,於是有了第二點感悟:

  • 一般化的生成程式碼往往需要涉及遞迴相關邏輯,就目前的實現而言,由於不想儲存中間結果,我還不得不在遞迴中加入了回撥
  • 就24點而言,四則運算的窮舉包括兩個部分:運算數字間的排列以及運算子的新增(包括可能的括號),導致目前的實現中產生了遞迴中的雙重回調(回撥中包含回撥)
  • 雖然通用化的程式碼擴充套件性更好,但是條件允許的情況下,還是建議採取更簡單的特定化實現~

編碼過程中還出現了不少之前沒有預料到的問題:

  • 除零錯誤
  • 算式生成涉及大量字串操作,繁瑣且容易出錯
  • 遊戲邏輯因為需求的原因,很難去除耦合,分離介面

沒想小小一個遊戲,卻能折射出這麼多軟體工程的問題,這裡有了第三點感悟:

  • 無論專案大小,始終對程式設計保持敬畏之心吧~

最後讓我們來做做腦部體操,自己來算個24點吧:

11 3 12 5

(什麼?算不出24點?那就自己編個程式幫你算吧~)

  • gist上自己使用雙棧演算法實現的四則運算程式碼
  • 這裡有一篇關於雙棧演算法的描述