小學生四則運算應用軟件(二)

1、針對上週的程序改進:

(1)除零問題:生成題目的時候同時計算,try catch異常,如有異常則從新生成

測試用例爲2/(2-2),以下會產生分母不該爲0的異常java

這裏的FractionException有多種類型,好比分母不能爲0、計算時超出數值範圍、沒法轉化爲Fraction等。算法

(2)參數化和用戶輸入異常處理:

     參數化是直接使用C#主函數的String[] args,而且針對每種錯誤狀況都要拋出相應異常,也是使用的try catch機制,其代碼以下:express

  1  static void Main(string[] args)
  2         {
  3             Console.WriteLine("-n表示生成四則算式的數目");
  4             Console.WriteLine("-a表示用戶是否輸入答案(1輸入,0不輸入)");
  5             Console.WriteLine("-c表示是否顯示正確答案(1顯示,0不顯示)");
  6             Console.WriteLine("-t表示是否生成題目文件(1生成,0不生成)");
  7             Console.WriteLine("-m表示文件生成題目的數量(若生成題目文件該參數必須輸入,不然不輸入)");
  8             try
  9             {
 10                 if (args.Length != 8 && args.Length != 10)
 11                     throw new Exception("參數數目不正確");
 12                 else if (args.Length == 8)
 13                 {
 14                     if (args[0] != "-n" || args[2] != "-a" || args[4] != "-c" || args[6] != "-t")
 15                         throw new Exception("參數名稱不正確");
 16                     if (int.Parse(args[1]) <= 0)
 17                         throw new Exception("題目數必須爲正");
 18                     if (int.Parse(args[7]) == 1)
 19                         throw new Exception("參數數目不正確");
 20                     if ((int.Parse(args[3]) != 0 && int.Parse(args[3]) != 1) ||
 21                             (int.Parse(args[5]) != 0 && int.Parse(args[5]) != 1))
 22                         throw new Exception("參數值必須爲0或1");
 23                 }
 24                 else
 25                 {
 26                     if (args[0] != "-n" || args[2] != "-a" || args[4] != "-c" || args[6] != "-t" || args[8] != "-m")
 27                         throw new Exception("參數名稱不正確");
 28                     if (int.Parse(args[1]) <= 0 || int.Parse(args[9]) <= 0)
 29                         throw new Exception("題目數必須爲正");
 30                     if (int.Parse(args[7]) == 0)
 31                         throw new Exception("參數數目不正確");
 32                     if ((int.Parse(args[3]) != 0 && int.Parse(args[3]) != 1) ||
 33                             (int.Parse(args[5]) != 0 && int.Parse(args[5]) != 1))
 34                         throw new Exception("參數值必須爲0或1");
 35                 }
 36 
 37                 int numOfQue = int.Parse(args[1]);
 38                 string[] inputAnswer = new string[numOfQue];
 39                 string[] correctAnswer = new string[numOfQue];
 40                 string[] ques = new string[numOfQue];
 41                 List<string> result = new List<string>();
 42                 for (int i = 0; i < numOfQue; i++)
 43                 {
 44 
 45                     result = produceQue();
 46                     ques[i] = result[0];
 47                     try
 48                     {
 49                         correctAnswer[i] = Calculate(result);
 50                         Console.WriteLine("{0,-20}", ques[i] + operators[4] + space);
 51                     }
 52                     catch (FractionException e)
 53                     {
 54                         i--;
 55                     }
 56                 }
 57                 Console.WriteLine();
 58                 int input = int.Parse(args[3]);
 59                 if (input == 1)
 60                 {
 61                     Console.Write("輸入答案: ");
 62                     for (int i = 0; i < numOfQue; i++)
 63                     {
 64                         Console.Write("{0,-20}", ques[i] + operators[4] + space);
 65                         inputAnswer[i] = Console.ReadLine();
 66                     }
 67 
 68                     int numOfCorrect = 0;
 69                     for (int i = 0; i < numOfQue; i++)
 70                     {
 71                         if (inputAnswer[i] == correctAnswer[i])
 72                             numOfCorrect++;
 73                     }
 74                     Console.WriteLine("您共答對" + numOfCorrect + "道題");
 75                 }
 76                 input = int.Parse(args[5]);
 77                 if (input == 1)
 78                 {
 79                     Console.Write("正確答案: ");
 80                     for (int i = 0; i < numOfQue; i++)
 81                         Console.Write("{0,-20}", ques[i] + operators[4] + space + correctAnswer[i]);
 82                     Console.WriteLine();
 83                 }
 84 
 85                 input = int.Parse(args[7]);
 86                 if (input == 1)
 87                 {
 88                     string filename = "que.txt";//這裏是你的已知文件
 89                     FileStream fs = File.Create(filename);  //建立文件
 90                     fs.Close();
 91                     StreamWriter sw = new StreamWriter(filename);
 92                     input = int.Parse(args[9]);
 93                     for (int i = 0; i < input; i++)
 94                     {
 95                         string que = "";
 96                         que = produceQue()[0];
 97                         sw.Write("{0,-20}", que + operators[4] + space);
 98                         if (i % 10 == 9)
 99                             sw.Write("\r\n");
100                     }
101                     sw.Close();
102                 }
103             }
104             catch (Exception e)
105             {
106                 Console.WriteLine(e.Message);
107                 Console.WriteLine("請輸入正確參數");
108             }
109         }
View Code

