數據結構與算法之中綴表達式轉換爲後綴表達式

1、中綴表達式轉換爲後綴表達式sql

      1.中綴表達式和後綴表達式spa

  • 中綴表達式是符合人類正常邏輯思惟的;
  • 後綴表達式則是比較契合計算機的運算。

      2.中綴表達式轉換爲後綴表達式3d

      思考:咱們要如何將(1-2)*(4+5)轉換爲1 2 - 4 5 + *呢?code

      提示:利用棧的「記憶」,符號都推入棧便可!blog

      案例:1+ (2-3) * 4 + 10/5it

      (1)首先遇到第一個輸入是數字1,數字在後綴表達式中都是直接輸出,接着是符號"+",入棧:io

      (2)第三個字符是"(",依然是符號,入棧,接着是數字2,輸出,而後是符號"-",入棧:原理

      (3)接下來是數字3,輸出,緊跟着是")",此時,咱們須要去匹配棧裏的"(",而後再匹配前將棧頂數據依次出棧(這就比如括號裏優先執行的道理),將"("和"-"出棧,並輸出"-":循環

      (4)緊接着是符號"*",直接入棧:遍歷

      (5)遇到數字4,輸出,以後是符號"+",此時棧頂元素是符號"*",此時按照先乘除後加減的原理,此時棧頂的乘號優先級比即將入棧的加號要大,因此,先讓棧內"*"出棧,再讓"+"出棧,並依次輸出,兩個全出棧就爲空棧了,再讓4後面的"+"入棧:

      (6)緊接着數字10,輸出,最後是符號"/",進棧:

      (7)最後一個數字5,輸出,全部的輸入處理完畢,可是棧中仍有數據,因此將棧中的符號依次出棧打印便可。

      規則總結:從左到右遍歷中綴表達式的每一個數字和符號,如果數字則直接輸出,如果符號,則判斷其與棧頂符號的優先級,是右括號或是優先級低於棧頂符號,則棧頂元素依次出棧並輸出,直到遇到左括號或棧空纔將後一個符號入棧。

      3.代碼實現

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10

typedef char ElemType;
typedef struct{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

// 建立一個棧
void InitStack(sqlStack *s){
    s->base = (ElemType *)malloc(STACK_INIT_SIZE *sizeof(ElemType));

    if(!s->base){
        exit(0);
    }
    
    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

// 壓棧
void Push(sqStack *s, ElemType e){

    if(s->top - s->base >= s->stackSize){
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT)*sizeof(ElemType));
        if(!s->base){
            exit(0);
        }
    }

    *(s->top) = e;
    s->top++;
}

void Pop(sqStack *s, ElemType *e){
    if(s->top == s->base){
        return;
    }
    *e = *--(s->top);
}

// 計算棧的當前容量 
int StackLen(sqStack s){
    return (s.top - s.base);
}

// 中綴表達式轉換爲後綴表達式
int main(){
    sqStack s;
    char c, e;
    
    InitStack(&s);

    printf("請輸入中綴表達式,以#號做爲結束標誌:");
    scanf("%c", &c);

    while(c!='#'){
        while(c>='0' && c<='9'){ // 循環輸入解決多位數的輸出問題,若是是數字直接打印
            printf("%c", c);
            scanf("%c", &c);
            if(c<'0' || c>'9'){
                printf(" ");
            }
        }
        if(')' == c){ // 若是是右括號,就出棧,直到彈出第一個左括號爲止
            Pop(&s, &e);
            while('(' != e){
                printf("%c", e);
                Pop(&s, &e)
            }
        }else if('+' == c || '-' == c){
            if(!StackeLen(s)){ // 若是棧爲空,直接入棧
                Push(&s, c);
            }else{ //若是棧不爲空,先彈棧,比較優先級
                do{
                       Pop(&s, &e);
                       if('(' == e){ // 若是彈棧的元素是左括號,則把左括號再入棧
                           Push(&s, e);
                       }else{ // 不是左括號,只能是+ - * / ,那麼就把以前入棧的符號先打印出來
                           printf("%c ", e);
                       }
                  }while(StackLen(s) && '(' != e);
                  Push(&s, c); // 最後將新輸入的+ -入棧
            }
        }else if('*' == c || '/' == c || '(' == c){
            Push(&s, c)
        }else if('#' == c){
            break;  
        }else{
            printf("\n出錯:輸入格式錯誤!\n")
        }
        scanf("%c", &c);
    }

    while(StackLen(s)){
        Pop(&s, &e);
        printf("&c ", e);
    }
    
    return 0;
}

 

本文爲原創文章,若是對你有一點點的幫助,別忘了點贊哦!比心!如需轉載,請註明出處,謝謝!

相關文章
相關標籤/搜索