- 題目:1 將中綴表達式轉換為后綴表達式
- 2 求后綴表達式的值
#include<stdio.h>
#define MaxSize 100
struct
{
char data[MaxSize];
int top; //棧頂指針
}op; //定義運算符棧
struct
{
float data[MaxSize];
int top;
}st; //定義數值棧
void trans(char exp[],char postexp[])
{
int i = 0;
int j = 0;
char ch;
op.top = -1; //棧頂指針初始化為-1
ch = exp[i];
i++;
while (ch != '\0')
{
switch (ch)
{
case '(': //判定為左括號 直接入棧
op.top++;
op.data[op.top] = ch;
break;
case ')':
while (op.data[op.top] != '(')
{
postexp[j] = op.data[op.top];
op.top--;
j++;
}
op.top--; //左括號也出棧 但不輸出
break;
case '+':
case '-':
//為 + 或者 - 時候,優先級不大於棧頂任何運算符的優先級 直到 )
while (op.top != -1 && op.data[op.top] != '(')
{
postexp[j] = op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top] = ch;
break;
case '*':
case '/':
//為 * 或者是 / 時, 其優先級不大於棧頂為 * 或者為 /的優先級 直到 (
while (op.top != -1 && op.data[op.top] != '('
&& (op.data[op.top] == '*' || op.data[op.top] == '/'))
{
//將棧頂運算符彈出並輸出
postexp[j] = op.data[op.top];
j++;
op.top--;
}
//該運算符的優先級大於棧頂運算符的優先級 直接壓棧
op.top++;
op.data[op.top] = ch;
break;
case ' ': //過濾掉空格
break;
default:
while (ch >= '0' && ch <= '9') //判定為數字
{
postexp[j] = ch;
j++;
ch = exp[i];
i++;
}
i--;
postexp[j] = '#'; //用#標識一個數值串結束
j++;
break;
}
ch = exp[i];
i++;
}
while (op.top != -1) //此時exp掃描完畢 棧不空時出棧並存放到postexp
{
postexp[j] = op.data[op.top];
j++;
op.top--;
}
postexp[j] = '\0'; //添加結束標識符
}
//后綴表達式的求值過程
float Compvalue(char postexp[])
{
char ch;
float d;
int i = 0;
ch = postexp[i];
i++;
st.top = -1;
while (ch != '\0')
{
switch (ch)
{
case '+':
st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
st.top = st.top - 1;
break;
case '-':
st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
st.top = st.top - 1;
break;
case '*':
st.data[st.top - 1] = st.data[st.top] * st.data[st.top - 1];
st.top = st.top - 1;
break;
case '/':
if (st.data[st.top] != 0)
{
st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
st.top = st.top - 1;
}
else
{
printf("除數為0.\n");
return 0.0;
}
break;
default:
d = 0;
while (ch >= '0' && ch <= '9')
{
d = d * 10 + ch - '0';
ch = postexp[i];
i++;
}
st.top++;
st.data[st.top] = d;
break;
}
ch = postexp[i];
i++;
}
return st.data[st.top];
}
int main()
{
int i = 0;
char exp[] = {"(2*2)*1+3*2/1"};
char postexp[MaxSize];
trans(exp,postexp);
while (postexp[i] != '\0')
{
printf("%c",postexp[i]);
i++;
}
printf("\n");
printf("運算結果為:%f.\n", Compvalue(postexp));
system("pause");
return 0;
}
后綴表達式求值如下:
while(從postexp中間讀取字符ch,ch != '\0')
{
若ch為數字,將后繼的所有數字構成一個整數存放到數值棧st中
若ch為 "+",則從數值棧st中退棧兩個運算數,相加后進棧st中
若ch為 "-",則從數值棧st中退棧兩個運算數,相減后進棧st中
若ch為 "*",則從數值棧st中退棧兩個運算數,相乘后進棧st中
若ch為 "/",則從數值棧st中退棧兩個運算數,相除后進棧st中(若除數為0,則提示錯誤)
}
-
運行結果
-
參考資料:
1 《新編數據結構習題與解析》