逆波兰式求值

北慕城南 提交于 2020-01-11 06:24:22

逆波兰式求值

第一步、生成中缀表达式

第二步、中缀表达式转换为后缀表达式

第三步、后缀表达式求值

本次实验采用自主设计链式堆栈结构存储数据

LinkedStack存储中缀及后缀表达式

#pragma once
#include <string>

using namespace std;

typedef struct sign {
	string sign;
	int    level;
	struct sign * next;
};

class LinkedStack
{
private:
	struct sign * top;
	int    count;
	int compare(string str);
public:
	LinkedStack();
	~LinkedStack();

	void push(string str);
	void pop();
	string front();
	int    frontLevel();
	bool isEmpty();

	void show();
};

#include "LinkedStack.h"
#include <iostream>


LinkedStack::LinkedStack()
{
	top = NULL;
	count = 0;
}


LinkedStack::~LinkedStack()
{
}

void LinkedStack::push(string str) {
	struct sign * s = new struct sign();
	s->sign = str;
	s->level = compare(str);
	s->next = top;
	top = s;
	count++;
}

void LinkedStack::pop() {
	if (count == 0) return;
	struct sign * s = top;
	top = top->next;
	delete s;
	count--;
}

string LinkedStack::front() {
	return top->sign;
}

int LinkedStack::frontLevel() {
	return top->level;
}

bool LinkedStack::isEmpty() {
	return count == 0;
}

int LinkedStack::compare(string str) {
	int level;
	switch (str[0]) {
	case '(':
		level = -10; break;
	case ')':
		level = -10; break;
	case '+':
		level = 0; break;
	case '-':
		level = 0; break;
	case '*':
		level = 1; break;
	case '/':
		level = 1; break;
	case '%':
		level = 2; break;
	case '^':    
		level = 2; break;
	default:
		level = 1; break;
	}
	return level;
}

void LinkedStack::show() {
	struct sign * point = top;
	while (point != NULL)
	{
		cout << point->sign << "  ";
		point = point->next;
	}
	cout << endl;
}

NewStack存储运算的中间结果

#pragma once
#include <string>

using namespace std;

struct Sign
{
	double sign;
	struct Sign * next;
};

class NewStack
{
private:
	struct Sign * top;
	int count;
public:
	NewStack();
	~NewStack();

	void push(double sign);
	void pop();
	double front();
};
#include "NewStack.h"

NewStack::NewStack()
{
	count = 0;
	top = NULL;
}


NewStack::~NewStack()
{
}

void NewStack::push(double sign) {
	struct Sign * s = new struct Sign();
	s->sign = sign;
	s->next = top;
	top = s;
	count++;
}

void NewStack::pop() {
	if (top == NULL) return;
	struct Sign * s = top;
	top = top->next;
	count--;
	delete s;
}

double NewStack::front() {
	return top->sign;
}

第一步、由运算表达式生成中缀表达式

void RPN::GenerateNifix()      //生成前缀表达式
{
	int left = 0;
	string str = "";
	for (int i = 0; i < data.length(); i++)
	{
		//string temp = data.substr(i, i + 1);
		char C = data[i];
		string temp = "";
		temp += C;
		if (isOperator(temp))
		{
			if (str != "")
			{
				nifix->push(str);
				str = "";
			}
			nifix->push(temp);
		}
		else
		{
			str = str + temp;
		}
	}
	if(str != "")
	nifix->push(str);

	LinkedStack * tempStack = new LinkedStack();
	//前缀表达式存储逆转
	while (!nifix->isEmpty())
	{
		tempStack->push(nifix->front());
		nifix->pop();
	}

	nifix = tempStack;
	cout << "中缀表达式:";
	nifix->show();
}

第二步、中缀表达式转换为后缀表达式

void RPN::GeneratePostfix()    //生成后缀表达式
{
	LinkedStack operatorStack;       //临时运算符栈
	while (!nifix->isEmpty())
	{
		//取出栈顶元素
		string str = nifix->front();
		int    level = nifix->frontLevel();
		nifix->pop();

		if (!isOperator(str))  //不是运算符
		{
			//直接将其压入到后缀栈
			postfix->push(str);
		}
		else
		{
			if (str == "(")
			{
				operatorStack.push(str);
				continue;
			}

			if (str == ")")
			{
				while ( operatorStack.front() != "(" ) {
					postfix->push(operatorStack.front());
					operatorStack.pop();
				}
				operatorStack.pop();
				continue;
			}

			if (operatorStack.isEmpty())
			{
				operatorStack.push(str);
				continue;
			}

			if (level <= operatorStack.frontLevel())
			{
				postfix->push(operatorStack.front());
				operatorStack.pop();
				operatorStack.push(str);
			}

			if (level > operatorStack.frontLevel())
			{
				operatorStack.push(str);
			}
		}
	}

	while (!operatorStack.isEmpty())
	{
		postfix->push(operatorStack.front());
		operatorStack.pop();
	}

	//逆转存储
	LinkedStack * temp = new LinkedStack();
	while (!postfix->isEmpty())
	{
		temp->push(postfix->front());
		postfix->pop();
	}

	postfix = temp;
	cout << "后缀表达式:";
	postfix->show();
}

第三步、计算后缀表达式

double RPN::calculate()        //计算后缀表达式
{
	NewStack st;
	while (!postfix->isEmpty())
	{
		string str = postfix->front();
		char C = str[0];
		postfix->pop();

		if (!isOperator(str))
		{
			double data = StrToDouble(str);
			st.push(data);
		}
		else
		{
			double y = st.front();
			st.pop();
			double x = st.front();
			st.pop();

			cout << "X=" << x << "  " << "Y=" << y << "  " <<"运算符" << C <<endl;

			double result;
			switch (C)
			{
			case '+':
				result = x + y;
				st.push(result);
				continue;
			case '-':
				result = x - y;
				st.push(result);
				continue;
			case '*':
				result = x * y;
				st.push(result);
				continue;
			case '/':
				result = x / y;
				st.push(result);
				continue;
			case '%':
				result = (int)x % (int)y;
				st.push(result);
				continue;
			case '^':
				result = pow(x, y);
				st.push(result);
				continue;
			}
		}
	}

	return st.front();
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!