中綴表達式,後綴表達式,前綴表達式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);
}