It took a week to update the calculator, and today I will finish it anyway. I have a little pursuit of perfection, and every day there are classes, evenings and homework, and every night will write some other blog posts.
The last time you missed a write how to implement the calculation. Ideas are as follows:
Before getting a stack of 2stack2, which is the inverse of the Polish-style. But notice that the equation is reversed. Because stacks can only be written from the top of the stack and taken out from the top of the stack. Therefore, the number of stacks 2 must be reversed.
Here is the code for the transformation:
// //Turn the Stack 2 value upside down// Private voidUpsidedown () {string[] strtemp = Stack2. ToArray ();//temporarily store stack stack2 values in an arrayStack2. Clear ();//empty the Stack stack2 for(inti=strtemp.length-1; i>=0; i--) {Stack2. Push (Strtemp[i]); } }
The value of the stack upside down, we can be calculated, the idea of the calculation is as follows: follow the steps
1: From the top of the stack element, if the number is directly deposited in the new stack 2: If it is an operator, do not deposit, the first two elements of the new stack is taken out sequentially, the first out of the number is placed on the right side of the operator, and then put on the left side 3: The results of the calculation back to the new stack Repeat the above steps to know that the calculation is complete.
Attention! The new stack holds the number, so pay attention to the type of stack.
// //Calculate Arithmetic// Public DoubleDomath () {varStacktemp =Newstack<Double>(); Try { while(Mystack2.count! =0) { if(!Ifnumber (Mystack2.peek ())) { DoubleD1 =Stacktemp.pop (); DoubleD2 =Stacktemp.pop (); Switch(Mystack2.pop ()) { Case "+": Stacktemp.push (D2+D1); Break; Case "-": Stacktemp.push (D2-D1); Break; Case "*": Stacktemp.push (D2*D1); Break; Case "/": Stacktemp.push (D2/D1); Break; }//End Switch}//End If Else{Stacktemp.push (convert.todouble (Mystack2.pop ())); } }//End While returnStacktemp.pop (); } Catch { return 0; } }
Four the general steps of the hybrid operation and the solution is so much, now it's time to solve how to make sure that the user enters the formula and how to get the formula how to parse (the problem mentioned earlier: that is, when the parentheses are accepted as a unary operator such as: 1+ (-2). The converted formulas are not calculated correctly. )
Idea one: How to solve the user disorderly input number
Use the stack to save the user each press button content, in addition to the first input, at each input time and the top of the stack to compare. If the input operator is two times in a row, the second is considered valid:
Private stringstr ="";//declares a tangent to define an empty string that is used to display user input in a labelstack<string> tempstack =Newstack<string> ();//declares an array to store user input//Determine if user clicks are valid Public voidIfvalid (strings) {if(Tempstack! =NULL) { if(Calculate.ifnumber (s))//If the user presses a number, the input is valid{Tempstack.push (s); } Else { if(! Calculate.ifnumber (Tempstack.peek ()))//If the user presses the operator twice in succession, the second time is considered valid{tempstack.pop (); Tempstack.push (s); } ElseTempstack.push (s); } }//End If Else{Tempstack.push (s); } STR=""; string[] TempStr =Tempstack.toarray (); //inverse of the resulting array for(inti =0; I < tempstr.length/2; i++) { stringtemp =Tempstr[i]; Tempstr[i]= Tempstr[tempstr.length-i-1]; Tempstr[tempstr.lengthI1] =temp; } foreach(varIteminchtempstr) Str+=item; Label1. Text=str; } Private voidButton1_Click (Objectsender, EventArgs e) {Ifvalid (button1). Text); } Private voidButton2_Click (Objectsender, EventArgs e) {Ifvalid (button2). Text); }
I have a lot of places to use the back and forth of the array elements of the code, but did not write it as a separate function, resulting in code redundancy.
Here the code is written in the Form1, the use of the Reversepolish Isnumber method, because it is different classes, and no reversepolish directly call, so to change the previously defined modified private to public The static adornment can be called directly.
Idea two: When a unary operator with parentheses is accepted such as: 1+ (-2). The formula obtained by inverse Polish law cannot be calculated correctly.
Bashi to parse, written as: 1+ (0-2) Form!
The code is as follows:
string[] stranalysis;//storing formulas after parsing the original calculation formula string[] str;//string array str for storing the original calculation formula// //parsing the original calculation formula// Public voidAnalysis () {varStacktemp =Newstack<string>(); intCount =0; Try { while(Count <stranalysis.length) {if(Stranalysis[count] = ="("&& (Stranalysis[count +1] =="-"|| Stranalysis[count +1] =="+"))//if the formula operand (the latter operand is + or-,{Stacktemp.push (Stranalysis[count]); Stacktemp.push ("0"); Count++; } Else if(!Ifnumber (Stranalysis[count])) {Stacktemp.push (Stranalysis[count]); Count++; } Else if(Ifnumber (Stranalysis[count])) {stringstrtemp =""; while(Count < Stranalysis.length && Ifnumber (Stranalysis[count]))//if it is a number, including decimal points., the string is spelled until an operator is encountered or the array is traversed.{strtemp+=Stranalysis[count]; Count++; } stacktemp.push (strtemp); } } } Catch{stacktemp=NULL; } STR=Stacktemp.toarray (); //invert a string array for(inti =0; I < Str. Length/2; i++) { stringtemp =Str[i]; Str[i]= Str[str. Length-i-1]; Str[str. LengthI1] =temp; } }
The general idea of thinking about so much, in short, the problem of one-to-many breakthroughs, the solution of the problem plan written method, finally together on the success. The above code is not all the code, I just want to share their ideas. Because I guess it's going to take a long time to look at it if I post all the code. After all, everyone's thinking is different. I'm not good at reading someone else's code T.
tip : Generally encountered access to memory, such as stack stacks to access the stack top code, the best exception handling, because it is easy to error.
You are welcome to ask questions!
Windows Form Simple Calculator implementation (bottom)