计算器如图所示,仅实现加减乘除及括号功能,公式错误时会有提示。
首先建立一个inputList,每点击数据一下,便将内容添加至inputList中,点击后退时则删除List中最后一个元素。
每次操作后将inputList组合成串显示在输入框中;
List<string> input = new List<string>(); public string Add(string str) { input.Add(str); return string.Join("", input); } public string delete() { if (input.Count > 0) input.RemoveAt(input.Count - 1); return string.Join("", input); }View Code
其次建立一个elementList,点击计算时将inputList中的字符组合成数据添加到elementList中,比如:
inputList中存放的是[1,.,2,*,1,0,+,1] 八个,组合到elementList中是[1.2,*,10,+,1] 五个。
List<string> element = new List<string>(); /// <summary> /// 将输入的字符串进行操作符,数值的分割 /// </summary> bool SplitEle() { element.Clear(); input.ForEach(i => { switch (Getflag(i)) { case enum_flag.data://数据 if (element.Count == 0 || Getflag(element.Last()) != enum_flag.data) element.Add(i); else element[element.Count - 1] = element.Last() + i; break; case enum_flag.limit://括号 case enum_flag.symbol://操作符+-*/ element.Add(i); break; } }); return true; }View Code
然后将我们输入的公式转换为后缀表达式,比如1.2*10+1要写为1.210*1+,后缀表达式的换算方法如下:
初始化一个Stack栈temp,用于临时存放运算符,建立一个postFixList,用于存放后缀表达式。遍历elementList:
①.遇到操作数据,如1.2,直接加入postFixList;
②.遇到左括号"(",直接放入栈temp中,遇到右括号")",则依次取出栈中运算符并加入到postFixList中,直至取出"(",
取出的"("不要放入postFixList中,若没有则公式错误;
③.遇到运算符,则依次取出栈中优先级>=自己的运算符,放入后缀postFixList中,若碰到左括号"("或者栈空则停止,
然后将自己放入栈temp中。
遍历结束后,将栈temp中剩余的运算符全部依次取出添加至postFixList,若postFixList中存在括号,则说明公式错误不对称。
此时应该temp为空,postFixList中为[1.2,10,*,1,+],代码如下:
List<string> postFix = new List<string>(); Stack<string> temp = new Stack<string>(); /// <summary> /// 将输入的公式转换为后缀表达式 /// </summary> bool ConvertToPostFix() { bool err = false; temp.Clear(); postFix.Clear(); element.ForEach(e => { switch (Getflag(e)) { case enum_flag.data: postFix.Add(e); break; case enum_flag.limit: if (e == "(") temp.Push(e); if (e == ")") { err = true; while (temp.Count > 0) { string cur = temp.Pop(); if (cur == "(") { err = false; break; } postFix.Add(cur); } } break; case enum_flag.symbol: while (temp.Count > 0) { if (temp.Peek() == "(") break; if ((temp.Peek() == "+" || temp.Peek() == "-") && (e == "*" || e == "/")) break; postFix.Add(temp.Pop()); } temp.Push(e); break; } }); while (temp.Count > 0) { if (temp.Peek() == "(" || temp.Peek() == ")") return false; postFix.Add(temp.Pop()); } return !err; }View Code
最后计算后缀表达式,计算步骤为,清空栈temp,遍历postFixList:
①.遇到操作数据,直接放入栈temp中;
②.遇到运算符,则依次取出两个栈顶元素data1和data2,与运算符进行运算,data1为右侧数据,data2为左侧数据;
然后将计算得到的值放入栈中;
遍历结束后,栈中应该只剩一个数值,即为最终结果,否则公式错误。代码如下:
/// <summary> /// 对后缀表达式进行计算 /// </summary> /// <returns></returns> bool ExcuteFormula() { temp.Clear(); bool err = false; postFix.ForEach(p => { if (Getflag(p) == enum_flag.data) temp.Push(p); if (Getflag(p) == enum_flag.symbol) { if (temp.Count >= 2) { float newV = cal(temp.Pop(), temp.Pop(), p); temp.Push(newV.ToString("0.00")); } else err = true; } }); return !err; } float cal(string r, string l, string a) { float left = float.Parse(l); float right = float.Parse(r); switch (a) { case "+": return left + right; case "-": return left - right; case "*": return left * right; case "/": return left / right; } return 0; }View Code
验证下计算过程,输入公式(1.2+1.3)*2/3,监视过程:
最初输入: 按数据分割:
后缀表达式: 栈:
结果:
标签:case,return,string,temp,C#,enum,element,简易,计算器 From: https://www.cnblogs.com/cfsl/p/16939852.html