国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用棧實現表達式求值

2019-11-08 02:13:03
字體:
來源:轉載
供稿:網友

為了實現用棧計算算數表達式的值,需設置兩個工作棧:用于存儲運算符的棧opter,以及用于存儲操作數及中間結果的棧opval。

算法基本思想如下:

(1)首先將操作數棧opval設為空棧,而將'#'作為運算符棧opter的棧底元素,這樣的目的是判斷表達式是否求值完畢。

(2)依次讀入表達式的每個字符,表達式須以'#'結尾,若是操作數則入棧opval,若是運算符,則將此運算符c與opter的棧頂元素top比較優先級后執行相應的操作,(具體操作如下:(i)若top的優先級小于c,即top<c,則將c直接入棧opter,并讀入下一字符賦值給c;(ii)若top的優先級等于c,即top=c,則彈出opter的棧頂元素,并讀入下一字符賦值給c,這一步目的是進行括號操作;(iii)若top優先級高于c,即top>c,則表明可以計算,此時彈出opval的棧頂兩個元素,并且彈出opter棧頂的的運算符,計算后將結果放入占opval中。)直至opter的棧頂元素和當前讀入的字符均為'#',此時求值結束。

算符間的優先關系如下表所示:

表中需要注意的是θ1為opter的棧頂元素,θ2位從表達式中讀取的操作符,此優先級表可以用二維數組實現,具體見代碼(表來源:嚴蔚敏《數據結構》)。

具體代碼如下:

#include<iostream>     //輸入的表達式要以'#'結尾,如‘5+6*3/(3-1)#’#include<cstring>#include<cstdio>#include<cctype>#include<stack>using namespace std;stack<char> opter;    //運算符棧stack<double> opval;  //操作數棧int getIndex(char theta)   //獲取theta所對應的索引{	int index = 0;	switch (theta)	{	case '+':		index = 0;		break;	case '-':		index = 1;		break;	case '*':		index = 2;		break;	case '/':		index = 3;		break;	case '(':		index = 4;		break;	case ')':		index = 5;		break;	case '#':		index = 6;	default:break;	}	return index;}char getPRiority(char theta1, char theta2)   //獲取theta1與theta2之間的優先級{	const char priority[][7] =     //算符間的優先級關系	{		{ '>','>','<','<','<','>','>' },		{ '>','>','<','<','<','>','>' },		{ '>','>','>','>','<','>','>' },		{ '>','>','>','>','<','>','>' },		{ '<','<','<','<','<','=','0' },		{ '>','>','>','>','0','>','>' },		{ '<','<','<','<','<','0','=' },	};	int index1 = getIndex(theta1);	int index2 = getIndex(theta2);	return priority[index1][index2];}double calculate(double b, char theta, double a)   //計算b theta a{	switch (theta)	{	case '+':		return b + a;	case '-':		return b - a;	case '*':		return b * a;	case '/':		return b / a;	default:		break;	}}double getAnswer()   //表達式求值{	opter.push('#');      //首先將'#'入棧opter	int counter = 0;      //添加變量counter表示有多少個數字相繼入棧,實現多位數的四則運算	char c = getchar();	while (c != '#' || opter.top() != '#')   //終止條件	{		if (isdigit(c))   //如果c在'0'~'9'之間		{			if (counter == 1)   //counter==1表示上一字符也是數字,所以要合并,比如12*12,要算12,而不是單獨的1和2			{				double t = opval.top();				opval.pop();				opval.push(t * 10 + (c - '0'));				counter = 1;			}			else			{				opval.push(c - '0');     //將c對應的數值入棧opval				counter++;			}			c = getchar();		}		else		{			counter = 0;   //counter置零			switch (getPriority(opter.top(), c))   //獲取運算符棧opter棧頂元素與c之間的優先級,用'>','<','='表示			{			case '<':               //<則將c入棧opter				opter.push(c);				c = getchar();				break;			case '=':               //=將opter棧頂元素彈出,用于括號的處理				opter.pop();				c = getchar();				break;			case '>':               //>則計算				char theta = opter.top();				opter.pop();				double a = opval.top();				opval.pop();				double b = opval.top();				opval.pop();				opval.push(calculate(b, theta, a));			}		}	}	return opval.top();   //返回opval棧頂元素的值}int main(){	//freopen("test.txt", "r", stdin);	int t;     // 需要計算的表達式的個數	cin >> t;	getchar();	while (t--)	{		while (!opter.empty())opter.pop();		while (!opval.empty())opval.pop();		double ans = getAnswer();		cout << ans << endl<< endl;		getchar();	}	return 0;}

結果:


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泗阳县| 周口市| 西峡县| 汉寿县| 乌兰县| 灵寿县| 永康市| 古浪县| 临沂市| 抚顺县| 漳浦县| 昆明市| 安义县| 汪清县| 蚌埠市| 柘城县| 苏尼特右旗| 民勤县| 东莞市| 桂林市| 齐河县| 上虞市| 靖边县| 泰州市| 阳东县| 巴中市| 上虞市| 武夷山市| 佛坪县| 新竹县| 西吉县| 新乐市| 呼和浩特市| 泗阳县| 塘沽区| 内黄县| 满城县| 门头沟区| 怀远县| 射阳县| 绥棱县|