1. 程式人生 > >藍橋杯-棧的應用-表示式的計算

藍橋杯-棧的應用-表示式的計算

問題描述
  輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。
輸入格式
  輸入一行,包含一個表示式。
輸出格式
  輸出這個表示式的值。
樣例輸入
1-2+3*(4-5)
樣例輸出
-4
資料規模和約定
  表示式長度不超過100,表示式運算合法且運算過程都在int內進行。

    這道題需要用到資料結構中棧的應用,利用棧的先進後出原理,先把中綴表示式轉換成字尾表示式,然後進行計算;例如:
    1+2+3*5+6  // 中綴表示式,意思是說運算子號在兩個數的中間
    1#2#+3#5#*+6
#+ // 字尾表示式。符號在兩個運算數後面,# 是為了區分數。

轉換為字尾表示式的過程為:

  1. 先定義兩個棧s1 和s2。s1表示用來儲存數字,s2 用來儲存符號。
  2. 遍歷表示式中的字元。
  3. 如果為數字,則直接入s1棧,如果當前下一個字元為符號的話需要在數字後面加上’#’,來區分數字;
  4. 如果為字元,當為’(’ 或 當前運算子的權值大於s2棧頂的符號元素的權值時可以直接入 s2 棧。
  5. 當遇到 ‘)’ 時,將s2 的棧頂元素依次出棧,然後依次儲存到s1 中,知道遇到 ‘(’ 時,‘(’出棧後停止出棧,‘(’不儲存到 s1 中。‘)’也不儲存到s2 中。就等於消去括號。
  6. 當權值小於棧頂元素時,也是s2 的元素依次出棧,知道當前元素大於棧頂元素後停止出棧,然後當前元素入s2 棧。
  7. 重複步驟 3~6,知道遍歷完所有元素。
  8. 將s2 中的所有元素依次出棧到 s1 棧中。轉換完畢。

得到運算結果的過程

  1. 顛倒s1 中的元素位置,s1依次出棧到s2 中。此時s1 為空,s2為後最表示式,下面將用s1儲存運算的數,s2 為表示式,宣告一個文字型變數num,用來拼接數字(用法見步驟3)。
  2. 將s2中的元素依次出棧。
  3. 如果是數字,並且s2棧頂元素是‘#’,那麼將元素轉換字元新增到num中,然後成後入s1棧並清空num用於下一個數字。如果還是數字,則用num加上當前陣列繼續下一次遍歷。
  4. 如果遇到運算子號,則將s1 中從棧頂出棧兩個元素,然後根據符號進行相應的運算(需要注意的是棧頂元素是第二個運算數,例如從棧頂依次出棧的數字為x , y, 在進行除運算時,需要y/x),然後將結果入s1 棧
  5. 重複上述步驟,直到s2 為空時,運算結束。

下面獻上渣渣程式碼:

import java.util.Scanner;
import java.util.Stack;
public class Main {
    //進行運算
    public static int yunSuan(char f,int x, int y){
        switch(f){
        case '-':
            return x-y;         
        case '+': 
            return x+y;
        case '*':
            return x*y;
        case '/':
            if(y == 0) {
                new ArithmeticException().printStackTrace();
                System.exit(0);
            }else{
                return x/y;
            }
        default :
            return 0;
        }
    }

    /**
     * 判斷是否為數字
     * 
     * @param n
     * @return
     */
    public static boolean judgeNum(char n) {
        if (n >= '0' && n <= '9')
            return true;
        return false;
    }

    /**
     * 返回各個符號的權值
     * 
     * @param c
     * @return
     */

    public static int quanZhi(char c) {
        int quan = 0;
        if (c == '+' || c == '-')
            quan = 1;
        else if (c == '*' || c == '/')
            quan = 2;
        else if(c == '(')
            quan = 3;
        return quan;
    }

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        char[] biaodashi = scan.next().toCharArray();
        scan.close();
        Stack s1 = new Stack(); // 儲存數字 48~57
        Stack s2 = new Stack(); // 儲存符號

        for (int i = 0; i < biaodashi.length; i++) {
            // 判斷是符號還是數字
            if (judgeNum(biaodashi[i])) {
                s1.push(biaodashi[i]);
//              System.out.println(biaodashi[i]);
                if (i == biaodashi.length - 1 || (!judgeNum(biaodashi[i + 1])))
                    s1.push('#');
            } else {
                if (s2.empty() || biaodashi[i] == '(' || quanZhi(biaodashi[i]) > quanZhi((char) s2.peek())) {
                    s2.push(biaodashi[i]);
//                  System.out.println(11111111);
                }else if(biaodashi[i] == ')'){
                    while (!s2.empty()) {
                        char c = (char)s2.pop();
                        if(c == '(')
                            break;
                        else{
                            s1.push(c);
//                          System.out.println(c+" 2 s1 push");
                        }
                    }
                }else if(quanZhi(biaodashi[i]) <= quanZhi((char) s2.peek())){
                    while (!s2.empty()) {
                        char c = (char)s2.peek();
                        if(quanZhi(biaodashi[i]) > quanZhi(c) || c == '('){
                            break;
                        }else{
                            s1.push((char)s2.pop());
                        }
//                      System.out.println(c+" 3 s1 push");
                    }
                    s2.push(biaodashi[i]);
                }
            }

        }
        // 將s2 中的 所有元素新增到s1 末尾
        while (!s2.empty()) {
            s1.push((char)s2.pop());
        }
        // 顛倒s1 的順序   儲存到s2 中
        while (!s1.empty()) {
            s2.push((char)s1.pop());
        }
//      String s1Str = "", s2Str="";
//      System.out.println("s1");
//      while (!s1.empty()) {
////            s1Str = s1.pop() + s1Str;
//          System.out.print(s1.pop());
////            s1Str += s1.pop();
//      }
//      System.out.println(s1Str);
//      System.out.println("s2");
//      while (!s2.empty()) {
////            s2Str = s2.pop() + s2Str;
//          System.out.print(s2.pop());
//      }
//      System.out.println(s2Str);      


        int result = 0; 
        String num = "";
        while(!s2.empty()){
            char c = (char) s2.pop();
            if(judgeNum(c)){
                num += String.valueOf(c);
                continue;
            }

            if(c == '#') {
                s1.push(Integer.parseInt(num));
//              System.out.println("s1 push "+num);
                num = "";
            }else{
                int y =(int) s1.pop();
                int x =(int) s1.pop();
                result = yunSuan(c, x, y);
                s1.push(new Integer(yunSuan(c, x, y)));
//              System.out.println("s1 push "+result);
            }
        }
        System.out.println(result);
    }
}

相關推薦

演算法-藍橋-演算法訓練 表示式計算 (JAVA)

1 引言什麼題。。。2 題目問題描述  輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。輸入格式  輸入一行,包含一個表示式。輸出格式  輸出這個表示式的值。樣例輸入1-2+3*(4-5)樣例輸出-4資料規模和約定  表示式長度不超過100,表示式運算

藍橋--演算法訓練 表示式計算

問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入

藍橋 演算法訓練 表示式計算

演算法訓練 表示式計算 時間限制:1.0s 記憶體限制:256.0MB 提交此題 問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的

藍橋-應用-表示式計算

問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出

表示式計算過程中的應用【轉】

棧在表示式計算過程中的應用 :建立運算元棧和運算子棧。運算子有優先順序。 規則:  自左至右掃描表示式,凡是遇到運算元一律進運算元棧。  當遇到運算子時,如果它的優先順序比運算子棧棧頂元素的優先順序高就進棧。反之,取出棧頂運算子和運算元棧棧頂的連續兩個運算元進行運算

藍橋-正則表示式

參考:當我們需要同時考慮“()”和“|”時,我們發現“()”括號的作用就是講上面的程式碼限定了一個範圍,所以我們只需要讓這段程式碼從一個“(”開始執行到一個“)”為止。那麼怎麼才能做到這種控制呢?我們可以分析一下樣例的計算過程。在遇到一個括號時,我們會先終止當前的計算,進入到

0x00資料結構——C語言實現(+字尾表示式計算

0x00資料結構——C語言實現(棧) 棧的實現 /* 棧(tack)是限制插入和刪除只能在一個位置上進行的表,該位置是表的末端,叫做棧的頂(top)。 對棧的基本操作有Push(進棧)和Pop(出棧)。 Functions: (在連結串列中增加

藍橋 演算法提高 概率計算 (概率DP)

  演算法提高 概率計算   時間限制:1.0s   記憶體限制:256.0MB 問題描述   生成n個∈[a,b]的隨機整數,輸出它們的和為x的概率。 輸入格式   一行輸入四個

藍橋:階乘計算

題目: 輸入一個正整數n,輸出n!的值。   其中n!=1*2*3*…*n。 演算法描述   n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A

藍橋 演算法提高 概率計算(Java解題)

問題描述  生成n個∈[a,b]的隨機整數,輸出它們的和為x的概率。輸入格式  一行輸入四個整數依次為n,a,b,x,用空格分隔。輸出格式  輸出一行包含一個小數位和為x的概率,小數點後保留四位小數樣例輸入2 1 3 4樣例輸出0.3333資料規模和約定  對於50%的資料,

藍橋演算法提高——概率計算(概率dp)

問題描述   生成n個∈[a,b]的隨機整數,輸出它們的和為x的概率。 輸入格式   一行輸入四個整數依次為n,a,b,x,用空格分隔。 輸出格式   輸出一行包含一個小數位和為x的概率,小數

藍橋之階乘計算(大數問題)

計算機 amp 當前 高精度 get rip sizeof scrip code Description 輸入一個正整數n,輸出n!的值。 其中n!=1*2*3*…*n。 算法描述 n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。

演算法訓練 表示式計算 ——藍橋

問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出 -4 資料規模和約定   表示式長度不超過1

藍橋_演算法訓練_表示式計算

  之前在學習棧的時候老師講過這個問題   思路就是:     1.將表示式(中綴式)轉化成字尾式;     2.進行字尾式的計算。    思路看起來很簡單,但是實際在敲程式碼的時候還是要注意很多問題。

藍橋——表示式計算(支援多位數運算的java實現)

問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出 -4 資料規模和約定   表示式長

Java實現表示式計算 藍橋

題目在這裡http://lx.lanqiao.cn/problem.page?gpid=T419 輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。 表示式計算雖然看起來挺簡單的,但是編碼起來也不是想象中的那麼容易。雖說上課的時候,有講過逆波蘭表示式,但是還沒動手實現

應用 - 後綴表達式的計算

structure str hub def csdn oid 應用 ref pri 有關棧API詳情參看我的還有一篇博文: 棧的鏈式存儲 - API實現 遍歷後綴表達式中的數字和符號 對於數字:進棧 對於符號: 從棧中彈出右操作數 從棧中彈出左操作數 依

17藍橋競賽題“承壓計算

pri tag ava print != decimal sys == stat public class JAVA17_3 { public static String formatFloatNumber(Double value) { if(

algo_156(藍橋) 表達式計算

+= 後序表達式 ase name urn cal break pen esp 問題描述   輸入一個只包含加減乖除和括號的合法表達式,求表達式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表達式。 輸出格式   輸出這個表達式的值。 樣例輸入 1-2+3*(4

第八屆藍橋JavaB---承壓計算

stat class 最小 註意 main 個數 scanner 之前 gpo 標題:承壓計算 X星球的高科技實驗室中整齊地堆放著某批珍貴金屬原料。 每塊金屬原料的外形、尺寸完全一致,但重量不同。 金屬材料被嚴格地堆放成金字塔形。