/// <summary> /// 根据算术表达式创建二叉树 /// </summary> /// <param name="str"></param> /// <param name="p"></param> /// <param name="q"></param> /// <param name="tail"></param> void createTreenode(TreeNode node, string str, int p, int q, int tail, ref OP[] Aop) { //p,q分别标志Aop的首尾 int i = 0, find = 0; if (str[p] == '(' && str[q] == ')') { for (int j = tail; j >= 0; j--) { if (Aop[j].operation != null && Aop[j].location >= p && Aop[j].location <= q) { Aop[j].location--; Aop[j].index--; } } str = str.Substring(p + 1, q - p - 1); q = q - 2; } string tr = ""; string substr = ""; if (istrigonometric(str, p, q, ref tr, tail, ref Aop)) { TreeNode subnode = new TreeNode(); if (tr == "sin" || tr == "cos" || tr == "tan") { substr = str.Substring(p + 4, q - p - 4); } if (tr == "ln") { substr = str.Substring(p + 3, q - p - 3); } if (tr == "sqrt") { substr = str.Substring(p + 5, q - p - 5); } for (int j = tail; i >= 0; i--) { if (Aop[i].operation != null && Aop[i].location >= p && Aop[i].location <= q) { Aop[i].index = -1; } } OP[] Bop = new OP[100]; int tail1 = Sortop1(substr, ref Bop); createTreenode(subnode, substr, 0, substr.Length - 1, tail1, ref Bop); switch (tr) { case "sin": node.data.Number = Math.Sin(caculate(subnode)); break; case "cos": node.data.Number = Math.Cos(caculate(subnode)); break; case "tan": node.data.Number = Math.Tan(caculate(subnode)); break; case "ln": node.data.Number = Math.Log(caculate(subnode)); break; case "sqrt": node.data.Number = Math.Sqrt(caculate(subnode)); break; } node.lChild = null; node.rChild = null; return; } if (isnum(str, p, q))//如果数据仅含运算数 { //创建头节点,并将数据位置为str2float node.data.Number = str2float(str, p, q); node.lChild = null; node.rChild = null; return; } else if (isoperator(str, p, q))//如果数据仅含运算符 { return; } else { for (int j = 0; j <= index; j++) //按照括号一层一层地找 { for (i = tail; i >= 0; i--) //从后往前找,才符合运算的法则,前面先算后面后算 { if (Aop[i].index == j && ((Aop[i].operation == "+") || (Aop[i].operation == "-")) && Aop[i].location >= p && Aop[i].location <= q) { find++; Aop[i].index = -1; node.lChild = new TreeNode(); node.rChild = new TreeNode(); node.data.Operator = Aop[i].operation; createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop); createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop); } } if (find == 0) { for (i = tail; i >= 0; i--) { if (Aop[i].index == j && ((Aop[i].operation == "*") || (Aop[i].operation == "/")) && Aop[i].location >= p && Aop[i].location <= q) { find++; Aop[i].index = -1; node.lChild = new TreeNode(); node.rChild = new TreeNode(); node.data.Operator = Aop[i].operation; createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop); createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop); } } } if (find == 0) { for (i = tail; i >= 0; i--) { if (Aop[i].index == j && (Aop[i].operation == "^") && Aop[i].location >= p && Aop[i].location <= q) { Aop[i].index = -1; node.lChild = new TreeNode(); node.rChild = new TreeNode(); node.data.Operator = Aop[i].operation; createTreenode(node.lChild, str, p, Aop[i].location - 1, tail, ref Aop); createTreenode(node.rChild, str, Aop[i].location + 1, q, tail, ref Aop); } } } } } }
private void setOperation(OP in_op) { if (in_op != OP.CLRENTRY && in_op != OP.BACKSPACE && in_op != OP.MRECALL && in_op != OP.PER) { //solve the current display equateDisplay(); } bool newOpIn = in_op == OP.ADD || in_op == OP.SUB || in_op == OP.MUL || in_op == OP.DIV; //set whether or not an op is displaying (like + - * or /).. useful for parsing string if (newOpIn || (displayedOp && (in_op == OP.MRECALL || in_op == OP.PER))) { displayedOp = true; } else if (in_op != OP.BACKSPACE) { displayedOp = false; } //set the operation for the next display if (in_op != OP.BACKSPACE && in_op != OP.MRECALL && in_op != OP.PER) { currentOperation = in_op; } if (in_op != OP.BACKSPACE && in_op != OP.MRECALL && in_op != OP.PER) { hasNum = false; } if (in_op != OP.MRECALL) { endingOp = false; } //display the operation in the display switch (in_op) { case OP.ADD: //textBox_display.Text = "+ "; soonTxt = "+ "; displayText(); break; case OP.SUB: //textBox_display.Text = "- "; soonTxt = "- "; displayText(); break; case OP.DIV: //textBox_display.Text = "/ "; soonTxt = "/ "; displayText(); break; case OP.MUL: //textBox_display.Text = "* "; soonTxt = "* "; displayText(); break; case OP.EQU: endingOp = true; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; break; case OP.RECIP: endingOp = true; currentValue = 1 / currentValue; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; break; case OP.SQRT: endingOp = true; currentValue = Math.Sqrt(currentValue); //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; break; case OP.INV: endingOp = true; currentValue *= -1; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; break; case OP.CLR: //textBox_display.Text = "0"; soonTxt = "0"; displayText(); currentValue = 0; currentOperation = OP.NONE; //memoryValue = 0; //memoryStored = false; //textBox_memory.Text = ""; break; case OP.CLRENTRY: //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); endingOp = true; break; case OP.BACKSPACE: if (!hasNum) { //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); endingOp = true; } else if (currentOperation != OP.NONE) { //textBox_display.Text = textBox_display.Text.Substring(0, textBox_display.Text.Length - 2); soonTxt = soonTxt.Substring(0, soonTxt.Length - 1); displayText(); if (soonTxt.Length <= TO_NUM) { hasNum = false; } } else if (soonTxt != "0") { //textBox_display.Text = textBox_display.Text.Substring(0, textBox_display.Text.Length - 1); soonTxt = soonTxt.Substring(0, soonTxt.Length - 1); displayText(); if (soonTxt.Length == 0) { hasNum = false; //textBox_display.Text = "0"; soonTxt = "0"; displayText(); } } break; case OP.PER: double newDigits = getDigits() * 0.01 * currentValue; if (displayedOp) { soonTxt = soonTxt.Substring(0, TO_NUM) + newDigits.ToString("g"); } else { soonTxt = newDigits.ToString("g"); } displayText(); break; case OP.MSTORE: if (currentValue != 0) { endingOp = true; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; memoryValue = currentValue; memoryStored = true; textBox_memory.Text = "M"; } else if (currentOperation == OP.NONE && soonTxt != "0") { endingOp = true; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; memoryValue = Convert.ToDouble(soonTxt); memoryStored = true; textBox_memory.Text = "M"; } break; case OP.MADD: if (memoryStored) { endingOp = true; //textBox_display.Text = currentValue.ToString(); soonTxt = currentValue.ToString(); displayText(); hasNum = false; memoryValue += currentValue; } break; case OP.MCLEAR: textBox_memory.Text = ""; memoryValue = 0; memoryStored = false; break; case OP.MRECALL: if (memoryStored && memoryValue != 0) { //different cases if (hasNum && currentOperation != OP.NONE) //typed an op and a num but not pressed equal.. hasNum && currentOperation != OP.NONE { //replace current typed num with the recalled num endingOp = true; //textBox_display.Text = textBox_display.Text.Substring(0, TO_NUM); //textBox_display.Text += memoryValue.ToString(); soonTxt = soonTxt.Substring(0, TO_NUM); soonTxt += memoryValue.ToString(); displayText(); hasNum = true; } else if (hasNum && currentOperation == OP.NONE) //typed a num but no op.. hasNum && currentOperation == OP.NONE { //replace current typed num with the recalled num endingOp = true; //textBox_display.Text = memoryValue.ToString(); soonTxt = memoryValue.ToString(); displayText(); hasNum = true; } else if (currentOperation == OP.NONE) //beginning with 0, !hasNum, currentOperation == OP.NONE { //replace 0 with the recalled num endingOp = true; //textBox_display.Text = memoryValue.ToString(); soonTxt = memoryValue.ToString(); displayText(); hasNum = true; } else //typed an op but not a num.. !hasNum, currentOperation != OP.NONE { //enter the recalled number as the num endingOp = true; if (displayedOp) { //textBox_display.Text += memoryValue.ToString(); soonTxt += memoryValue.ToString(); displayText(); hasNum = true; } else { //textBox_display.Text = memoryValue.ToString(); soonTxt = memoryValue.ToString(); displayText(); currentValue = Convert.ToDouble(soonTxt); hasNum = false; } } } break; default: break; } }