国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++ 數(shù)據(jù)結(jié)構(gòu) 棧 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式并求值

這篇具有很好參考價(jià)值的文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu) 棧 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式并求值。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

寫(xiě)在前面,這里用的是我自己寫(xiě)的Stack類(lèi),并非STL,實(shí)現(xiàn)方法為靜態(tài)數(shù)組,但使用過(guò)程中的函數(shù)方法一樣,無(wú)傷大雅。(完整code和Stack_static類(lèi)賦在最后)

中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式:

1.從左到右遍歷

2.數(shù),即參與運(yùn)算數(shù),直接放進(jìn)后綴表達(dá)式之后

3.左括號(hào),直接壓入棧(因?yàn)槔ㄌ?hào)的優(yōu)先級(jí)最高,無(wú)需判斷)(入棧后優(yōu)先級(jí)最低,確保其它的符號(hào)正常入棧)

4.右括號(hào),意味著括號(hào)已經(jīng)結(jié)束,那么不斷彈出棧頂,直到遇到左括號(hào)。

5.運(yùn)算符,將該運(yùn)算符與棧頂運(yùn)算符進(jìn)行比較

????????如果優(yōu)先級(jí)高于棧頂運(yùn)算符則壓入堆棧

????????如果優(yōu)先級(jí)低于或等于棧頂運(yùn)算符則將棧頂運(yùn)算符彈出并放入后綴表達(dá)式中

????????***這里是核心,低于或等于棧頂元素意味著前面部分可以運(yùn)算了,先放入表達(dá)式,即先進(jìn)行運(yùn)算的一定是高優(yōu)先級(jí)的運(yùn)算符。

????????直到優(yōu)先級(jí)大于棧頂運(yùn)算符或者棧空,再將該運(yùn)算符入棧。

6.對(duì)字符串處理完畢后,則按順序彈出棧中所剩運(yùn)算符,放入表達(dá)式中

這里我給出一個(gè)例子:2+(3*(4-1))+3

C++ 數(shù)據(jù)結(jié)構(gòu) 棧 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式并求值

code中的棧類(lèi)是我自己寫(xiě)的類(lèi),不是STL中的,但功能大致一樣,

/*
返回運(yùn)算符的優(yōu)先級(jí)
*/
int value(char c){
    switch(c){
        case '(':
            return 0;
            break;
        case '+':
        case '-':
            return 1;
            break;
        case '*':
        case '/':
            return 2;
            break;
        default:
            cout<<"input error"<<endl;
            return 0;
    }
}

//將中綴表達(dá)式轉(zhuǎn)化成后綴表達(dá)式
string change(string str){
    string changed = "";
    Stack_static s;
    int opflag = 1;//記錄運(yùn)算符是否出現(xiàn),用于判斷-是負(fù)號(hào)還是減號(hào)。
    for(int i = 0; i < int(str.length());i++){
        if(str[i]>='0' && str[i]<='9'){//若為數(shù)字,則直接接到后綴表達(dá)式后面
            changed += str[i];
            opflag = 0;
        }
        else if(str[i]=='('){//若為左括號(hào),直接壓入棧
            s.push(str[i]);
        }
        else if(str[i]==')'){//若為右括號(hào),一直出棧接入后綴表達(dá)式,直到遇到左括號(hào)
            while(s.top()!='('){
                changed += ' ';
                changed += s.top();
                s.pop();
                if(s.empty())break;
            }
            s.pop();
        }
        else{
            if(opflag){
                changed += str[i];
                opflag = 0;
            }
            else{
                changed += ' ';//遇到正常的符號(hào),說(shuō)明一個(gè)數(shù)字已經(jīng)輸入完畢,所以加一個(gè)空格隔開(kāi)個(gè)個(gè)數(shù)字
                if(s.empty())s.push(str[i]);//若???,則直接入棧
                else if(value(str[i]) > value(s.top()))s.push(str[i]);//若優(yōu)先級(jí)大于棧頂,直接入棧
                else {//若優(yōu)先級(jí)小于等于前一個(gè),則不斷比較并出棧
                    while(value(str[i]) <= value(s.top())){
                        changed += s.top();
                        changed += ' ';
                        s.pop();
                        if(s.empty())break;//如果空了,退出循環(huán)
                    }
                    s.push(str[i]);
                }
                opflag = 1;
            }
        }
    }
    while(!s.empty()){//當(dāng)結(jié)束時(shí),棧不為空,則一個(gè)一個(gè)出棧
        changed += ' ';
        changed += s.top();
        s.pop();
    }
    return changed;//返回最終的后綴表達(dá)式
}

