栈应用之逆波兰式

1.也称中缀表达式转化为后缀表达式

    其思想为:

      (1)首先,需要分配2个栈,栈s1用于临时存储运算符(含一个结束符号),此运算符在栈内遵循越往栈顶优先级越高的原则;
          栈s2用于输入逆波兰式,为方便起见,栈s1需先放入一个优先级最低的运算符,在这里假定为'#';
  (2)从中缀式的左端开始逐个读取字符x,逐序进行如下步骤:
      1.若x是操作数,则分析出完整的运算数(在这里为方便,用字母代替数字),将x直接压入栈s2;
      2.若x是运算符,则分情况讨论:
        若x是'(',则直接压入栈s1;
        若x是')',则将距离栈s1栈顶的最近的'('之间的运算符,逐个出栈,依次压入栈s2,此时抛弃'(';
        若x是除'('和')'外的运算符,则再分如下情况讨论:
          1)若当前栈s1的栈顶元素为'(',则将x直接压入栈s1;
          2)若当前栈s1的栈顶元素不为'(',则将x与栈s1的栈顶元素比较,若x的优先级大于栈s1栈顶运算符优先                                             级,则将x直接压入栈s1。否者,将栈s1的栈顶运算符弹出,压入栈s2中,直到栈s1的栈顶运算符优先                                           级别低于(不包括等于)x的优先级,或栈s2的栈顶运算符为'(',此时再则将x压入栈s1;
  (3)在进行完(2)后,检查栈s1是否为空,若不为空,则将栈中元素依次弹出并压入栈s2中(不包括'#');
  (4)完成上述步骤后,栈s2便为逆波兰式输出结果。但是栈s2应做一下逆序处理,因为此时表达式的首字符位于栈底;
具体代码为:

#include
#include
#include
#include
using namespace std;
class NibolanCls {
public:
	void InputOfString();//初始字符串的输入,字符串最后以“#”结尾
	int PriorityOfInit(char ch);//优先级设置
	void ToNiBoLan();//进行转化
	void OutputOfNiBoLan();//输出逆波兰式
private:
	stack m_operater;//存储操作数
	stack m_charofnibolan;//存储逆波兰式的字符组成
	vector m_inputofexpression;//存储输入的表达式
	vector m_storageofnibolan;//存储逆波兰式
};
void NibolanCls::InputOfString() {
	char c;
	cout << "可以输入  0123456789 - + * ^ /  这些符号来进行输入字符串!" << endl;
	cout << "input string :" << endl;
	while (cin >> c) {
		m_inputofexpression.push_back(c);
		if (c == '#') {//以'#'作为结束符
			m_inputofexpression.pop_back();
			break;
		}
	}
}
int NibolanCls::PriorityOfInit(char ch) {
	switch (ch) {
	case '(':
	case '#':
		return 0; break;
	case '+':
	case '-':
		return 1; break;
	case '*':
	case '/':
		return 2; break;
	case '^':
		return 3; break;

	}
}
void NibolanCls::ToNiBoLan() {
	int i, j;
	char my_vectorchar = ' ';
	char my_fristchar = '#';//在栈中设置一个最低优先级的符号'#'
	m_operater.push(my_fristchar);
	for (i = 0; i < m_inputofexpression.size(); i++) {
		if (m_inputofexpression[i] == '(') {
			m_operater.push(m_inputofexpression[i]);
		}
		else if (m_inputofexpression[i] == ')') {
			my_vectorchar = m_operater.top();
			while (my_vectorchar != '(') {
				m_charofnibolan.push(my_vectorchar);
				m_operater.pop();
				my_vectorchar = m_operater.top();
			}
			m_operater.pop();
		}
		else {//判断是数字还是运算符
			if ('0' < m_inputofexpression[i] && m_inputofexpression[i] < '9') {
				m_charofnibolan.push(m_inputofexpression[i]);
			}
			else {
				my_vectorchar = m_operater.top();
				if (my_vectorchar == '(') {//栈顶为'('
					m_operater.push(m_inputofexpression[i]);
				}
				else {
					if (PriorityOfInit(my_vectorchar) <= PriorityOfInit(m_inputofexpression[i]))
						m_operater.push(m_inputofexpression[i]);
					else {//优先级低
						while (PriorityOfInit(my_vectorchar) > PriorityOfInit(m_inputofexpression[i])) {
							m_charofnibolan.push(my_vectorchar);
							m_operater.pop();
							my_vectorchar = m_operater.top();
						}
						m_operater.push(m_inputofexpression[i]);
					}
				}
			}
		}
	}
	if (m_operater.empty()) {
		cout << "the m_operater is empty!" << endl;
	}
	else {
		my_vectorchar = m_operater.top();
		while (my_vectorchar != '#') {
			m_charofnibolan.push(my_vectorchar);
			m_operater.pop();
			my_vectorchar = m_operater.top();
		}
	}
}
void NibolanCls::OutputOfNiBoLan() {
	int i, j;
	char my_outputnibolan;
	cout << "the nibolan is :" << endl;
	while (!m_charofnibolan.empty()) {
		my_outputnibolan = m_charofnibolan.top();
		m_storageofnibolan.push_back(my_outputnibolan);
		m_charofnibolan.pop();
	}
	for (j = m_storageofnibolan.size() - 1; j >= 0; j--) {
		cout << m_storageofnibolan[j];
	}
	cout << endl;
}
int main() {
	NibolanCls my_nibolan;
	my_nibolan.InputOfString();
	my_nibolan.ToNiBoLan();
	my_nibolan.OutputOfNiBoLan();
	system("pause");
	return 0;
}

 代码截图为:

 

你可能感兴趣的:(数据结构,MFC/C++)