其中參數說明爲:編程

測試用例及結果如圖所示:數組

這是目前考慮的參數問題,固然咱們也能夠添加更多的參數,例如生成四則運算表達式運算符的數目以及操做數的範圍。數據結構

(3)括號交叉重疊的問題:

      目前括號的功能是經過隨機生成(、)位於第幾個操做數來實現,但這樣可能會出現這種狀況(2*(4)+3)。即第一對括號是(2*4),第二對括號是(4+3),處理的方法是若是同一個操做數先後分別有左括號和右括號,就將這兩括號省略不添加。部分代碼截圖以下:app

(4)代碼優化及擴展:

        因爲最後是想將該應用以網頁(Java Web)的形式顯示,所以檢查重複問題、優化等都是在Java程序的基礎上改進。目前是已經將程序的主要功能經過Python、Java實現了,那麼就淺談下代碼的轉變之路。dom

2、C#轉Python---Python功能強大之處

      Python編程速度快,有不少強大的第三方庫,還能夠有負索引獨特的語法,無數據類型的嚴格限制...種種優勢促成了Python已然成爲了當前社會下十分流行的語言。ide

      簡單舉個例子,在C#辛辛苦苦寫的Fraction類,Python裏只需from fractions import Fraction這樣一句話就能夠搞定(o(╯□╰)o,獨自在風中凌亂會兒)。而無數據類型的嚴格限制,使得咱們不必檢查類型轉化的錯誤,甚至能夠在一個List裏添加多種數據類型的元素。固然負索引的出現,也能讓咱們直接將List轉化成棧和隊列的這種結構。再加上Python代碼的嚴格縮進,又會讓代碼風格整齊美觀,這些怎能不令程序猿爲之欣喜若狂?廢話很少說,直接上代碼:函數

  1 from fractions import Fraction
  2 import random
  3 input0 = 1
  4 operators = "+-*/="
  5 space = " "
  6 priorities = {"#": -1, "+": 0, "-": 0,"*":1,"/":1}
  7 def produceQue():
  8     strque = []
  9     isOperand = []
 10     count = random.randint(1, 2)
 11     num = []
 12     den = []
 13     operand = []
 14     index = []
 15     numOfBrackets = 0
 16     for i in range(count + 1):
 17         num.append(random.randint(2, 4))
 18         if random.randint(1, 10) < 8:
 19             den.append(1)
 20         else:
 21             den.append(random.randint(1, 4))
 22             numOfBrackets = random.randint(1, count)
 23         operand.append(Fraction(num[i], den[i]))
 24         if i < count:
 25             index.append(random.randint(0, 3))
 26     start = []
 27     end = []
 28     for i in range(numOfBrackets):
 29         start.append(random.randint(1, count))
 30         end.append(random.randint(start[i]+1, count + 1))
 31     for i in range(len(start)):
 32         for j in range(len(end)):
 33             if start[i] == end[j]:
 34                 start.pop(i)
 35                 end.pop(j)
 36                 start.append(-1)
 37                 end.append(-1)
 38     j = 1
 39     for i in range(count + 1):
 40         strque.append(str(operand[i]))
 41         isOperand.append(i + 1)
 42         if i < count:
 43             strque.append(operators[index[i]])
 44             isOperand.append(0)
 45     for i in range(numOfBrackets):
 46         if start[i] != -1:
 47           left = isOperand.index(start[i])
 48           strque.insert(left, "(")
 49           isOperand.insert(left, -1)
 50         if end[i] != -1:
 51           right = isOperand.index(end[i])
 52           strque.insert(right+1, ")")
 53           isOperand.insert(right+1, -1)
 54     strque.insert(0, "")
 55     j = 1
 56     while j < len(strque):
 57         strque[0] += strque[j] + space
 58         j = j + 1
 59     return strque
 60 
 61 def Compute(leftNum,rightNum,op):
 62     if op == 0:
 63         return Fraction(leftNum)+Fraction(rightNum)
 64     if op == 1:
 65         return Fraction(leftNum)-Fraction(rightNum)
 66     if op == 2:
 67         return Fraction(leftNum)*Fraction(rightNum)
 68     if op == 3:
 69         return Fraction(leftNum)/Fraction(rightNum)
 70 
 71 def IsOperator(op):
 72     try:
 73         i = operators.index(str(op))
 74         bo = True
 75     except:
 76         bo = False
 77     finally:
 78         return bo
 79 
 80 def IsLeftAssoc(op):
 81     if op == "+" or op == "-" or op == "*" or op == "/":
 82         return True
 83     else:
 84         return False
 85 
 86 
 87 def PreOrderToPostOrder(expression):
 88     result = []
 89     operatorStack = []
 90     operatorStack.append("#")
 91     top = ""
 92     cur = ""
 93     tempChar = ""
 94     tempNum = ""
 95     i = 1
 96     while i < len(expression):
 97         cur = expression[i]
 98         top = operatorStack[-1]
 99         if cur == "(":