接下來(lái)是后綴表達(dá)式的求值方法

1.依舊是從左到右遍歷字符串

2.數(shù),這次的數(shù)的處理是直接壓入棧

3.符號(hào),若是空格,則將前面保存的數(shù)壓入棧(因?yàn)閿?shù)可能是多位數(shù),所以不能直接壓入棧,有別于轉(zhuǎn)后綴。所以我們需要一個(gè)數(shù)來(lái)保存字符輸進(jìn)來(lái)的數(shù)字。)

4.運(yùn)算符,碰到一個(gè)運(yùn)算符,我們就進(jìn)行一次計(jì)算,對(duì)棧頂?shù)膬蓚€(gè)數(shù)字進(jìn)行計(jì)算,這也就是后綴表達(dá)式的計(jì)算原理

接下來(lái)舉個(gè)例子,式子與上面的相同

后綴表達(dá)式為2 3 4 1-* 3++

C++ 數(shù)據(jù)結(jié)構(gòu) 棧 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式并求值

最后所剩的14即為最終答案,直接輸出即可

下面是實(shí)現(xiàn)的代碼

//計(jì)算兩個(gè)數(shù),用于彈出的運(yùn)算符和兩個(gè)數(shù)
double calculate(double x,double y,char c){
    switch (c)
    {
    case '+':
        return x+y;
        break;
    case '-':
        return x-y;
        break;
    case '*':
        return x*y;
        break;
    case '/':
        if(!y){
            cerr<<"除數(shù)不能為0"<<endl;
            exit(0);
        }
        return x/y;
        break;
    default:
        cerr<<"input error"<<endl;
        exit(0);
        break;
    }
}

//計(jì)算后綴表達(dá)式的值
double result(string str){
    Stack_static S_num;
    int num = 0,flag = 0,fu_flag = 0;
    for(int i = 0;i < int(str.length());i++){
        if(str[i]>='0' && str[i]<='9'){//遇到數(shù)字存入num中
            num = num*10 + str[i]-'0';
            flag = 1;//flag用來(lái)記錄現(xiàn)在數(shù)字是否存在
        }
        else{
            if(flag){//避免連續(xù)讀入字符時(shí),數(shù)字棧中存入多個(gè)0
                if(fu_flag)//如果是負(fù)數(shù)
                    S_num.push(-double(num));
                else
                    S_num.push(double(num));
                flag = 0;
                fu_flag = 0;
                num = 0;//置0
            }
            if(str[i]==' '){
                fu_flag = 0;
                continue;
            }
            if(str[i]=='-' && str[i+1]>='0' && str[i+1]<='9'){
                fu_flag = 1;
                continue;
            }
            
            double a,b;
            a = S_num.top();//取出棧頂
            S_num.pop();
            b = S_num.top();//取出棧頂
            S_num.pop();
            S_num.push(calculate(b,a,str[i]));//計(jì)算后壓入棧
        }
    }
    return S_num.top();
}

我的Stack_static類(lèi),是靜態(tài)數(shù)組的實(shí)現(xiàn)

#include<iostream>
const int STACK_MAX = 128;
typedef int StackElement;
class Stack_static
{
private:
    StackElement myArray[STACK_MAX];
    int myTop;
public:
    Stack_static();
    ~Stack_static();
    void push(const StackElement &value);
    void pop();
    StackElement top();
    bool empty();
    void display(std::ostream & out);
    int get_myTop(){
        return myTop;
    }
    StackElement bottom();
};

Stack_static::Stack_static()
{
    myTop = -1;
}

Stack_static::~Stack_static()
{
}

bool Stack_static::empty(){
    if(myTop==-1)return true;
    return false;
}

StackElement Stack_static::top(){
    if( !empty())
        return myArray[myTop];
    else{
        std::cerr << "*** Stack is empty -- return ***\n";
        StackElement garbage=0;
        return garbage;
    }
}

void Stack_static::push(const StackElement &value){
    if(myTop < STACK_MAX-1){
        myTop++;
        myArray[myTop] = value;
    }
    else{
        std::cerr << "*** Stack full -- can't add new value ***\n";
        exit(1);
    }
}

void Stack_static::pop(){
    if(!empty())
        myTop--;
    else    
        std::cerr << "*** Stack is empty***\n";
}

void Stack_static::display(std::ostream &out){

    
    for(int i = myTop-1;i >= 0; i-- ){
        out<< myArray[i] << std::endl;
    }
}

