还是有一些小问题....懒得改了,但大体思路还是清晰的,首先定义一个运算符栈,一个数栈。
关于优先级,两个括号(,)优先级最低,其次是+、-,最高的是*、/
关于运算法则,打个比方,"(3+5*4)+3"这个串
首先遇到左括号,直接压入运算符栈,然后是3,直接压入数栈,然后遇到5,压入数栈,遇到*,将其压入运算符栈,遇到右括号,将运算符栈顶的*取出,取出两个数栈栈顶的数,进行乘法运算,将运算结果压入数栈,因为此时运算符栈顶仍不是左括号,取出栈顶的+号,拿出数栈栈顶的两个数,进行加法运算,并将结果压入数栈。此时栈顶是左括号了,那么将左括号弹出栈。此时数栈里还有一个23,运算符栈为空。接着来。此时轮到了+号,直接压入数栈,遇到3,直接压入数栈。此时发现串已经结尾了,但是运算符栈还没有清空。那么就清空吧,把+号拿出来,数栈的23和3拿出来,加法运算,结果压入数栈。此时运算符栈清空,数栈剩个26。这就是最后的结果。是不是很简单但是有一点云里雾里。。
说一下运算规则吧。优先级大家都知道了,优先级从高到低依次是 "*/","+-","()",每当要压运算符时,首先得看看运算符栈里有什么,如果没有,肯定是可以直接压入的,左括号也是可以不管三七二十一直接压入的,除此之外,如果遇到栈顶运算符优先级更高时,是必须将栈顶运算符先取出来运算,直到栈顶元素优先级小于或者等于要压入的运算符的优先级才可压入。比如3*5+5+5,在压入第一个+号时,必须先将栈里的*号先拿出来运算结束后,才能放进去,否则计算结果将是错误的。当压入的是右括号时,必须一直弹运算符栈进行运算,直到遇到左括号为止。当串扫描到末尾时,也必须将运算符栈清空,最后留在数栈的数就是结果。关于小数点,关于复数加减运算,我写的小程序里有了一定的处理
就类似于这样的简单功能。。。。恩,将就看看吧。。程序不完善,不过也懒得改了,毕竟是练习,最近事又多。
下面贴一下源码
主要用到的几个类和方法:
类Parser 的parse方法,比如给一个“3+4i”的字符串,返回给你一个3个结点的队,队列第一个元素是一个ComplexNumber对象,实数域为3,队列的第二个元素是“+”号,队列第三个元素是一个ComplexNumber对象,实数域为0,虚数域为4。
类Operators 用于测试字符是否是运算符,用来进行控制运算,比较运算符优先级....
类Handler 给一个字符串,他帮你处理,返回给你一个结果。其实就是调一下Parser类的方法去解析一下字符串,然后算一下结果,然后返回结果。
类ComplexNumber,就是复数类啊,不用说了,提供实数域虚数域,getset方法,加减乘除以及toString()方法
using System; using System.Collections; using System.Text; namespace MySpace{ class Parser{ public static Queue Parse(string input){ char[] arr = input.ToCharArray(); Queue queue = new Queue(); foreach(char x in arr){ queue.Enqueue(x); } queue = ParseStringQueue(queue); return queue; } //传入字符串队列,返回封装好的队列。 //ComplexNumber对象或char类型运算符各占用一个结点 private static Queue ParseStringQueue(Queue queue){ Queue secOndQ= new Queue(); char c; StringBuilder sb = null; string temp; int count = queue.Count; bool flag = false; //false表示允许创建新SB对象进行缓存数字字符串 for(int i=0;i
Don_Yao整合修复一些bug后的代码
using System; using System.Collections; using System.Collections.Generic; using System.Text; // 解析计算字符串公式 namespace CalcuStrFormula { // 处理类 class Handler { private Stack _complexNumberStack = new Stack(); private Stack _operatorStack = new Stack(); private Parser _parser = new Parser(); private Operators _operators = new Operators(); private static Handler _instance; public static Handler instance { get { if (_instance == null) { _instance = new Handler(); } return _instance; } } public ComplexNumber Process(string inputString) { _complexNumberStack.Clear(); _operatorStack.Clear(); Queue queue = _parser.Parse(inputString); ComplexNumber complexNumber = null; char op, topOp; int count = queue.Count; for (int i = 0; iqueueChar = new Queue (); foreach (char x in arr) { queueChar.Enqueue(x); } Queue queueResult = ParseStringQueue(queueChar); return queueResult; } // 传入字符串队列,返回封装好的队列。 // ComplexNumber对象或char类型运算符各占用一个结点 private Queue ParseStringQueue(Queue queue) { Queue secOndQ= new Queue(); char c; StringBuilder sb = null; string temp; int count = queue.Count; bool flag = false; // false表示允许创建新SB对象进行缓存数字字符串 for (int i = 0; i = c.GetRealPart()) return this; return c; } // 转int public ComplexNumber ToFloorInt() { _realPart = Math.Floor(_realPart); return this; } public override string ToString() { return "(" + _realPart + " + " + _imaginPart + " i" + ")"; } } // 操作符类 class Operators { private char[][] _signOperator; public Operators() { // 从上到下,优先级由高到低 _signOperator = new char[4][]; _signOperator[0] = new char[4]; _signOperator[0][0] = '^'; _signOperator[0][1] = 's'; // 最小值 _signOperator[0][2] = 'b'; // 最大值 _signOperator[0][3] = 'i'; // int值 _signOperator[1] = new char[2]; _signOperator[1][0] = '*'; _signOperator[1][1] = '/'; _signOperator[2] = new char[2]; _signOperator[2][0] = '+'; _signOperator[2][1] = '-'; _signOperator[3] = new char[2]; _signOperator[3][0] = '('; _signOperator[3][1] = ')'; } // 比较操作符优先级 public int ComparePriority(char firstSign, char secondSign) { int priorityF = 0, priorityS = 0; for (int i = 0; i <_signOperator.Length; i++) { foreach (char x in _signOperator[i]) { if (firstSign == x) { priorityF = i; } if (secOndSign== x) { priorityS = i; } } } return (priorityF - priorityS); } // 是否是需要两个参数的操作符 public bool IsTwoNumOperator(char op) { if (op == 'i') return false; return true; } public bool Contains(char x) { if (x == '(' || x == ')') { UnityEngine.Debug.LogError(x + "为中文字符,请改为英文字符"); } foreach (char[] arr in _signOperator) { foreach (char y in arr) { if (x == y) { return true; } } } return false; } public ComplexNumber Compute(char op, ComplexNumber c1, ComplexNumber c2) { ComplexNumber result = null; switch (op) { case '+': result = c1.ComplexAdd(c2); break; case '-': result = c1.ComplexMinus(c2); break; case '*': result = c1.ComplexMulti(c2); break; case '/': result = c1.ComplexDivision(c2); break; case '^': result = c1.ComplexPow(c2); break; case 's': result = c1.ComplexMinimum(c2); break; case 'b': result = c1.ComplexMaximum(c2); break; case 'i': result = c2.ToFloorInt(); break; } return result; } } }
这篇文章就介绍到这了,希望能帮助到你。