100             operatorStack.append(cur)
101         else:
102             if(IsOperator(cur)):
103                 while IsOperator(top) and (IsLeftAssoc(cur) and priorities[cur] <= priorities[top]) or (not IsLeftAssoc(cur) and priorities[cur] < priorities[top]):
104                    result.append(operatorStack.pop())
105                    top = operatorStack[-1]
106                 operatorStack.append(cur)
107             elif cur == ")":
108                 tempChar = operatorStack.pop()
109                 while len(operatorStack) > 0 and   tempChar != "(":
110                     result.append(tempChar)
111                     tempChar = operatorStack.pop()
112             else:
113                 tempNum = cur
114                 result.append(tempNum)
115         i = i + 1
116 
117     while len(operatorStack) > 0:
118         cur = operatorStack.pop()
119         if cur == "#":
120             continue;
121         if len(operatorStack) > 0:
122             top = operatorStack[-1]
123         result.append(cur)
124     return result
125 
126 def Calculate(expression):
127     rpn = PreOrderToPostOrder(expression)
128     operandStack = []
129     left = ""
130     right = ""
131     while len(rpn) > 0:
132         cur = rpn.pop(0)
133         if IsOperator(cur):
134             right = operandStack.pop()
135             left = operandStack.pop()
136             index = operators.index(cur)
137             operandStack.append(Compute(left,right,index))
138         else:
139             operandStack.append(cur)
140     return operandStack.pop()
141 
142 while input0 == 1:
143     print("請輸入生成四則運算題的數目:")
144     numOfQue = int(input())
145     inputAnswer = []
146     correctAnswer = []
147     ques = []
148     result =[]
149     for i in range(numOfQue):
150        result = produceQue()
151        ques.append(result[0])                       print(result[0]+space+operators[4]+space+str(Calculate(result)))
View Code

測試用例以下:

