中綴,前綴,後綴表達式

中綴表達式,後綴表達式,前綴表達式2008-12-19 16:47中綴表達式:運算符放在兩個運算對象中間,如:(2+1)*3;
後綴表達式:不包含括號,運算符放在兩個運算對象的後面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則,如:2 1 + 3 *;
前綴表達式:同後綴表達式一樣,不包含括號,運算符放在兩個運算對象的前面,如:* + 2 1 3。
(2)表達式的計算:
由於後綴表達式中沒有括號,不需判別優先級,計算嚴格從左向右進行,故計算一個後綴表達式要比計算機一箇中綴表達式簡單得多。
將中綴表達式轉換爲後綴表達式的算法思想:
·當讀到數字直接送至輸出隊列中
·當讀到運算符t時,
a.將棧中所有優先級高於或等於t的運算符彈出,送到輸出隊列中;
b.t進棧
·讀到左括號時總是將它壓入棧中
·讀到右括號時,將靠近棧頂的第一個左括號上面的運算符全部依次彈出,送至輸出隊列後,再丟棄左括號。

下面是一個將中綴表達式轉換爲後綴表達式並求值的一個c語言的例子

/*將中綴表達式轉換爲後綴表達式並求值*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

typedef struct             /*定義一個用於存儲字符集合的棧*/
{
    char elements[MAX];
    int top;
}
STACK_char;
typedef struct             /*定義一個用於存儲浮點數集合的棧*/
{
    float elements[MAX];
    int top;
}
STACK_num;

/*以下爲棧的基本操作函數*/
void MakeNull_char(STACK_char *);
char Top_char(STACK_char *);
char PopAddTop_char(STACK_char *);
void Push_char(char,STACK_char *);
void MakeNull_num(STACK_num *);
float Top_num(STACK_num *);
float PopAddTop_num(STACK_num *);
void Push_num(float,STACK_num *);

int compare(char,char);      /*比較運算符優先級的函數*/
void change(char *,char *);  /*將中綴表達式轉換爲後綴表達式的函數*/
float compute(char *);       /*對後綴表達式進行運算的函數*/

int main()
{
    char a[MAX],b[MAX];
    float result;

    printf("請輸入一個表達式:/n");
    gets(a);
    change(a,b);
    printf("後綴表達式爲:/n%s/n",b);
    result=compute(b);
    printf("運算結果爲:/n%.3f",result);
    getchar();
    return 0;
}

/*以下定義操作函數*/
void MakeNull_char(STACK_char *S)               /*此函數將棧初始化爲空棧*/
{
    (*S).top=MAX;
}

char Top_char(STACK_char *S)                   /*此函數返回棧頂元素*/
{
    return (*S).elements[(*S).top];
}

char PopAddTop_char(STACK_char *S)             /*此函數返回棧頂元素並刪除棧頂元素*/
{
    (*S).top=(*S).top+1;
    return (*S).elements[(*S).top-1];
}

void Push_char(char x,STACK_char *S)           /*此函數將將一元素壓入棧中*/
{
    (*S).top=(*S).top-1;
    (*S).elements[(*S).top]=x;
}

void MakeNull_num(STACK_num *S)
{
    (*S).top=MAX;
}

float Top_num(STACK_num *S)
{
    return (*S).elements[(*S).top];
}

float PopAddTop_num(STACK_num *S)
{
    (*S).top=(*S).top+1;
    return (*S).elements[(*S).top-1];
}

void Push_num(float x,STACK_num *S)
{
    (*S).top=(*S).top-1;
    (*S).elements[(*S).top]=x;
}

int compare(char x,char y)           /*此函數比較運算符優先級*/
{
    if ((x=='*'||x=='/'||x=='%')&&(y=='+'||y=='-'))
        return 1;
    else
        return 0;
}

