先贴一段上学时候写的代码占个位
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了先贴一段上学时候写的代码占个位相关的知识,希望对你有一定的参考价值。
C#计算器
using System; using System.Collections.Generic; using System.Linq; namespace System { /// <summary> /// 计算器类 /// </summary> public class Calculator { string strFormula; /// <summary> /// 用一个字符串表达式初始化实例。 /// </summary> /// <param name="strFormula"></param> public Calculator(string strFormula) { this.strFormula = strFormula; } public Calculator() { } /// <summary> /// 表达式结果。如果没有用有效表达式初始化实例,则结果为0。 /// </summary> public double Result { get { if (strFormula == null || strFormula == string.Empty) return 0; else return Calculate(Scan(strFormula)); } } /// <summary> /// 静态方法,用于计算一个字符串表达式。 /// </summary> /// <param name="formula">字符串表达式</param> /// <returns></returns> public static double Calculate(string formula) { var cal = new Calculator(); return cal.Calculate(cal.Scan(formula)); } /// <summary> /// 扫描字符串,生成表达式元素队列。 /// </summary> /// <param name="formula">表达式字符串</param> /// <returns>表达式队列</returns> protected List<object> Scan(string formula) { List<object> formulaList = new List<object>(); bool numFlag = false; int numStartIndex = 0; for (int i = 0; i < formula.Length; i++) { //判断是否为非法字符 if (IllegalChar(formula[i])) { throw new Exception("存在非法字符。"); } //进行数字匹配 if ((numFlag == false) && ((char.IsNumber(formula[i]) == true) || formula[i] == ‘.‘)) { numFlag = true; numStartIndex = i; } if ((numFlag == true) && (char.IsNumber(formula[i]) == false) && formula[i] != ‘.‘) { numFlag = false; formulaList.Add(double.Parse(formula.Substring(numStartIndex, i - numStartIndex))); } //进行运算符匹配 if (IsFormulaOperaor(formula[i])) { formulaList.Add(formula[i].ToString()); } } //对标志进行最后一轮收尾操作 if (numFlag) { formulaList.Add(double.Parse(formula.Substring(numStartIndex))); } return formulaList; } /// <summary> /// 计算经过扫描形成的算术队列 /// </summary> /// <param name="formula">算术队列</param> /// <returns></returns> protected double Calculate(List<object> formula) { //扫描并递归子表达式 ushort deep = 0; int StartIndex = 0; for (int i = 0; i < formula.Count; i++) { checked { if (formula[i].ToString() == "(") { if (deep == 0) { StartIndex = i; } deep++; } if (formula[i].ToString() == ")") { deep--; if (deep == 0) { //递归子表达式 Skip Take var result = Calculate(formula.Skip(StartIndex + 1).Take(i - StartIndex - 1).ToList()); //替换值 formula[StartIndex] = result; //移除子表达式,StartIndex + 1 ~ i + 1 formula.RemoveRange(StartIndex + 1, i - StartIndex); //重新设置新的开始位置 i = StartIndex; } } } } //优化表达式 OptimizeFormula(ref formula); //进行运算 //进行乘除运算 for (int i = 1; i < formula.Count; i++) { if (formula[i].ToString() == "*") { if (formula[i - 1] is double && formula[i + 1] is double) { formula[i - 1] = (double)formula[i - 1] * (double)formula[i + 1]; formula.RemoveRange(i--, 2); } else { throw new Exception("表达式不合法,连续出现运算符"); } } if (formula[i].ToString() == "/") { if (formula[i - 1] is double && formula[i + 1] is double) { formula[i - 1] = (double)formula[i - 1] / (double)formula[i + 1]; formula.RemoveRange(i--, 2); } else { throw new Exception("表达式不合法,连续出现运算符"); } } } //进行加减运算 for (int i = 1; i < formula.Count; i++) { if (formula[i].ToString() == "+") { if (formula[i - 1] is double && formula[i + 1] is double) { formula[i - 1] = (double)formula[i - 1] + (double)formula[i + 1]; formula.RemoveRange(i--, 2); } else { throw new Exception("表达式不合法,连续出现运算符"); } } if (formula[i].ToString() == "-") { if (formula[i - 1] is double && formula[i + 1] is double) { formula[i - 1] = (double)formula[i - 1] - (double)formula[i + 1]; formula.RemoveRange(i--, 2); } else { throw new Exception("表达式不合法,连续出现运算符"); } } } if (formula.Count != 1) { throw new Exception("表达式集合堆栈没有计算完全,这可能是因为表达式不正确造成的。"); } return (double)formula[0]; } /// <summary> /// 对表达式进行优化,同时检测表达式是否合法 /// </summary> /// <param name="formula">表达式列表</param> protected void OptimizeFormula(ref List<object> formula) { if (formula[0].ToString() == "-" && formula[1] is double) { formula[1] = (double)formula[1] * -1; formula.RemoveAt(0); } if (IsArithmeticOperator(formula[0].ToString()) || IsArithmeticOperator(formula.Last().ToString())) { throw new Exception("表达式不正确"); } for (int i = 1; i < formula.Count - 1; i++) { //判断是否为正负号 if (formula[i].ToString() == "+" || formula[i].ToString() == "-") { if (IsArithmeticOperator(formula[i - 1].ToString()) && formula[i + 1] is double) { //如果为符号与后面的数字合并 if (formula[i].ToString() == "-") { formula[i + 1] = (double)formula[i + 1] * -1; } //移除正负号表示位 formula.RemoveAt(i); } } } for (int i = 1; i < formula.Count - 1; i++) { //两个运算符叠加在一起的情况 if (formula[i].ToString() == "*" || formula[i].ToString() == "/") { if (IsArithmeticOperator(formula[i - 1].ToString()) || IsArithmeticOperator(formula[i + 1].ToString()) ) { throw new Exception("存在运算符错误"); } } } } /// <summary> /// 判断给定字符是否为非法字符 /// </summary> /// <param name="c"></param> /// <returns></returns> protected bool IllegalChar(char c) { return !("1234567890.+-*/() ".Contains(c)); } /// <summary> /// 是否属于表达式运算符集的成员。 /// </summary> /// <param name="c"></param> /// <returns></returns> protected bool IsFormulaOperaor(char c) { return "+-*/()".Contains(c); } /// <summary> /// 是否为算术运算符。 /// </summary> /// <param name="c"></param> /// <returns></returns> protected bool IsArithmeticOperator(string c) { return "+,-,*,/".Split(‘,‘).Contains(c); } } }
以上是关于先贴一段上学时候写的代码占个位的主要内容,如果未能解决你的问题,请参考以下文章