表達式計算(藍橋杯)


 

問題描述
  輸入一個只包含加減乖除和括號的合法表達式,求表達式的值。其中除表示整除。
輸入格式
  輸入一行,包含一個表達式。
輸出格式
  輸出這個表達式的值。
樣例輸入
1-2+3*(4-5)
樣例輸出
-4
數據規模和約定
  表達式長度不超過100,表達式運算合法且運算過程都在int內進行。
 
分析(起初不會做,在網上找的題解,分析的很詳細,講了先轉換為
中綴表達式,在轉換為后綴表達式,主要是入棧和出棧):

1.將中綴表達式轉換為后綴表達式的方法:
(1) 初始化兩個棧:運算符棧S1和儲存中間結果的棧S2;
(2) 從左至右掃描中綴表達式;
(3) 遇到操作數時,將其壓入S2,這里由於運算數可能大於10,所以如果數字后面一個符號是運算符,則將‘#’入S2棧充當分割線;
(4) 遇到運算符時有三種情況:
(4-1) 三種情況下直接入S1棧①S1為空②運算符為‘(’③運算符優先級比S1棧頂運算符的高;
(4-2)如果右括號“)”,則依次彈出S1棧頂的運算符,並壓入S2,直到遇到左括號為止,此時將這一對括號丟棄;
(4-3) 若運算符優先級小於或等於S1棧頂運算符的優先級,則依次彈出S1棧頂元素,直到運算符的優先級大於S1棧頂運算符優先級;
(6) 重復步驟(2)至(5),直到表達式的最右邊;
(7) 將S1中剩余的運算符依次彈出並壓入S2;
(8) 依次彈出S2中的元素並輸出,結果的逆序即為中綴表達式對應的后綴表達式。

運算符優先級: 左括號>(乘=除)>(加=減)>右括號  為了編程方便假定右括號優先級最小。

例:將 1 + ( ( 23 + 34 ) * 5 ) - 6轉化為中綴表達式

 

所以計算結果為:1 # 2 3 # 3 4 # + 5 # * + 6 # -

 

2.后綴表達式計算方法:

(1)定義一個int棧S3,定義一個整形數組num用來存儲大於10的數字便於計算,從左至右掃描表達式。

(2)遇到數字時:

(2-1)若數字后面一個元素不是#(數字后面只可能是#或數字)則將數字字符轉化為數字存在num[ ]數組中;

(2-2)若數字后面一個元素是#,將num數組中保存的數字算出來並壓入S3棧中。

(3)遇到運算符時,彈出S3棧頂的兩個數,用運算符對它們做相應的計算(次頂元素 op 棧頂元素),並將結果入棧;重復上述過程直到表達式最右端,最后運算得出的值即為表達式的結果。

例如后綴表達式“1 # 2 3 # 3 4 # + 5 # * + 6 # -”:

所以最后計算的結果為280
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;

int bb0(int a,int b,char c)
{
    if(c=='+')
        return a+b;
    if(c=='-')
        return a-b;
    if(c=='*')
        return a*b;
    if(c=='/')
        return a/b;
}

void bb1(char a[105],char b[105],char c[100])
{
    int k=0,l=0,flag=0;
    for(int i=0;a[i]!='\0';i++)
    {
        if(a[i]>='0'&&a[i]<='9')
        {
            b[k++]=a[i];
            if(a[i+1]<'0'||a[i+1]>'9')
                b[k++]='#';
        }    
        else if(a[i]==')')
        {
            while(c[--l]!='(')
            {
                b[k++]=c[l];
            }    
        }
        else
        {
            if(l>0)
            {
                if(a[i]=='+'||a[i]=='-')
                {
                    if(c[l-1]!='(')
                    {
                        b[k++]=c[--l];
                    }
                }
                if(a[i]=='*'||a[i]=='/')
                {
                    if(c[i-1]=='*'||c[i-1]=='/')
                        b[k++]=c[--l];
                }
            }
            c[l++]=a[i];
        }
    }    
    while(l>0)
    {
        b[k++]=c[--l];
    }
    b[k]='\0';
}

void bb2(char b[105],int d[50])
{
    int c=0,l=0;
    for(int i=0;b[i]!='\0';i++)
    {
        if(b[i]<='9'&&b[i]>='0')
        {
            c=c*10+(b[i]-'0');
        }
        else if(b[i]=='#')
        {
            d[l++]=c;
            c=0;        
        }
        else
        {
            d[l-2]=bb0(d[l-2],d[l-1],b[i]);
            l=l-1;
        }        
    }
}

int main()
{
    char a[105];
    char b[105]={' '};
    char c[100]={' '};
    int d[50];
    cin>>a;
    bb1(a,b,c);
    bb2(b,d);
    cout<<d[0]<<endl;
    return 0;
}

代碼是看了題解后才寫出來的,題解也直接粘貼復制過來了,方便以后復習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM