資料結構相關複習—算術運算式求值演算法(帶括弧遞迴運算)

來源:互聯網
上載者:User

首先聲明,這僅僅是一個演算法的雛形,實用率幾乎為0。我只說這個思想。代碼是用java寫的,可以運行,但是運算式和中間值不能為負數【因為我用的java的字串截取,如果使用C語言的話,在不帶括弧的情況中,就沒有這個問題了,也可以為負數】,下面我寫出我的想法,然後你就知道為什麼不能為負數了。

第一:判斷有沒有括弧,有的話,遇到一個右括弧,那麼就截取對應的左括弧與右括弧之間的字串,還要讓字串加一個=。【因為沒有括弧的方法中限制的】

第二:如果現在只有加減乘除的話,比如說1+2*3+4+5-5=,就進入迴圈

第三:分為兩個棧,遇到一個符號的時候,先放數字棧資料,然後比較符號棧的頂部,與即將放入棧的符號,進行比較。如果即將進棧的優先順序比頂部的優先順序低,那麼

數字棧出兩個,符號棧出一個,進行計算,結果放到數字棧,即將放入棧的符號現在也放入棧。

第四:遇到等號的話,全部出棧。棧為空白的話,返回數字棧的第一個值。【即最終結果】

package 計算機;public class Demo {public double number[] = new double[6];// 數字棧public char sign[] = new char[6];// 符號棧,*/=優先順序大於+-優先順序public int topNum = -1;// 頭指標public int topSign = -1;// 頭指標// 運算式求值,帶括弧演算法,注意:運算式一定要正確,並且不能出現負數,因為這個演算法用的是字串截取public double evaluation(String string) throws Exception {// 參數代表正確的運算式double result = 0;// 如果式子中包含括弧,截取括弧匹配中的字串if (string.contains("(") || string.contains(")")) {int temp = 0;for (int i = 0; i < string.length(); i++) {if (string.charAt(i) == '(') {// 碰到左括弧,記錄下來temp = i;continue;}if (string.charAt(i) == ')') {// 碰到右括弧,進行遞迴,實際上相當於出棧string = string.substring(0, temp)+ evaluation(string.substring(temp + 1, i) + "=")// 加個等號繼續遞迴+ string.substring(i + 1);System.out.println(string);i = -1;continue;}}}// 現在式子中只有加減乘除的話,進行棧的操作for (int i = 0; i < string.length(); i++) {switch (string.charAt(i)) {case '+':case '-':case '*':case '/':case '=':result = calculate(string, i, string.charAt(i));string = string.substring(i + 1);i = -1;break;default:break;}}return result;}private double calculate(String string, int sub, char signal) {double x = Double.parseDouble(string.substring(0, sub));number[++topNum] = x;// 數字進棧if (topSign == -1) {// 如果符號棧為空白sign[++topSign] = signal;return number[topNum];}if (signal == '=') {// 計算數值while (topSign != -1) {if (sign[topSign] == '+') {number[topNum - 1] += number[topNum];} else if (sign[topSign] == '-') {number[topNum - 1] -= number[topNum];} else if (sign[topSign] == '*') {number[topNum - 1] *= number[topNum];} else if (sign[topSign] == '/') {number[topNum - 1] /= number[topNum];}topSign--;topNum--;// 退棧}return number[topNum];}if (comparePriority(signal, sign[topSign])) {// 退棧,並且將計算結果放入數字棧中if (sign[topSign] == '+') {number[topNum - 1] += number[topNum];} else if (sign[topSign] == '-') {number[topNum - 1] -= number[topNum];} else if (sign[topSign] == '*') {number[topNum - 1] *= number[topNum];} else if (sign[topSign] == '/') {number[topNum - 1] /= number[topNum];}sign[topSign] = signal;// 符號棧應該是topSign--【退棧】,然後++【進棧】,在這裡我們直接換符號了topNum--;// 退棧} else {sign[++topSign] = signal;// 進棧}return number[topNum];}/** * 比較a,b的優先順序if(a<==b)那麼返回true */boolean comparePriority(char a, char top) {boolean judge = false;if ((a == '+' || a == '-')&& (top == '+' || top == '-' || top == '*' || top == '/')) {judge = true;}if ((a == '*' || a == '/') && (top == '*' || top == '/')) {judge = true;}return judge;}public static void main(String[] args) {try {System.out.println(new Demo().evaluation("1*(2+3/(5-2))+4+5="));} catch (Exception e) {e.printStackTrace();System.out.println("對不起,運算式不是標準的正數運算運算式,過程值也不能為負");}}}

看到這裡,你可能會覺得我這個局限比較大,確實是這樣,這個確實比較水。因為還要考慮好多種情況,我只把這個演算法的思想寫了出來。真正要寫好這個運算式求值的話,還真是不容易。

如果哪位大哥能給我一個不錯的源碼,我就感激不盡了。

還有就是,我聽人說,這個帶括弧的,不用遞迴的話,可以用三個棧來進行操作,可能我智力有限吧,實在是想不出來怎麼操作三個棧才能算出來,哪個大哥指點一下,我就不勝感激了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.