四則運算——二叉樹
題目在這:個人作業1——四則運算題目生成程序(基於控制台)
第一次作業:個人作業——四則運算
這次的程序改用了樹的結構保存,優化了表達式生成方式,並完善了查重功能
程序設計基礎
由於從中序表達式(也就是正常的表達式)轉換成樹結構式在括號的處理上有點麻煩。所以將表達式轉換為后序表達式再轉成樹結構,就可以不去處理括號。
表達式生成
根據運算符個數循環生成表達式:
每次生成一個基礎數符對:`Num`+`Operator`
根據隨機數判斷是否生成括號與括號的位置
1.沒有括號:`原表達式`+`Num`+`Operator`
2.括號在當前表達式后面:`原表達式`+`(`+`Num`+`Operator`,括號計數器加1
3.括號在表達式前面:`(`+`原表達式`+`Num`+`Operator`,括號計數器加1
判斷當前表達式是否存在為配對的括號
若括號計數器不為零
1.需要加:`原表達式`+`Num`+`)`+`Operator`,括號計數器減1
2.不加:`原表達式`+`Num`+`Operator`
循環結束時判斷括號對是否匹配完全
若括號計數器不為零
循環在表達式末尾加上`)`;
由於基礎數符對為`Num`+`Operator`的形式,在循環結束時需要去掉末尾多余的一個Operator
判斷是否存在包裹整個表達式的括號,即括號對內長度是否等於表達式長度(不算括號),若存在則去除表達式兩端的括號,再次判斷。
二叉式生成
具體生成方式參考上面的程序設計基礎,我在樹的類中加上的代表運算結果的值`value`,用來存放當前樹的運算結果。
當生成節點的對象為一個`Num`的時候,節點的值就位`Num`本身。
當對象為一個`Operator`的時候,節點的值為左右子樹進行當前運算符運算后的結果,即`value Op value`
當表達式掃描完成,計算過程也就結束了,最后根節點的值就是表達式的運算結果。
查重方式
由於采用了二叉樹的結構存放表達式,所以可以再二叉樹生成的時候將樹根據一點規則判斷左右子樹的對象
若生成節點的對象是`*`或者`+`
1.左右子樹的值不同,則值大的作為左子樹
2.左右子樹的值相同時,判斷子樹的運算符優先級大小,優先級大的作為左子樹
3.運算符優先級相同,判斷子樹下的左子樹值得大小,值大的作為左子樹
4.若為子樹為一個為數字,一個為運算符,則運算符作為左子樹
5.若左右子樹都為數字,則值大的作為左子樹
根據這個規則,基本上包含了交換律可能出現的情況,將可以有交換律變換得到的表達式都轉為一個統一的表達式,在根據檢查已生成的表達式樹的結構,若存在重復的就放棄當前表達式,重新生成並查重。
在這個規則下
3+2+1 與 3+1+2 兩個表達式不是重復的表達式
因為不能再有限次的交換律加成為相同的表達式。
這個具體說明在原版的題目中
程序測試
表達式生成測試

表達式查重測試:(3+2)x(4+1) 與 (4+1)x(2+3)

原版題目:四則運算題目生成程序
代碼已上傳至Coding
Coding地址
https://coding.net/u/w2197525161/p/jisuan/git/tree/master/
個人想法
第一次作業由於都是自己從無到有寫出來的,沒有參考已有的好的思路與方法,所以時間花費較多。並且在查重方面沒有很好的處理。
這次的程序是在老師建議下采用了二叉樹的結構存放表達式用來解決表達式查重問題,認識到了參考的作用。很多難點已經有了各種解決方式,通過收集與整理,加上自己的理解可以更好的完成現有的任務。
優化的表達式生成方式也是在看了別人的思路下想到的。
附:
別人的思路:小學生終結者——四則運算生成器
