最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之前綴,中綴和后綴表達(dá)式

 更新時(shí)間:2022年01月20日 15:36:52   作者:YSOcean  
這篇文章主要為大家介紹了Java的前綴,中綴和后綴表達(dá)式 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

1、人如何解析算術(shù)表達(dá)式

如何解析算術(shù)表達(dá)式?或者換種說法,遇到某個(gè)算術(shù)表達(dá)式,我們是如何計(jì)算的:

①、求值 3+4-5

  

這個(gè)表達(dá)式,我們在看到3+4后都不能直接計(jì)算3+4的值,知道看到4后面的 - 號,因?yàn)闇p號的優(yōu)先級和前面的加號一樣,所以可以計(jì)算3+4的值了,如果4后面是 * 或者 /,那么就要在乘除過后才能做加法操作,比如:

②、求值 3+4*5

這個(gè)不能先求3+4的值,因?yàn)?后面的*運(yùn)算級別比前面的+高。通過這兩個(gè)表達(dá)式的說明,我們可以總結(jié)解析表達(dá)式的時(shí)候遵循的幾條規(guī)則:

  • ①、從左到右讀取算式。
  • ②、已經(jīng)讀到了可以計(jì)算值的兩個(gè)操作數(shù)和一個(gè)操作符時(shí),可以計(jì)算,并用計(jì)算結(jié)果代替那兩個(gè)操作數(shù)和一個(gè)操作符。
  • ③、繼續(xù)這個(gè)過程,從左到右,能算就算,直到表達(dá)式的結(jié)尾。

2、計(jì)算機(jī)如何解析算術(shù)表達(dá)式

對于前面的表達(dá)式 3+4-5,我們?nèi)耸怯兴季S能力的,能根據(jù)操作符的位置,以及操作符的優(yōu)先級別能算出該表達(dá)式的結(jié)果。但是計(jì)算機(jī)怎么算?

計(jì)算機(jī)必須要向前(從左到右)來讀取操作數(shù)和操作符,等到讀取足夠的信息來執(zhí)行一個(gè)運(yùn)算時(shí),找到兩個(gè)操作數(shù)和一個(gè)操作符進(jìn)行運(yùn)算,有時(shí)候如果后面是更高級別的操作符或者括號時(shí),就必須推遲運(yùn)算,必須要解析到后面級別高的運(yùn)算,然后回頭來執(zhí)行前面的運(yùn)算。我們發(fā)現(xiàn)這個(gè)過程是極其繁瑣的,而計(jì)算機(jī)是一個(gè)機(jī)器,只認(rèn)識高低電平,想要完成一個(gè)簡單表達(dá)式的計(jì)算,我們可能要設(shè)計(jì)出很復(fù)雜的邏輯電路來控制計(jì)算過程,那更不用說很復(fù)雜的算術(shù)表達(dá)式,所以這樣來解析算術(shù)表達(dá)式是不合理的,那么我們應(yīng)該采取什么辦法呢?

請大家先看看什么是前綴表達(dá)式,中綴表達(dá)式,后綴表達(dá)式:這三種表達(dá)式其實(shí)就是算術(shù)表達(dá)式的三種寫法,以 3+4-5為例

  • ①、前綴表達(dá)式:操作符在操作數(shù)的前面,比如 +-543
  • ②、中綴表達(dá)式:操作符在操作數(shù)的中間,這也是人類最容易識別的算術(shù)表達(dá)式 3+4-5
  • ③、后綴表達(dá)式:操作符在操作數(shù)的后面,比如 34+5-

上面我們講的人是如何解析算術(shù)表達(dá)式的,也就是解析中綴表達(dá)式,這是人最容易識別的,但是計(jì)算機(jī)不容易識別,計(jì)算機(jī)容易識別的是前綴表達(dá)式和后綴表達(dá)式,將中綴表達(dá)式轉(zhuǎn)換為前綴表達(dá)式或者后綴表達(dá)式之后,計(jì)算機(jī)能很快計(jì)算出表達(dá)式的值,那么中綴表達(dá)式是如何轉(zhuǎn)換為前綴表達(dá)式和后綴表達(dá)式,以及計(jì)算機(jī)是如何解析前綴表達(dá)式和后綴表達(dá)式來得到結(jié)果的呢?

3、后綴表達(dá)式

后綴表達(dá)式,指的是不包含括號,運(yùn)算符放在兩個(gè)運(yùn)算對象的后面,所有的計(jì)算按運(yùn)算符出現(xiàn)的順序,嚴(yán)格從左向右進(jìn)行(不再考慮運(yùn)算符的優(yōu)先規(guī)則)。

由于后綴表達(dá)式的運(yùn)算符在兩個(gè)操作數(shù)的后面,那么計(jì)算機(jī)在解析后綴表達(dá)式的時(shí)候,只需要從左向右掃描,也就是只需要向前掃描,而不用回頭掃描,遇到運(yùn)算符就將運(yùn)算符放在前面兩個(gè)操作符的中間(這里先不考慮乘方類似的單目運(yùn)算),一直運(yùn)算到最右邊的運(yùn)算符,那么就得出運(yùn)算結(jié)果了。既然后綴表達(dá)式這么好,那么問題來了:

