您好,登錄后才能下訂單哦!
本篇文章為大家展示了C#中怎么利用棧實現加減乘除運算,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
首先遇到左括號,直接壓入運算符棧,然后是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<count;i++){c = (char)queue.Dequeue();if(!Operators.Contains(c)){//如果掃描到的不是運算符,則將其加入到buffer尾部if(!flag){flag = true;sb = new StringBuilder();}sb.Append(c);}if(Operators.Contains(c) || queue.Count == 0){//如果掃描到的是運算符,則將緩沖區中的串加入隊尾if(sb != null && flag == true){temp = sb.ToString();try{if(temp.EndsWith("i")){if(temp.Length==1){secondQ.Enqueue(new ComplexNumber(0,1));}else{//i前有數字則開出數字部分。temp = temp.Substring(0,temp.Length-1);secondQ.Enqueue(new ComplexNumber(0,double.Parse(temp)));}}else{secondQ.Enqueue(new ComplexNumber(double.Parse(temp),0));}sb = null;flag = false;}catch(Exception e){Console.WriteLine("Error");}}//如果是運算符,則最后將運算符放入隊。if(Operators.Contains(c)){secondQ.Enqueue(c);}}}return secondQ;}}class ComplexNumber{private double m_dRealPart;private double m_dImaginPart;public ComplexNumber(){m_dRealPart = 0.0;m_dImaginPart = 0.0;}public ComplexNumber(double r,double i){m_dRealPart = r;m_dImaginPart = i;}public ComplexNumber(ComplexNumber c){m_dRealPart = c.GetRealPart();m_dImaginPart = c.GetImaginaryPart();}//get,set方法public double GetRealPart(){return m_dRealPart;}public double GetImaginaryPart(){ return m_dImaginPart;}public void SetRealPart(double d){ m_dRealPart = d;}public void SetImaginaryPart(double d){ m_dImaginPart = d;}public ComplexNumber ComplexAdd(ComplexNumber c){ return new ComplexNumber(this.m_dRealPart + c.GetRealPart(),this.m_dImaginPart + c.GetImaginaryPart());}public ComplexNumber ComplexAdd(double c){return new ComplexNumber( this.m_dRealPart + c,this.m_dImaginPart);}public ComplexNumber ComplexMinus(ComplexNumber c){ return new ComplexNumber(this.m_dRealPart - c.GetRealPart(),this.m_dImaginPart - c.GetImaginaryPart());}public ComplexNumber ComplexMinus(double c){return new ComplexNumber(this.m_dRealPart - c, this.m_dImaginPart);}//乘public ComplexNumber ComplexMulti(ComplexNumber c){return new ComplexNumber(this.m_dRealPart * c.GetRealPart()- this.m_dImaginPart * c.GetImaginaryPart(),this.m_dRealPart *c.GetImaginaryPart()+ this.m_dImaginPart *c.GetRealPart());}public ComplexNumber ComplexMulti(double c){returnnew ComplexNumber(this.m_dRealPart * c,this.m_dImaginPart * c);}//除public ComplexNumber ComplexDivision(ComplexNumber c){returnnew ComplexNumber((this.m_dRealPart*c.GetRealPart()+this.m_dImaginPart*c.GetImaginaryPart())/(c.GetRealPart()*c.GetRealPart()+c.GetImaginaryPart()*c.GetImaginaryPart()),(this.m_dImaginPart*c.GetRealPart()-this.m_dRealPart*c.GetImaginaryPart())/(c.GetRealPart()*c.GetRealPart()+c.GetImaginaryPart()*c.GetImaginaryPart()));}public ComplexNumber ComplexDivision(double c){return newComplexNumber(this.m_dRealPart/c,this.m_dImaginPart/c);}public override String ToString(){ return "(" + m_dRealPart + " + " + m_dImaginPart + " i" + ")";}}class Operators{static char[][] signOperator;static Operators(){signOperator = new char[3][];signOperator[0] = new char[2];signOperator[0][0]='*';signOperator[0][1]='/';signOperator[1] = new char[2];signOperator[1][0]='+';signOperator[1][1]='-';signOperator[2] = new char[2];signOperator[2][0]='(';signOperator[2][1]=')';}public static 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 static bool Contains(char x){foreach(char[] arr in signOperator){foreach(char y in arr){if(x == y){return true;}}}return false;}public static ComplexNumber Compute(char ope,ComplexNumber c1,ComplexNumber c2){ComplexNumber result = null;switch(ope){case '+':result=c1.ComplexAdd(c2);break;case '-':result=c2.ComplexMinus(c1);break;case '*':result=c1.ComplexMulti(c2);break;case '/':result=c1.ComplexDivision(c2);break;}return result;}}class Handler{private Stack complexNumberStack = new Stack();private Stack operatorStack = new Stack();private static Handler handler = new Handler();private Handler(){}public static Handler GetHandler(){return handler;}public ComplexNumber Process(string inputString){Queue queue = Parser.Parse(inputString);ComplexNumber complexNumber = null;char c,top,ct;int count = queue.Count;for(int i=0;i<count;i++){Object obj = queue.Dequeue();if(obj is char){c = (char)obj;if(operatorStack.Count == 0){operatorStack.Push(c);}else{top = (char)operatorStack.Peek();if(c=='('){operatorStack.Push(c); //左括號直接壓入。不判斷棧頂}else if(c==')'){//右括號壓入前觀察棧頂,若棧頂是左括號,則彈出棧頂的左括號//否則彈出棧頂運算符,從數棧中彈出操作數進行運算,并將結果重新壓入數棧,直到遇到左括號while((ct=(char)operatorStack.Pop())!='('){ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c3 = Operators.Compute(ct,c1,c2);complexNumberStack.Push(c3);}}else if(Operators.ComparePriority(top,c)<0){//若即將壓入的運算符不是括號,則比較棧頂運算符和即將壓入的運算符的優先級//如果棧頂優先級高,則將棧頂運算符取出運算,直到棧頂優先級不大于其。while(Operators.ComparePriority((char)operatorStack.Peek(),c)<0){ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c3 = Operators.Compute((char)operatorStack.Pop(),c1,c2);complexNumberStack.Push(c3);operatorStack.Push(c);}}else{operatorStack.Push(c);}}}else if(obj is ComplexNumber) {complexNumber = (ComplexNumber)obj;complexNumberStack.Push(complexNumber);}if(queue.Count == 0){if(operatorStack.Count != 0){while(operatorStack.Count != 0){c = (char)operatorStack.Pop();ComplexNumber c1 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c2 = (ComplexNumber)complexNumberStack.Pop();ComplexNumber c3 = Operators.Compute(c,c1,c2);complexNumberStack.Push(c3);}}}}return (ComplexNumber)complexNumberStack.Pop();}}class PrimeClass{static void Main(string[] args){String input;Handler handler = Handler.GetHandler();while(!(input = Console.ReadLine()).Equals("END")){ComplexNumber c = (ComplexNumber)handler.Process(input);Console.WriteLine(c);};}}}
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<object> queue = _parser.Parse(inputString); ComplexNumber complexNumber = null; char op, topOp; int count = queue.Count; for (int i = 0; i < count; i++) { object obj = queue.Dequeue(); if (obj is char) { op = (char)obj; if (_operatorStack.Count == 0) { _operatorStack.Push(op); } else { topOp = (char)_operatorStack.Peek(); if (op == '(') { _operatorStack.Push(op); // 左括號直接壓入。不判斷棧頂 } else if (op == ')') { // 右括號壓入前觀察棧頂,若棧頂是左括號,則彈出棧頂的左括號 // 否則彈出棧頂運算符,從數棧中彈出操作數進行運算,并將結果重新壓入數棧,直到遇到左括號 while ((topOp = (char)_operatorStack.Pop()) != '(') { ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符號右邊數 ComplexNumber c2 = null; // 符號左邊數 if (_operators.IsTwoNumOperator(topOp)) { c2 = (ComplexNumber)_complexNumberStack.Pop(); } ComplexNumber c3 = _operators.Compute(topOp, c2, c1); _complexNumberStack.Push(c3); } } else if (_operators.ComparePriority(topOp, op) <= 0) { // 若即將壓入的運算符不是括號,則比較棧頂運算符和即將壓入的運算符的優先級 // 如果棧頂優先級高,則將棧頂運算符取出運算,直到棧頂優先級不大于其。 while (_operatorStack.Count != 0 && _operators.ComparePriority((char)_operatorStack.Peek(), op) <= 0) { topOp = (char)_operatorStack.Pop(); ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符號右邊數 ComplexNumber c2 = null; // 符號左邊數 if (_operators.IsTwoNumOperator(topOp)) { c2 = (ComplexNumber)_complexNumberStack.Pop(); } ComplexNumber c3 = _operators.Compute(topOp, c2, c1); _complexNumberStack.Push(c3); } _operatorStack.Push(op); } else { _operatorStack.Push(op); } } } else if (obj is ComplexNumber) { complexNumber = (ComplexNumber)obj; _complexNumberStack.Push(complexNumber); } if (queue.Count == 0) { while (_operatorStack.Count != 0) { topOp = (char)_operatorStack.Pop(); ComplexNumber c1 = (ComplexNumber)_complexNumberStack.Pop(); // 符號右邊數 ComplexNumber c2 = null; // 符號左邊數 if (_operators.IsTwoNumOperator(topOp)) { c2 = (ComplexNumber)_complexNumberStack.Pop(); } ComplexNumber c3 = _operators.Compute(topOp, c2, c1); _complexNumberStack.Push(c3); } } } return (ComplexNumber)_complexNumberStack.Pop(); } } // 3+4i解析成Queue包含 3, +, 4i public class Parser { private Operators _operators = new Operators(); public Queue<object> Parse(string input) { input = input.Replace(" ", ""); if (input.StartsWith("-")) input = '0' + input; char[] arr = input.ToCharArray(); Queue<char> queueChar = new Queue<char>(); foreach (char x in arr) { queueChar.Enqueue(x); } Queue<object> queueResult = ParseStringQueue(queueChar); return queueResult; } // 傳入字符串隊列,返回封裝好的隊列。 // ComplexNumber對象或char類型運算符各占用一個結點 private Queue<object> ParseStringQueue(Queue<char> queue) { Queue<object> secondQ = new Queue<object>(); char c; StringBuilder sb = null; string temp; int count = queue.Count; bool flag = false; // false表示允許創建新SB對象進行緩存數字字符串 for (int i = 0; i < count; i++) { c = queue.Dequeue(); if (!_operators.Contains(c)) { // 如果掃描到的不是運算符,則將其加入到buffer尾部 if (!flag) { flag = true; sb = new StringBuilder(); } sb.Append(c); } if (_operators.Contains(c) || queue.Count == 0) { // 如果掃描到的是運算符,則將緩沖區中的串加入隊尾 if (sb != null && flag == true) { temp = sb.ToString(); try { if (temp.EndsWith("i")) { if (temp.Length == 1) { secondQ.Enqueue(new ComplexNumber(0, 1)); } else { // i前有數字則開出數字部分。 temp = temp.Substring(0, temp.Length - 1); secondQ.Enqueue(new ComplexNumber(0, double.Parse(temp))); } } else { secondQ.Enqueue(new ComplexNumber(double.Parse(temp), 0)); } sb = null; flag = false; } catch (Exception e) { UnityEngine.Debug.Log("Error " + e.ToString()); } } // 如果是運算符,則最后將運算符放入隊。 if (_operators.Contains(c)) { secondQ.Enqueue(c); } } } return secondQ; } } // 復數類,提供實數域虛數域,getset方法,加減乘除以及toString()方法 class ComplexNumber { private double _realPart; // 實數部分 private double _imaginPart; // 虛數部分 public ComplexNumber() { _realPart = 0.0; _imaginPart = 0.0; } public ComplexNumber(double r, double i) { _realPart = r; _imaginPart = i; } public ComplexNumber(ComplexNumber c) { _realPart = c.GetRealPart(); _imaginPart = c.GetImaginaryPart(); } // get,set方法 public double GetRealPart() { return _realPart; } public double GetImaginaryPart() { return _imaginPart; } public void SetRealPart(double d) { _realPart = d; } public void SetImaginaryPart(double d) { _imaginPart = d; } // 加 public ComplexNumber ComplexAdd(ComplexNumber c) { return new ComplexNumber(_realPart + c.GetRealPart(), _imaginPart + c.GetImaginaryPart()); } public ComplexNumber ComplexAdd(double c) { return new ComplexNumber(_realPart + c, _imaginPart); } // 減 public ComplexNumber ComplexMinus(ComplexNumber c) { return new ComplexNumber(_realPart - c.GetRealPart(), _imaginPart - c.GetImaginaryPart()); } public ComplexNumber ComplexMinus(double c) { return new ComplexNumber(_realPart - c, _imaginPart); } // 乘 public ComplexNumber ComplexMulti(ComplexNumber c) { return new ComplexNumber( _realPart * c.GetRealPart() - _imaginPart * c.GetImaginaryPart(), _realPart * c.GetImaginaryPart() + _imaginPart * c.GetRealPart()); } public ComplexNumber ComplexMulti(double c) { return new ComplexNumber(_realPart * c, _imaginPart * c); } // 除 public ComplexNumber ComplexDivision(ComplexNumber c) { return new ComplexNumber((_realPart * c.GetRealPart() + _imaginPart * c.GetImaginaryPart()) / (c.GetRealPart() * c.GetRealPart() + c.GetImaginaryPart() * c.GetImaginaryPart()) , (_imaginPart * c.GetRealPart() - _realPart * c.GetImaginaryPart()) / (c.GetRealPart() * c.GetRealPart() + c.GetImaginaryPart() * c.GetImaginaryPart())); } public ComplexNumber ComplexDivision(double c) { return new ComplexNumber(_realPart / c, _imaginPart / c); } // 冪 public ComplexNumber ComplexPow(ComplexNumber c) { int pow; if (int.TryParse(c.GetRealPart().ToString(), out pow)) { ComplexNumber origin = new ComplexNumber(this); ComplexNumber multi = new ComplexNumber(this); for (int i = 0; i < pow - 1; i++) { origin = origin.ComplexMulti(multi); } return origin; } else { return ComplexPow(c.GetRealPart()); } } public ComplexNumber ComplexPow(double c) { return new ComplexNumber(Math.Pow(_realPart, c), 0.0); } // 最小值 public ComplexNumber ComplexMinimum(ComplexNumber c) { if (_realPart <= c.GetRealPart()) return this; return c; } // 最大值 public ComplexNumber ComplexMaximum(ComplexNumber c) { if (_realPart >= 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; } }}
上述內容就是C#中怎么利用棧實現加減乘除運算,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。