3、C#轉Java---一切只爲了網頁顯示

       很不幸Java也沒有Fraction類,那就本身寫唄,主要功能實現以下:

  1 public class Fraction {    
  2         long m_iNumerator;
  3         long m_iDenominator;
  4         
  5         
  6         public Fraction() throws Exception
  7         {
  8             Initialize(0,1);
  9         }
 10     
 11         public Fraction(long iWholeNumber) throws Exception
 12         {
 13             Initialize(iWholeNumber, 1);
 14         }
 15         
 16         public Fraction(String strValue) throws Exception
 17         {
 18             Fraction temp=ToFraction(strValue);
 19             Initialize(temp.getNumerator(), temp.getDenominator());
 20         }
 21         
 22         public Fraction(long iNumerator, long iDenominator) throws Exception
 23         {
 24             Initialize(iNumerator, iDenominator);
 25         }
 26         private void Initialize(long iNumerator, long iDenominator) throws Exception
 27         {
 28             this.setNumerator(iNumerator);
 29             this.setDenominator(iDenominator);
 30             ReduceFraction(this);
 31         }
 32     
 33     
 34         
 35         public long getNumerator()
 36         {
 37             return m_iNumerator;    
 38         }
 39         public void setNumerator(long Numerator)
 40         {
 41             m_iNumerator = Numerator;    
 42         }
 43         public long getDenominator() throws Exception
 44         {
 45             if(m_iDenominator != 0)
 46               return m_iDenominator;
 47             else
 48                 throw new Exception("Denominator cannot be assigned a ZERO Value");
 49         }
 50         public void setDenominator(long Denominator) throws Exception
 51         {
 52             if(Denominator != 0)
 53              m_iDenominator = Denominator;
 54             else
 55                 throw new Exception("Denominator cannot be assigned a ZERO Value");
 56         }
 57     
 58     
 59 
 60         
 61         public String ToString() throws Exception
 62         {
 63             String str;
 64             if ( this.getDenominator()==1 )
 65                 str=Long.toString(this.getNumerator());
 66             else
 67                 str=this.getNumerator() + "/" + this.getDenominator();
 68             return str;
 69         }
 70     
 71         public static Fraction ToFraction(String strValue) throws Exception
 72         {
 73             int i;
 74             for (i=0;i<strValue.length();i++)
 75                 if (strValue.charAt(i)=='/')
 76                     break;
 77             
 78             if (i==strValue.length())        
 79                 return new Fraction(Long.parseLong(strValue),1);
 80         
 81             long iNumerator=Long.parseLong(strValue.substring(0,i));
 82             long iDenominator=Long.parseLong(strValue.substring(i+1));
 83             return new Fraction(iNumerator, iDenominator);
 84         }
 85         
 86         public static void ReduceFraction(Fraction frac) throws Exception
 87         {
 88             try
 89             {
 90                 if (frac.getNumerator()==0)
 91                 {
 92                     frac.setDenominator(1);
 93                     return;
 94                 }
 95                 
 96                 long iGCD=GCD(frac.getNumerator(), frac.getDenominator());
 97                 frac.setNumerator(frac.getNumerator()/iGCD);
 98                 frac.setDenominator(frac.getDenominator()/iGCD);
 99                 
100                 if ( frac.getDenominator()<0 )    
101                 {
102                     frac.setNumerator(frac.getNumerator()*(-1));
103                     frac.setDenominator(frac.getDenominator()*(-1));    
104                 }
105             } 
106             catch(Exception exp)
107             {
108                 throw new Exception("Cannot reduce Fraction: " + exp.getMessage());
109             }
110         }
111         private static long GCD(long iNo1, long iNo2)
112         {
113         
114             if (iNo1 < 0) iNo1 = -iNo1;
115             if (iNo2 < 0) iNo2 = -iNo2;
116             
117             do
118             {
119                 if (iNo1 < iNo2)
120                 {
121                     long tmp = iNo1;  
122                     iNo1 = iNo2;
123                     iNo2 = tmp;
124                 }
125                 iNo1 = iNo1 % iNo2;
126             } while (iNo1 != 0);
127             return iNo2;
128         }
129     
130         public static Fraction Inverse(Fraction frac1) throws Exception 
131         {
132             if (frac1.getNumerator()==0)
133                 throw new Exception("Operation not possible (Denominator cannot be assigned a ZERO Value)");
134             long iNumerator=frac1.getDenominator();
135             long iDenominator=frac1.getNumerator();
136             return ( new Fraction(iNumerator, iDenominator));
137         }    
138         
139         public String Add(String str1, String str2)
140         {
141             
142             try{
143               Fraction frac1 = new Fraction(str1);
144               Fraction frac2 = new Fraction(str2);
145               long iNumerator=frac1.getNumerator()*frac2.getDenominator() + frac2.getNumerator()*frac1.getDenominator();
146               long iDenominator=frac1.getDenominator()*frac2.getDenominator();
147               return ( new Fraction(iNumerator, iDenominator).ToString() );    
148             }catch(Exception e){
149                 return e.getMessage();
150             }
151         }
152         
153         public String Multiply(String str1, String str2)
154         {        
155             try{
156               Fraction frac1 = new Fraction(str1);
157               Fraction frac2 = new Fraction(str2);
158               long iNumerator=frac1.getNumerator()*frac2.getNumerator();
159                 long iDenominator=frac1.getDenominator()*frac2.getDenominator();
160               return ( new Fraction(iNumerator, iDenominator).ToString() );    
161             }catch(Exception e){
162                 return e.getMessage();
163             }
164         }
165 }
View Code

