這次的程式改用了樹的結構儲存,優化了表示式生成方式,並完善了查重功能
資料結構基礎溫故-4.樹與二叉樹(下)
從字尾表示式建立表示式樹
由於從中序表示式(也就是正常的表示式)轉換成樹結構式在括號的處理上有點麻煩。所以將表示式轉換為後序表示式再轉成樹結構,就可以不去處理括號。
根據運算子個數迴圈生成表示式:
每次生成乙個基礎數符對:`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)
原版題目:四則運算題目生成程式
第一次作業由於都是自己從無到有寫出來的,沒有參考已有的好的思路與方法,所以時間花費較多。並且在查重方面沒有很好的處理。
優化的表示式生成方式也是在看了別人的思路下想到的。
別人的思路:小學生終結者——四則運算生成器 利用二叉樹計算四則運算表示式
先做個簡單實現,沒有括號,所有數字都是個位數 主要思路如下 例如有這樣乙個四則運算表示式 2 3 4 2 3 1 先將其分成兩部分的和 2 3 4 2 3 1 號作為二叉樹的根,左右兩部分分別作為二叉樹根的左右子樹 再依次遞迴的分下去。最終將其轉化為下面這樣的一棵樹 計算時,使用二叉樹的後續遍歷,先...
python四則運算程式 四則運算(Python)
四則運算程式 一 資訊 二.題目要求 寫乙個能自動生成小學四則運算題目的程式,然後在此基礎上擴充套件 除了整數以外,還要支援真分數的四則運算,例如 1 6 1 8 7 24 程式要求能處理使用者的輸入,判斷對錯,累積分數 程式支援可以由使用者自行選擇加 減 乘 除運算 三 import random...
java四則運算
public class arithmetic implements serializable 除法 param number1 除數 param number2 被除數 param decimal 保留幾位小數點 return public static double divide string ...