C++小程序——中綴表達式轉換爲後綴表達式

轉換步驟

  1. 初始化兩個棧:運算符棧s1操作數棧s2

  2. 從左到右掃描中綴表達式

  3. 遇到操作數時,將其壓入棧s2

  4. 遇到運算符時,比較其與s1棧頂運算符優先級

    (1)若s1為空,或棧頂運算符為左括號(,則直接將此運算符入棧;

    (2)否則,若其優先級比棧頂運算符的高,將此運算符壓入s1

    (3)否則,將s1棧頂的運算符彈出並壓入s2,再次跳轉到步驟(4.1)s1中新的棧頂運算符進行比較;

  5. 遇到括號時;

    (1)若為左括號(,則直接壓入s1

    (2)若爲右括號),則依次彈出s1棧頂的運算符,並壓入s2,直到遇到左括號爲止。此時將這對括號丟棄;

  6. 重複步驟2-5,直至表達式的最右邊

  7. s1中剩餘的運算符依次彈出,並壓入s2

  8. 依次彈出s2中所有元素並輸出,所得結果的逆序即爲對應的後綴表達式。

示例

Github開源項目鏈接地址:PostfixExpression

中綴表達式(初始):1+((2+3)*4)-5

後綴表達式(轉換結果):1 2 3 + 4 * + 5 -

示例

源代碼

#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
using namespace std;


stack<char> operSta, numSta;
map<char, int> operMap;


void init();
void trimSpace(string &str);
void scan(const char c);
void inputNum(const char c);
void inputOper(const char c);
void sweep();
void showStack(stack<char> &sta);


int main()
{
	init();

	// Get a string
	string midfixStr;
	cout << "Enter a midfix string: ";
	cin >> midfixStr;

	// Trim spaces
	trimSpace(midfixStr);

	// Convert midfix to postfix
	for (int i = 0, len = midfixStr.length(); i < len; ++i)
	{
		char tmp = midfixStr.at(i);
		scan(tmp);
	}
	// Do last things
	sweep();

	// Show result
	showStack(numSta);
}

void init()
{
	operMap.insert(make_pair('(', 10));
	operMap.insert(make_pair(')', 0));
	operMap.insert(make_pair('+', 2));
	operMap.insert(make_pair('-', 2));
	operMap.insert(make_pair('*', 4));
	operMap.insert(make_pair('/', 4));
}

void trimSpace(string &str)
{
	auto itor = remove_if(str.begin(), str.end(), ::isspace);
	str.erase(itor, str.end());
}

void scan(const char c)
{
	if (c >= '0' && c <= '9') inputNum(c);
	else if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') inputOper(c);
	else 
	{
		cout << "Find invalid character, can not parse!" << endl;
		exit(-1);
	}
}

void inputNum(const char c)
{
	numSta.push(c);
}

void inputOper(const char c)
{
	// Check if the underlying container has no elements
	if (operSta.empty()) 
	{
		operSta.push(c);
		return;
	}

	// Has elements
	char topC = operSta.top();
	int priNew = operMap.at(c);
	int priTop = operMap.at(topC);

	// Is '(' or the priority is higher than the top element
	if (priNew > priTop || topC == '(' || c == '(') 
	{
		operSta.push(c);
		return;
	}

	// If the input element is ')'
	if (c == ')')
	{
		char tmp;
		while ((tmp = operSta.top()) != '(')
		{
			operSta.pop();
			numSta.push(tmp);
		}
		operSta.pop();
		return;
	}

	// If the priority is lower than the top element
	operSta.pop();
	numSta.push(topC);

	// Recursive
	inputOper(c);
}

void sweep()
{
	while (!operSta.empty())
	{
		char tmp = operSta.top();
		operSta.pop();
		numSta.push(tmp);
	}
}

void showStack(stack<char> &sta)
{
	stack<char> tmpSta;
	
	while (!sta.empty())
	{
		char c = sta.top();
		sta.pop();
		tmpSta.push(c);
	}

	// Reverse
	while (!tmpSta.empty())
	{
		char c = tmpSta.top();
		tmpSta.pop();
		sta.push(c);

		cout << c << " ";
	}
	cout << endl;
}


程序效果截圖

效果1
效果2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值