void change(char *a,char *b)         /*此函數將中綴表達式轉換爲後綴表達式*/
{
    char num[12]="0123456789.";
    char c[2],d[2];                  /*定義兩個字符串,用於下面字符串比較*/
    STACK_char S;
    int i,k;

    MakeNull_char(&S);
    Push_char('#',&S);
    k=0;
    for (i=0;i<strlen(a);i++)
    {
        c[0]=a[i];
        c[1]='/0';
        d[0]=a[i+1];
        d[1]='/0';
        if (a[i]==' ')               /*輸入過程遇空格跳過*/
            continue;
        else if (strstr(num,c))      /*比較字符串以確定當前字符是否爲數字*/
        {
            b[k]=a[i];
            k++;
            if (i==strlen(a)-1)
            {
                b[k]=' ';
                k++;
            }
            else if (strstr(num,d)==NULL)     /*運算符後加空格*/
            {
                b[k]=' ';
                k++;
            }
        }
        else
        {
            if (a[i]!=')')
            {
                if (a[i]=='(')                /*遇‘(’壓入棧*/
                    Push_char(a[i],&S);
                else if (compare(a[i],Top_char(&S))||Top_char(&S)=='#')   /*優先級高於棧頂元素壓入棧*/
                    Push_char(a[i],&S);
                else
                {
                    while (compare(a[i],Top_char(&S))==0&&Top_char(&S)!='#'&&Top_char(&S)!='(')   /*優先級低於棧頂元素直接輸出*/
                    {
                        b[k]=PopAddTop_char(&S);
                        k++;
                        b[k]=' ';
                        k++;
                    }
                    Push_char(a[i],&S);
                }
            }
            else
            {
                while (Top_char(&S)!='(')        /*遇‘)’向前查找第一個‘(’並輸出其間運算符*/
                {
                    b[k]=PopAddTop_char(&S);
                    k++;
                    b[k]=' ';
                    k++;
                }
                PopAddTop_char(&S);
            }
        }
    }
    while (Top_char(&S)!='#')          /*依次輸出剩餘運算符*/
    {
        b[k]=PopAddTop_char(&S);
        k++;
        b[k]=' ';
        k++;
    }
    b[k-1]='/0';               /*字符串後加‘/0’結束*/
}

float compute(char *b)          /*計算後綴表達式的值*/
{
    float result;
    float integer=0,decimal=0;  /*定義變量,表示整數、小數部分*/
    float m=1;
    float t=0.1;
    float top,second;
    STACK_num L;
    int i;

    i=0;
    MakeNull_num(&L);
    while (b[i]!='/0')
    {
        while (b[i]!=' '&&b[i]!='.'&&b[i]!='+'&&b[i]!='-'&&b[i]!='*'&&b[i]!='/'&&b[i]!='+'&&b[i]!='%')   /*對整數部分進行運算*/
        {
            integer=integer*m+b[i]-48;
            m*=10;
            i++;
        }
        if (b[i]=='.')         /*對小數部分進行運算*/
        {
            i++;
            while (b[i+1]!=' '&&b[i+1]!='/0')
            {
                i++;
                decimal+=(b[i]-48)*t;
                t*=0.1;
            }
            decimal+=(b[i]-48)*t;
            t*=0.1;
            i++;
        }
        integer+=decimal;
        if (b[i]==' '&&b[i-1]!='+'&&b[i-1]!='-'&&b[i-1]!='*'&&b[i-1]!='/'&&b[i-1]!='+'&&b[i-1]!='%')      /*將一個完整操作數進行壓棧*/
        {
            Push_num(integer,&L);
            m=1;
            t=0.1;
            integer=0;
            decimal=0;
        }
        switch (b[i])                          /*對不同運算符進行分別處理*/
        {
        case'+':
            top=PopAddTop_num(&L);
            second=Top_num(&L);
            result=top+second;
            PopAddTop_num(&L);
            Push_num(result,&L);
            break;
        case'-':
            top=PopAddTop_num(&L);
            second=Top_num(&L);
            result=second-top;
            PopAddTop_num(&L);
            Push_num(result,&L);
            break;
        case'*':
            top=PopAddTop_num(&L);
            second=Top_num(&L);
            result=top*second;
            PopAddTop_num(&L);
            Push_num(result,&L);
            break;
        case'/':
            top=PopAddTop_num(&L);
            second=Top_num(&L);
            result=second/top;
            PopAddTop_num(&L);
            Push_num(result,&L);
            break;
        case'%':
            top=PopAddTop_num(&L);
            second=Top_num(&L);
            result=(int)second%(int)top;
            PopAddTop_num(&L);
            Push_num(result,&L);
            break;
        }
        i++;
    }
    return Top_num(&L);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章