用棧求算術表達式的值


  • 題目: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 《新編數據結構習題與解析》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM