1. 程式人生 > >逆波蘭式的轉換與計算(簡單)

逆波蘭式的轉換與計算(簡單)

我們平常書寫的表示式:--如2+3*4+4 又稱為中綴表示式,我們可以將它轉換為字尾表示式

213*+4+

輸入有兩行,第一行為逆波蘭式的結果,第二行為輸入表示式的正確計算結果。逆波蘭式中相鄰的數字或運算子之間不用輸出空格

保證表示式計算的合理性,不需判斷除零等情況

表示式的計算遵循同級運算從左向右,先乘除後加減

樣例輸入:

2+1*3+4

樣例輸出:

213*+4+

9

解題思路:

首先定義兩個棧,一個臨時儲存運算子S1,另一個作為輸入逆波蘭式S2的存放棧

在S1中先放入一個‘#’運算子調整為最低,方便運算子的比較

然後開始從表示式中取值

(1)若取出的是表示式,直接將其放置到S2存放棧中

(2)若取出的運算子,則將該元素與S1棧頂元素進行比較,如果該運算子優先順序大於(小於或者等於都不行)S1棧頂運算子優先順序,則將該運算子進S1棧,否則,將S1棧棧的棧頂運算子彈出,送入S2棧,之後再和S1現在的棧頂比較,直到運算子優先順序大於棧頂為止後,將該運算子送入S1中

(3)重複上述1-2步,直到所有輸入字元都處理完畢

(4)將S1中的所有符號除‘#’以外都push到S2中

這樣我們就得到了一個逆波蘭序列

計算結果:

將逆波蘭式依次堆入一個棧中,如果堆入的是一個運算子,取出棧裡的頭兩個運算元(必為數字),將其執行運算子所代表的操作後

(一般是 下 運算子 上),將結果放回棧中,最後剩下的棧頂就是結果

程式碼如下:

am>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int precede(char a) {
	switch (a)
	{
	case '+':
		return 1;
	case '-':
		return 1;
	case '*':
		return 2;
	case '/':
		return 2;
	case '#':
		return 0;
	}
}

bool comparePrecde(char a,char b) {  //前表示式中的元素 後棧中的元素
	int pre_a = precede(a);
	int pre_b = precede(b);

	if (pre_a > pre_b) {
		return true;
	}
	else {
		return false;
	}
}

int main() {

	stack<char> numStack;  //用來儲存數字
	stack<char> exprStack;  //用來儲存表示式
	stack<char> tempStack;  //暫時儲存
	stack<float> resStack;  //用來儲存計算結果
	vector<char> opVec;   //正序輸出
	exprStack.push('#');   

	string buffer;   //用來讀取中綴表示式
	cin >> buffer;
	for (int i = 0; i < buffer.size(); ++i) {   //數字和運算子分離
		if (isdigit(buffer[i])) {
			numStack.push(buffer[i]);
		}
		else {
			while (!comparePrecde(buffer[i], exprStack.top())) {
				numStack.push(exprStack.top());
				exprStack.pop();
			}
			exprStack.push(buffer[i]);
		}
	}
	
	while (exprStack.top() != '#') {     //剩餘的元素壓入棧
		numStack.push(exprStack.top());
		exprStack.pop();
	}
	
	while (!numStack.empty()) {
		opVec.push_back(numStack.top());
		tempStack.push(numStack.top());
		numStack.pop();
	}
	
	reverse(opVec.begin(), opVec.end());  //輸出逆波蘭式列
	for (auto x : opVec) {
		cout << x;
	}

	cout << endl;
	//計算結果
	while (!tempStack.empty()) {
		if (isdigit(tempStack.top())) {
			resStack.push((float)(tempStack.top() - '0'));  //char to int
			tempStack.pop();
		}
		else {
			char expr = tempStack.top();
			tempStack.pop();
			float a = resStack.top();
			resStack.pop();
			float b = resStack.top();
			resStack.pop();

			switch (expr)
			{
			case'+':
				resStack.push(b + a);
				break;
			case'-':
				resStack.push(b - a);
				break;
			case'*':
				resStack.push(b * a);
				break;
			case'/':
				resStack.push(b / a);
				break;
			}
		}
	}

	cout << resStack.top() << endl;   //輸出結果

	return 0;
}