StackElement Stack_static::bottom(){
    if(!empty()){
        return myArray[0];
    }
    else{
        std::cerr<<"*** Stack is empty!***\n";
        StackElement garbage=0;
        return garbage;
    }
}

整個(gè)代碼以及測(cè)試:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-434920.html

#include"Stack_static.h"
#include<iostream>
using namespace std;

//簡(jiǎn)易計(jì)算器,只包含+-*/()

/*
返回運(yùn)算符的優(yōu)先級(jí)
*/
int value(char c){
    switch(c){
        case '(':
            return 0;
            break;
        case '+':
        case '-':
            return 1;
            break;
        case '*':
        case '/':
            return 2;
            break;
        default:
            cout<<"input error"<<endl;
            return 0;
    }
}

//計(jì)算兩個(gè)數(shù),用于彈出的運(yùn)算符和兩個(gè)數(shù)
double calculate(double x,double y,char c){
    switch (c)
    {
    case '+':
        return x+y;
        break;
    case '-':
        return x-y;
        break;
    case '*':
        return x*y;
        break;
    case '/':
        if(!y){
            cerr<<"除數(shù)不能為0"<<endl;
            exit(0);
        }
        return x/y;
        break;
    default:
        cerr<<"input error"<<endl;
        exit(0);
        break;
    }
}

//將中綴表達(dá)式轉(zhuǎn)化成后綴表達(dá)式
string change(string str){
    string changed = "";
    Stack_static s;
    int opflag = 1;//記錄運(yùn)算符是否出現(xiàn),用于判斷-是負(fù)號(hào)還是減號(hào)。
    for(int i = 0; i < int(str.length());i++){
        if(str[i]>='0' && str[i]<='9'){//若為數(shù)字,則直接接到后綴表達(dá)式后面
            changed += str[i];
            opflag = 0;
        }
        else if(str[i]=='('){//若為左括號(hào),直接壓入棧
            s.push(str[i]);
        }
        else if(str[i]==')'){//若為右括號(hào),一直出棧接入后綴表達(dá)式,直到遇到左括號(hào)
            while(s.top()!='('){
                changed += ' ';
                changed += s.top();
                s.pop();
                if(s.empty())break;
            }
            s.pop();
        }
        else{
            if(opflag){
                changed += str[i];
                opflag = 0;
            }
            else{
                changed += ' ';//遇到正常的符號(hào),說(shuō)明一個(gè)數(shù)字已經(jīng)輸入完畢,所以加一個(gè)空格隔開(kāi)個(gè)個(gè)數(shù)字
                if(s.empty())s.push(str[i]);//若??眨瑒t直接入棧
                else if(value(str[i]) > value(s.top()))s.push(str[i]);//若優(yōu)先級(jí)大于棧頂,直接入棧
                else {//若優(yōu)先級(jí)小于等于前一個(gè),則不斷比較并出棧
                    while(value(str[i]) <= value(s.top())){
                        changed += s.top();
                        changed += ' ';
                        s.pop();
                        if(s.empty())break;//如果空了,退出循環(huán)
                    }
                    s.push(str[i]);
                }
                opflag = 1;
            }
        }
    }
    while(!s.empty()){//當(dāng)結(jié)束時(shí),棧不為空,則一個(gè)一個(gè)出棧
        changed += ' ';
        changed += s.top();
        s.pop();
    }
    return changed;//返回最終的后綴表達(dá)式
}

//計(jì)算后綴表達(dá)式的值
double result(string str){
    Stack_static S_num;
    int num = 0,flag = 0,fu_flag = 0;
    for(int i = 0;i < int(str.length());i++){
        if(str[i]>='0' && str[i]<='9'){//遇到數(shù)字存入num中
            num = num*10 + str[i]-'0';
            flag = 1;//flag用來(lái)記錄現(xiàn)在數(shù)字是否存在
        }
        else{
            if(flag){//避免連續(xù)讀入字符時(shí),數(shù)字棧中存入多個(gè)0
                if(fu_flag)//如果是負(fù)數(shù)
                    S_num.push(-double(num));
                else
                    S_num.push(double(num));
                flag = 0;
                fu_flag = 0;
                num = 0;//置0
            }
            if(str[i]==' '){
                fu_flag = 0;
                continue;
            }
            if(str[i]=='-' && str[i+1]>='0' && str[i+1]<='9'){
                fu_flag = 1;
                continue;
            }
            
            double a,b;
            a = S_num.top();//取出棧頂
            S_num.pop();
            b = S_num.top();//取出棧頂
            S_num.pop();
            S_num.push(calculate(b,a,str[i]));//計(jì)算后壓入棧
        }
    }
    return S_num.top();
}