①、如何將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式?

對于這個(gè)問題,轉(zhuǎn)換的規(guī)則如下:

一、先自定義一個(gè)棧

package com.ys.poland;
public class MyCharStack {
    private char[] array;
    private int maxSize;
    private int top;
    public MyCharStack(int size){
        this.maxSize = size;
        array = new char[size];
        top = -1;
    }
    //壓入數(shù)據(jù)
    public void push(char value){
        if(top < maxSize-1){
            array[++top] = value;
        }
    }
    //彈出棧頂數(shù)據(jù)
    public char pop(){
        return array[top--];
    }
    //訪問棧頂數(shù)據(jù)
    public char peek(){
        return array[top];
    }
    //查看指定位置的元素
    public char peekN(int n){
        return array[n];
    }
    //為了便于后面分解展示棧中的內(nèi)容,我們增加了一個(gè)遍歷棧的方法(實(shí)際上棧只能訪問棧頂元素的)
    public void displayStack(){
        System.out.print("Stack(bottom-->top):");
        for(int i = 0 ; i < top+1; i++){
            System.out.print(peekN(i));
            System.out.print(' ');
        }
        System.out.println("");
    }
    //判斷棧是否為空
    public boolean isEmpty(){
        return (top == -1);
    }
    //判斷棧是否滿了
    public boolean isFull(){
        return (top == maxSize-1);
    }
}

二、前綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式

package com.ys.poland;
public class InfixToSuffix {
    private MyCharStack s1;//定義運(yùn)算符棧
    private MyCharStack s2;//定義存儲(chǔ)結(jié)果棧
    private String input;
    //默認(rèn)構(gòu)造方法,參數(shù)為輸入的中綴表達(dá)式
    public InfixToSuffix(String in){
        input = in;
        s1 = new MyCharStack(input.length());
        s2 = new MyCharStack(input.length());
    }
    //中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式,將結(jié)果存儲(chǔ)在棧中返回,逆序顯示即后綴表達(dá)式
    public MyCharStack doTrans(){
        for(int j = 0 ; j < input.length() ; j++){
            System.out.print("s1棧元素為:");
            s1.displayStack();
            System.out.print("s2棧元素為:");
            s2.displayStack();
            char ch = input.charAt(j);
            System.out.println("當(dāng)前解析的字符:"+ch);
            switch (ch) {
            case '+':
            case '-':
                gotOper(ch,1);
                break;
            case '*':
            case '/':
                gotOper(ch,2);
                break;
            case '(':
                s1.push(ch);//如果當(dāng)前字符是'(',則將其入棧
                break;
            case ')':
                gotParen(ch);
                break;
            default:
                //1、如果當(dāng)前解析的字符是操作數(shù),則直接壓入s2
                //2、
                s2.push(ch);
                break;
            }//end switch
        }//end for
        while(!s1.isEmpty()){
            s2.push(s1.pop());
        }
        return s2;
    }
    public void gotOper(char opThis,int prec1){
        while(!s1.isEmpty()){
            char opTop = s1.pop();
            if(opTop == '('){//如果棧頂是'(',直接將操作符壓入s1
                s1.push(opTop);
                break;
            }else{
                int prec2;
                if(opTop == '+' || opTop == '-'){
                    prec2 = 1;
                }else{
                    prec2 = 2;
                }
                if(prec2 < prec1){//如果當(dāng)前運(yùn)算符比s1棧頂運(yùn)算符優(yōu)先級高,則將運(yùn)算符壓入s1
                    s1.push(opTop);
                    break;
                }else{//如果當(dāng)前運(yùn)算符與棧頂運(yùn)算符相同或者小于優(yōu)先級別,那么將S1棧頂?shù)倪\(yùn)算符彈出并壓入到S2中
                    //并且要再次再次轉(zhuǎn)到while循環(huán)中與 s1 中新的棧頂運(yùn)算符相比較;
                    s2.push(opTop);
                }
            }
        }//end while
        //如果s1為空,則直接將當(dāng)前解析的運(yùn)算符壓入s1
        s1.push(opThis);
    }
    //當(dāng)前字符是 ')' 時(shí),如果棧頂是'(',則將這一對括號丟棄,否則依次彈出s1棧頂?shù)淖址瑝喝雜2,直到遇到'('
    public void gotParen(char ch){
        while(!s1.isEmpty()){
            char chx = s1.pop();
            if(chx == '('){
                break;
            }else{
                s2.push(chx);
            }
        }
    }
}

三、測試

@Test
public void testInfixToSuffix(){
    String input;
    System.out.println("Enter infix:");
    Scanner scanner = new Scanner(System.in);
    input = scanner.nextLine();
    InfixToSuffix in = new InfixToSuffix(input);
    MyCharStack my = in.doTrans();
    my.displayStack();
}

四、結(jié)果  

五、分析  

②、計(jì)算機(jī)如何實(shí)現(xiàn)后綴表達(dá)式的運(yùn)算?  