主函數代碼爲:

  1 import java.util.ArrayList;
  2 import java.util.HashMap;
  3 import java.util.LinkedList;
  4 import java.util.Queue;
  5 import java.util.Random;
  6 import java.util.Scanner;
  7 import java.util.Stack;
  8 
  9 public class Program{
 10     
 11     static Random ran = new Random();
 12     static HashMap<String, String> priorities = new HashMap<String, String>() {
 13         {
 14             put("#", "-1");  
 15             put("+", "0"); 
 16             put("-", "0"); 
 17             put("*", "1"); 
 18             put("/", "1"); 
 19         }
 20     };
 21     final static String operators = "+-*/=";
 22     final static String space = " ";
 23   
 24   public static void main(String args[]) throws Exception{
 25       int input = 1;
 26       while (input == 1)
 27       {
 28           System.out.println("請輸入生成四則運算題的數目: ");
 29           Scanner sc = new Scanner(System.in);
 30           int numOfQue = sc.nextInt();
 31           String[] ques = new String[numOfQue];
 32           ArrayList que = new ArrayList();
 33          
 34           for(int i = 0;i < numOfQue;i++){
 35               que = produceQue();
 36               ques[i] = (String) que.get(0);
 37               TreeNode s = suffixExpressionToTree(PreOrderToPostOrder(que));
 38               System.out.println();
 39               System.out.println(ques[i] + operators.charAt(4) + space + Calculate(que));
 40             
 41           }
 42       }
 43 }
 44   static ArrayList produceQue() throws Exception{
 45       ArrayList str = new ArrayList();
 46       ArrayList isOperand = new ArrayList();
 47       int count = ran.nextInt(2) + 1;
 48       int[] num = new int[count+1];
 49       int[] den = new int[count+1];
 50       String[] operand = new String[count+1];
 51       int[] index = new int[count];
 52       int numOfBrackets = 0;
 53       if(count > 1)
 54           numOfBrackets = ran.nextInt(count);
 55       for(int i = 0;i < count + 1;i++){
 56           num[i] = ran.nextInt(3) + 2;
 57           if(ran.nextInt(10) < 8)
 58               den[i] = 1;
 59           else{
 60               den[i] = ran.nextInt(4)+1;
 61           }
 62           operand[i] = new Fraction(num[i],den[i]).ToString();
 63           if(i < count)
 64               index[i] = ran.nextInt(4);
 65       }
 66       ArrayList start = new ArrayList(numOfBrackets);
 67       ArrayList end = new ArrayList(numOfBrackets);
 68       for(int i = 0;i < numOfBrackets;i++){
 69            start.add(ran.nextInt(count-1) + 1);
 70            end.add(ran.nextInt(count-(int)start.get(i)) + (int)start.get(i) + 1);
 71       }
 72       for(int i = 0;i < numOfBrackets;i++)
 73           for(int j = 0;j < numOfBrackets;j++){
 74               if(start.get(i).equals(end.get(j))){
 75                   start.set(i, -1);
 76                   end.set(j, -1);
 77               }
 78           }
 79       for(int i = 0;i < count + 1;i++){
 80           str.add(operand[i]);
 81           isOperand.add(i + 1);
 82           if(i < count){
 83               str.add(operators.charAt(index[i]));
 84               isOperand.add(0);
 85           }
 86       }
 87      for(int i = 0;i < numOfBrackets;i++){
 88          if((int)start.get(i) != -1){
 89              int left = isOperand.indexOf(start.get(i));
 90              str.add(left, "(");
 91              isOperand.add(left,0);
 92          }
 93          if((int)end.get(i) != -1){
 94              int right = isOperand.indexOf(end.get(i))+1;
 95              str.add(right,")");
 96              isOperand.add(right,0);
 97          }
 98      }
 99      str.add(0,"");
100      int j = 1;
101      while(j < str.size()){
102          str.set(0, str.get(0).toString()+str.get(j).toString()+space);
103          j = j + 1;
104      }
105      return str;
106   }  
107   static boolean IsOperator(String op){
108       return operators.contains(op);
109   }
110   static boolean IsLeftAssoc(String op){
111       if(op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/"))
112           return true;
113       else
114           return false;
115   }
116   static String Compute(String leftNum,String rightNum,int op) throws Exception{
117       Fraction result = new Fraction();
118     switch(op){
119     case 0:
120           return result.Add(leftNum,rightNum);
121     case 1:
122           rightNum = "-"+rightNum;
123           return result.Add(leftNum,rightNum);
124     case 2:
125           return result.Multiply(leftNum, rightNum);
126     case 3:
127           rightNum = result.Inverse(new Fraction(rightNum)).ToString();
128           return result.Multiply(leftNum, rightNum);
129       }
130     return null;
131   }
132   static Queue PreOrderToPostOrder(ArrayList expression){
133       Queue<String> result=new LinkedList<String>();
134       Stack<String> operatorStack=new Stack<String>();
135       operatorStack.push("#");
136       String top,cur,tempChar,tempNum;
137       for(int i = 1;i < expression.size();i++){
138           cur =  expression.get(i).toString();
139           top = operatorStack.peek();
140           if(cur == "(")
141               operatorStack.push(cur);
142           else{
143               if(IsOperator(cur)){
144                   while(IsOperator(top) && ((IsLeftAssoc(cur) && priorities.get(cur).compareTo(priorities.get(top))<=0)
145                     ||(!IsLeftAssoc(cur) && priorities.get(cur).compareTo(priorities.get(top)) < 0))){
146                       result.add(operatorStack.pop());
147                       top = operatorStack.peek();
148                   }
149                   operatorStack.push(cur);
150               }
151               else if(cur == ")"){
152                   while(operatorStack.size() > 0 && (tempChar = operatorStack.pop()) != "("){
153                       result.add(tempChar);
154                   }
155               }
156               else{
157                   tempNum = cur;
158                   result.add(tempNum);
159               }
160           }
161       }
162       while(operatorStack.size()>0){
163           cur = operatorStack.pop();
164           if(cur == "#") continue;
165           if(operatorStack.size() > 0)
166               top = operatorStack.peek();
167           result.add(cur);
168       }
169       return result;
170   }
171 
172   static String Calculate(ArrayList expression) throws Exception
173   {
174       Queue rpn = PreOrderToPostOrder(expression);
175       Stack operandStack = new Stack<String>();
176       String left, right,cur;
177       while (rpn.size() > 0)
178       {
179           cur = (String) rpn.poll();
180           int index = operators.indexOf(cur);
181           if (index >= 0)
182           {
183               right = (String) operandStack.pop();
184               left = (String) operandStack.pop();
185               operandStack.push(Compute(left, right, index));
186           }
187           else
188           {
189               operandStack.push(cur);
190           }
191       }
192       return (String) operandStack.pop();
193   }
194   static TreeNode suffixExpressionToTree(Queue suffixStr)
195   {
196       if (suffixStr.isEmpty()) return null;
197       // 用於臨時存儲節點的棧
198       Object[] chs = suffixStr.toArray();
199       Stack<TreeNode> stack = new Stack<TreeNode>();
200       // 遍歷全部字符,不是運算符的入棧,是運算符的,將棧中兩個節點取出,合成一顆樹而後入棧
201       for (int i = 0; i < chs.length; i++)
202       {
203           if (IsOperator(chs[i].toString()))
204           {
205               if (stack.isEmpty() || stack.size() < 2)
206               {
207                   System.err.println("輸入的後綴表達式不正確");
208                   return null;
209               }
210               TreeNode root = new TreeNode(chs[i]);
211               root.right = stack.pop();
212               root.left = stack.pop();
213               stack.push(root);
214           }
215           else
216           {
217               stack.push(new TreeNode(chs[i]));
218           }
219       }
220       if (stack.isEmpty() || stack.size() > 1)
221       {
222           System.err.println("輸入的後綴表達式不正確");
223           return null;
224       }
225       //stack.pop().printAll();
226        return stack.pop();
227            
228   }
229   static boolean CompTree(TreeNode tree1,TreeNode tree2) 
230   { 
231       if(tree1 == null && tree2 == null) 
232           return true; 
233    
234       if(tree1 != null && tree2 != null) 
235       { 
236           if(tree1.val.equals(tree2.val)) 
237           { 
238             if(tree1.val.equals("+") || tree1.val.equals("*"))
239             {
240                 if(CompTree(tree1.left, tree2.left) && 
241                   CompTree(tree1.right, tree2.right) || 
242                   CompTree(tree1.right, tree2.left) && 
243                   CompTree(tree1.left, tree2.right)) 
244               { 
245                   return true; 
246               }
247           }
248           else{
249                if(CompTree(tree1.left, tree2.left) && CompTree(tree1.right, tree2.right))
250                     { 
251                         return true; 
252                     }
253           }
254           } 
255       } 
256       return false; 
257   }
258 }
View Code

測試用例以下:

      這裏着重講下關於生成題目的重複檢測問題,剛開始我想着是把四則運算表達式轉化成一棵二叉樹,那麼這就歸結成二叉樹同構的問題了。函數suffixExpressionToTree即是經過算式後綴式生成一棵二叉樹。網上根據http://blog.csdn.net/smartxxyx/article/details/23992487,也請教了一個算法大神,說是要用到哈希。具體策略爲:先隨機產生一系列隨機數做爲存到數組,接着從根節點出發,遞歸計算每一個子樹的哈希值,將子樹的哈希值相加而後和父節點本身對應的數組上的隨機數相加獲得父節點的哈希值。這個計算結果和子樹的順序是沒有關係的,因此同構的樹一哈希值必定是同樣的。對於異構的樹,必然在某些節點計算的哈希值不一樣,因爲都是隨機產生的一些數字,於是他們相加值和另一棵樹哈希值相同的機率也會很是低。在"國家集訓隊2007論文集1.楊弋《Hash在信息學競賽中的一類應用》.doc"一文中,是使用一種相似樹狀遞推的方法計算二叉樹的Hash值,

     對於一個節點v,先求出它全部兒子節點的Hash值,並從小到大排序,記做H1H2,…,HD。那麼v的Hash值就能夠計算爲:

 

      換句話說,就是從某個常數開始,每次乘以p,和一個元素異或,再除以q取餘,再乘以p,和下一個元素異或,除以q取餘……一直進行到最後一個元素爲止。最後把所獲得的結果乘以b,再對q取餘。

    +_+那麼這樣構造的算式二叉樹,葉子節點確定都是操做數,那麼Hash值直接取操做數,然後隨機a、p、b計算二叉樹根的Hash值進行比較。代碼實現起來我仍是一臉懵逼,若是有誰有這方面的看法,歡迎指教!

     如今我只是使用簡單粗暴的方式來比較兩棵二叉樹,就是遞歸比較他們的左右孩子是否相同,若是節點爲"+"或"*",還要互換左右孩子進行比較。

     部分測試用例以下:

              

4、總結

      整個代碼轉化比較痛苦,畢竟疏通路是個艱難的過程。而在轉化的時候不得不考慮各類語言的特性,可能一種簡單的數據結構在另外一種語言並無實現,而複雜的卻已封裝好,不過這也許就是程序語言的魅力之處了。接下來的工做就是網頁顯示和細節優化了,敬請期待!

相關文章
相關標籤/搜索