数据结构__不含括号的加减乘除法混合运算

这个程序我一共写了5个文件,4个是头文件,最后1个则是main函数的cpp文件。

第一个文件名为head.h

用于包含一些基本的头文件,如下所示:

#pragma once
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;

第二个文件名为stack.h

用于定义基本的栈和相应的栈操作,如下所示:

#pragma once
#include"head.h"

struct node
{
	double data;
	node *next;
public:
	node();
};

node::node() {}

class stack
{
private:
	node* top;
public:
	stack() { top = NULL; }
	~stack();
	void push(double e);
	double pop();
	double getTop();
	bool isEmpty() { if (top == NULL) return true; else return false; }
};

double stack::getTop()
{
	if (top != NULL) 
		return top->data;
}

stack::~stack()
{
	node* p;
	while (top)
	{
		p = top->next;
		delete top;
		top = p;
	}
}

void stack::push(double e)
{
	node* p = new node;
	if (!p)
	{
		cout << "内存分配失败" << endl;
		return;
	}
	p->data = e;
	p->next = top;
	top = p;
}

double stack::pop()
{
	if (top == NULL)
	{
		cout << "溢出" << endl;
	}
	double temp = top->data;
	node* p = top;
	top = top->next;
	delete p;
	return temp;
}

第三个文件名是queue.h

用于定义基本的队列和相关的操作,如下:

#pragma once
#include"head.h"

struct Node
{
	double data;
	Node *next;
};
class sqqueue 
{
private:
	Node *front;
	Node *rear;
public:
	sqqueue();
	~sqqueue();
	void enqueue(double e);
	double dequeue();
	bool isEmpty();
	double getFront();
};

double sqqueue::getFront()
{
	return front->next->data;
}

sqqueue::sqqueue()
{
	front = new Node;
	front->next = NULL;
	rear = front;
}

sqqueue::~sqqueue()
{
	Node *p=NULL;
	while (front != NULL)
	{
		p = front;
		front = front->next;
		delete p;
	}
}

void sqqueue::enqueue(double e)
{
	Node *s = new Node;
	s->data = e;
	s->next = rear->next;
	rear->next = s;
	rear = s;
	if (front->next == NULL)
		front->next = s;
}

double sqqueue::dequeue()
{
	double e;
	Node *p = NULL;
	if (rear == front)
	{
		cout << "下溢" << endl;
	}
	p = front->next;
	e = p->data;
	front->next = p->next;
	if (p->next == NULL)
		rear = front;
	delete p;
	return e;
}

bool sqqueue::isEmpty()
{
	if (rear == front) return true;
	else return false;
}

第四个文件名是change.h

里面有两个函数,第一个名为change的函数作用是“逆波兰”,第二个Cal函数则是计算后缀表达式并输出最后的计算结果,如下:

#pragma once
#include"queue.h"
#include"stack.h"

sqqueue output;
stack s;
stack a;

void change(string str)
{
	double num;
	double temp;
	for (int i = 0; i < str.length();)
	{
		if (str[i] >= '0'&&str[i] <= '9')
		{
			temp = str[i++] - '0';
			while (i < str.length() && str[i] >= '0'&&str[i] <= '9')
			{
				temp = temp * 10 + (str[i] - '0');
				i++;
			}
			output.enqueue(temp);
		}
		else
		{
			if (((str[i] == '+' || str[i] == '-')&&(s.getTop() == -3|| s.getTop() == -4))|| ((str[i] == '+' || str[i] == '-') && (s.getTop() == -1 || s.getTop() == -2))|| ((str[i] == '*' || str[i] == '/') && (s.getTop() == -3 || s.getTop() == -4)))
			{
				while (!s.isEmpty())
				{
					output.enqueue(s.pop());
				}
			}
			switch (str[i])
			{
			case '+':s.push(-1); break;
			case '-':s.push(-2); break;
			case '*':s.push(-3); break;
			case '/':s.push(-4); break;
			default:break;
			}
			i++; 
		}
	}
	while (!s.isEmpty())
	{
		output.enqueue(s.pop());
	} 
}

void Cal()
{
	double temp;
	double r, l;
	while (!output.isEmpty())
	{
		if (output.getFront() >= 0)
		{
			a.push(output.dequeue());
		}
		else
		{
			double x = output.dequeue();
			if (x == -1)
			{
				r = a.pop();
				l = a.pop();
				temp = l + r;
				a.push(temp);
			}
			else if (x == -2)
			{
				r = a.pop();
				l = a.pop();
				temp = l - r;
				a.push(temp);
			}
			else if (x == -3)
			{
				r = a.pop();
				l = a.pop();
				temp = l * r;
				a.push(temp);
			}
			else if (x == -4)
			{
				r = a.pop();
				l = a.pop();
				temp = l / r;
				a.push(temp);
			}
		}
	}
	cout << a.pop() << endl;
}

最后一个cpp文件是用来写main函数的,很简洁,没啥好说的。文件名就叫main.cpp:

#include"change.h"
int main(void)
{
	string str;
	cin >> str;
	change(str);
	Cal();
	system("pause");
	return 0;
}

个人以为,主要是第四个叫change的文件需要注意,尤其是逆波兰的步骤。。。。一不小心写错一点点就会有内存访问错误,原因是退栈出栈入队出队的操作容易不小心写混,导致读取数据的data指针指向NULL。主要是找BUG会找很久很久。

下面展示几个测试数据:

 

posted @ 2018-10-27 23:26  TIM3347_Tian  阅读(23)  评论(0)    收藏  举报  来源