4、前綴表達(dá)式

前綴表達(dá)式,指的是不包含括號,運(yùn)算符放在兩個(gè)運(yùn)算對象的前面,嚴(yán)格從右向左進(jìn)行(不再考慮運(yùn)算符的優(yōu)先規(guī)則),所有的計(jì)算按運(yùn)算符出現(xiàn)的順序。

注意:后綴表達(dá)式是從左向右解析,而前綴表達(dá)式是從右向左解析。

①、如何將中綴表達(dá)式轉(zhuǎn)換為前綴表達(dá)式?  

②、計(jì)算機(jī)如何實(shí)現(xiàn)前綴表達(dá)式的運(yùn)算?  

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • IDEA不能生成SerialVersionUID,alt+enter不提示沒有效果問題

    IDEA不能生成SerialVersionUID,alt+enter不提示沒有效果問題

    文章介紹了在使用IntelliJ IDEA時(shí),通過安裝AutoFillingJavaCallArguments插件并導(dǎo)入Serializable接口后,遇到無法自動(dòng)生成序列ID的問題,解決方法是在設(shè)置中搜索serial,勾選“不帶'serialVersionUID'的可序列化類”選項(xiàng)
    2025-01-01
  • java 接口回調(diào)實(shí)例詳解

    java 接口回調(diào)實(shí)例詳解

    這篇文章主要介紹了java 接口回調(diào)實(shí)例詳解的相關(guān)資料,所謂回調(diào)就是使用java中的多態(tài),需要的朋友可以參考下
    2017-07-07
  • springboot實(shí)現(xiàn)熱部署操作方法

    springboot實(shí)現(xiàn)熱部署操作方法

    這篇文章主要介紹了springboot實(shí)現(xiàn)熱部署操作方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java中字符串與日期的轉(zhuǎn)換實(shí)例

    java中字符串與日期的轉(zhuǎn)換實(shí)例

    java中字符串與日期的轉(zhuǎn)換實(shí)例,需要的朋友可以參考一下
    2013-05-05
  • Spring工作原理簡單探索

    Spring工作原理簡單探索

    這篇文章主要介紹了Spring工作原理簡單探索,涉及Springaop與IOC,動(dòng)態(tài)代理靜態(tài)代理,反射等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java使用Callable接口實(shí)現(xiàn)多線程的實(shí)例代碼

    Java使用Callable接口實(shí)現(xiàn)多線程的實(shí)例代碼

    這篇文章主要介紹了Java使用Callable接口實(shí)現(xiàn)多線程的實(shí)例代碼,實(shí)現(xiàn)Callable和實(shí)現(xiàn)Runnable類似,但是功能更強(qiáng)大,具體表現(xiàn)在可以在任務(wù)結(jié)束后提供一個(gè)返回值,Runnable不行,call方法可以拋出異,Runnable的run方法不行,需要的朋友可以參考下
    2023-08-08
  • java開發(fā)技巧代碼寫的快且bug少的原因分析

    java開發(fā)技巧代碼寫的快且bug少的原因分析

    這篇文章主要為大家介紹了java開發(fā)中代碼寫的快且bug少的原因分析及技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Java集合中的fail-fast(快速失敗)機(jī)制詳解

    Java集合中的fail-fast(快速失敗)機(jī)制詳解

    這篇文章主要給大家介紹了關(guān)于Java集合中fail-fast(快速失敗)機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • java顯示當(dāng)前運(yùn)行時(shí)的參數(shù)(java運(yùn)行參數(shù))

    java顯示當(dāng)前運(yùn)行時(shí)的參數(shù)(java運(yùn)行參數(shù))

    這篇文章主要介紹了java顯示當(dāng)前運(yùn)行時(shí)參數(shù)的示例(java運(yùn)行參數(shù)),需要的朋友可以參考下
    2014-04-04
  • java中brew安裝rabbitmq以及簡單實(shí)例

    java中brew安裝rabbitmq以及簡單實(shí)例

    RabbitMQ是基于AMQP協(xié)議,由Erlang語言開發(fā)的開源消息隊(duì)列系統(tǒng),廣泛應(yīng)用于分布式系統(tǒng)中,用于應(yīng)用程序間的消息傳遞,它支持多種交換機(jī)類型,如直連交換機(jī)、扇形交換機(jī)和主題交換機(jī)等,能夠滿足不同的消息路由需求
    2024-10-10

最新評論

万安县| 北流市| 五台县| 宁安市| 祥云县| 高陵县| 浦江县| 黄浦区| 苏尼特左旗| 石景山区| 福安市| 灵山县| 城固县| 金山区| 论坛| 平顶山市| 黄山市| 三明市| 汝城县| 行唐县| 若尔盖县| 浮梁县| 巴东县| 资溪县| 县级市| 伊宁市| 玛纳斯县| 黑龙江省| 克什克腾旗| 武宁县| 墨脱县| 台安县| 万州区| 大洼县| 台江县| 临高县| 五原县| 东源县| 平阴县| 札达县| 巴林左旗|