//測(cè)試代碼
int main(){
    string a;
    cout << "Infix expression?";
    cin >> a;
    cout << "Postfix expression is " << change(a) << endl;
    cout << "Result:" << result(change(a));
    return 0;
}

到了這里,關(guān)于C++ 數(shù)據(jù)結(jié)構(gòu) 棧 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式并求值的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【尚硅谷】數(shù)據(jù)結(jié)構(gòu)和算法——前綴、中綴、后綴表達(dá)式規(guī)則

    【尚硅谷】數(shù)據(jù)結(jié)構(gòu)和算法——前綴、中綴、后綴表達(dá)式規(guī)則

    跟著B(niǎo)站的尚硅谷學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法,語(yǔ)言為java,目前是第七個(gè)代碼內(nèi)容——前綴、中綴、后綴表達(dá)式 課程傳送門(mén):尚硅谷——前綴、中綴、后綴表達(dá)式 1)前綴表達(dá)式又稱波蘭式, 前綴表達(dá)式 的運(yùn)算符位于操作符之前。 2)舉例說(shuō)明:(3+4)*5-6 對(duì)應(yīng)的前綴表達(dá)式就是 - *

    2024年02月03日
    瀏覽(20)
  • 數(shù)據(jù)結(jié)構(gòu)——前綴、中綴、后綴表達(dá)式實(shí)現(xiàn)和轉(zhuǎn)換(Java)

    數(shù)據(jù)結(jié)構(gòu)——前綴、中綴、后綴表達(dá)式實(shí)現(xiàn)和轉(zhuǎn)換(Java)

    1.7.1 概念 它們都是對(duì)表達(dá)式的記法,因此也被稱為前綴記法、中綴記法和后綴記法。它們之間的區(qū)別在于 運(yùn)算符相對(duì)與操作數(shù)的位置 不同 前綴 表達(dá)式的運(yùn)算符位于與其相關(guān)的 操作數(shù)之前 ;中綴和后綴同理。 平時(shí)我們 日常使用 并最為熟悉的就是中綴表達(dá)式。如: 1 + 2 *

    2024年02月05日
    瀏覽(28)
  • 【數(shù)據(jù)結(jié)構(gòu)】超詳細(xì)講解:算術(shù)表達(dá)式轉(zhuǎn)化為后綴表達(dá)式、前綴表達(dá)式、表達(dá)式樹(shù)的構(gòu)建

    【數(shù)據(jù)結(jié)構(gòu)】超詳細(xì)講解:算術(shù)表達(dá)式轉(zhuǎn)化為后綴表達(dá)式、前綴表達(dá)式、表達(dá)式樹(shù)的構(gòu)建

    作者: 努力學(xué)習(xí)的大一在校計(jì)算機(jī)專業(yè)學(xué)生,熱愛(ài)學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:算法、數(shù)據(jù)結(jié)構(gòu)、Java等相關(guān)知識(shí)。 博主主頁(yè): @是瑤瑤子啦 所屬專欄: 【數(shù)據(jù)結(jié)構(gòu)】:該專欄專注于數(shù)據(jù)結(jié)構(gòu)知識(shí),持續(xù)更新,每一篇內(nèi)容優(yōu)質(zhì),淺顯易懂,不失深度! 近期目標(biāo): 寫(xiě)好專欄

    2024年02月08日
    瀏覽(17)
  • 數(shù)據(jù)結(jié)構(gòu)之表達(dá)式求值

    數(shù)據(jù)結(jié)構(gòu)之表達(dá)式求值

    ?前言 運(yùn)用堆棧解決表達(dá)式的求值,代碼思路為: 1.定義兩個(gè)棧,一個(gè)char類(lèi)型的棧用于存放運(yùn)算符(ysf)一個(gè)int類(lèi)型的棧用于存放操作數(shù)(czs) 如一個(gè)表達(dá)式3+6*9,將“+”,“*”入ysf棧,將“3”“6”“9”入czs棧 2.運(yùn)用getchar進(jìn)行數(shù)據(jù)的錄入,如果接收的是運(yùn)算符,將其插入到運(yùn)

    2024年04月29日
    瀏覽(18)
  • 數(shù)據(jù)結(jié)構(gòu) 實(shí)驗(yàn)2——表達(dá)式求值

    數(shù)據(jù)結(jié)構(gòu) 實(shí)驗(yàn)2——表達(dá)式求值

    一、實(shí)驗(yàn)名稱:表達(dá)式求值 二、實(shí)驗(yàn)學(xué)時(shí): 6 學(xué)時(shí) 三、實(shí)驗(yàn)?zāi)康?1.理解棧的結(jié)構(gòu)特點(diǎn)和基本操作特性; 2.掌握利用棧實(shí)現(xiàn)表達(dá)式求值算法。 四、實(shí)驗(yàn)內(nèi)容 ( 步驟 ) 輸入一個(gè)算術(shù)表達(dá)式(以“=”結(jié)束),求其值。要求表達(dá)式以“=”結(jié)束,操作數(shù)為多位實(shí)數(shù),對(duì)錯(cuò)誤表達(dá)式要進(jìn)行

    2023年04月08日
    瀏覽(19)
  • 數(shù)據(jù)結(jié)構(gòu) | 后綴表達(dá)式【深入剖析堆棧原理】

    數(shù)據(jù)結(jié)構(gòu) | 后綴表達(dá)式【深入剖析堆棧原理】

    Hello,大家好,國(guó)慶的第二天,帶來(lái)的是數(shù)據(jù)結(jié)構(gòu)中堆棧部分的后綴表達(dá)式,這也是一塊有關(guān)棧的應(yīng)用方面困擾了眾多同學(xué)的一個(gè)大難題,今天就讓我們一起解決這個(gè)難題?? 后綴表達(dá)式也稱為 逆波蘭表達(dá)式 ,也就是將算術(shù)運(yùn)算符放在操作數(shù)的后面 例如【1 + 2 * 3】的后綴表達(dá)

    2023年04月27日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)】12 堆棧應(yīng)用:表達(dá)式求值

    【數(shù)據(jù)結(jié)構(gòu)】12 堆棧應(yīng)用:表達(dá)式求值

    有一個(gè)常量表達(dá)式的中綴表達(dá)式為:5 + 6 / 2 - 3 * 4,其后綴形式表示為: 5 6 2 / + 3 4 × -。后綴表達(dá)式的特點(diǎn)是運(yùn)算符位于兩個(gè)預(yù)算數(shù)之后。其前綴表達(dá)式為: - + 5 / 6 2 × 3 4。 后綴表達(dá)式相比于中綴表達(dá)式的求值要容易很多。 從左到右掃描該表達(dá)式: (1)遇見(jiàn)運(yùn)算數(shù)5 6 2時(shí)不

    2024年02月20日
    瀏覽(31)
  • 【數(shù)據(jù)結(jié)構(gòu)】反射、枚舉以及l(fā)ambda表達(dá)式

    Java的反射(reflection)機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任 意一個(gè)對(duì)象,都能夠調(diào)用它的任意方法和屬性,既然能拿到那么,我們就可以修改部分類(lèi)型信息;這種動(dòng)態(tài)獲取信 息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為java語(yǔ)言的反射

    2024年03月13日
    瀏覽(28)
  • 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

    中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

    ??一種不需要括號(hào)的后綴表達(dá)法,也把它稱為 逆波蘭 表示,是波蘭邏輯學(xué)家盧卡西維奇(Lukasiewicz)發(fā)明的一種表示表達(dá)式的方法。 ??中綴表達(dá)式指的是“9+(3-1)×3+8÷2”,這種就是我們通常見(jiàn)到的書(shū)寫(xiě)算式順序,要計(jì)算中綴表達(dá)式則首先要將字符串轉(zhuǎn)換為后綴表達(dá)式,即

    2023年04月08日
    瀏覽(17)
  • 【數(shù)據(jù)結(jié)構(gòu)】你知道波蘭表達(dá)式和逆波蘭表達(dá)式嗎?我才知道原來(lái)?xiàng)T诒磉_(dá)式求值中還能這樣使用……

    【數(shù)據(jù)結(jié)構(gòu)】你知道波蘭表達(dá)式和逆波蘭表達(dá)式嗎?我才知道原來(lái)?xiàng)T诒磉_(dá)式求值中還能這樣使用……

    大家好,很高興又和大家見(jiàn)面啦?。?! 在前面的內(nèi)容中我們?cè)敿?xì)介紹了棧的第一種應(yīng)用——在括號(hào)匹配問(wèn)題中的應(yīng)用,如果還沒(méi)有閱讀過(guò)的朋友可以回看前面兩篇文章。在今天的內(nèi)容中我們將介紹棧的另一種應(yīng)用——在表達(dá)式求值中的應(yīng)用。 表達(dá)式相信大家應(yīng)該不陌生了,

    2024年04月27日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包