首页 > 编程语言 >逆波兰式求值(C++_模拟)

逆波兰式求值(C++_模拟)

时间:2023-06-20 10:03:12浏览次数:31  
标签:temp int t2 integ t1 insertFront C++ 求值 模拟


题目

       将中缀表达式翻译成后缀表达式(逆波兰表达式)时,可以去掉中缀表达式中出现的括号,简化表达式。如中缀 表达式“(2+3)6”被转成后缀表达式“23+6”后,可以借助于栈对表达式求值,完成运算。规则大致如下:
       遇到操作数,则入栈;
       遇到二元运算符,则连续从栈中弹出两个操作数,先弹出的做第二操作数,后弹出的做第一操作数,与该二元运 算符作用后,将得到的结果再存入栈中;
       遇到一元运算符,则从栈中弹出一个操作数,与该一元运算符作用后,将得到的结果再存入栈中;
       按照上面的规则,扫描后缀表达式(由键盘读到):2、3 是操作数,依次入栈;之后碰到加号“+”这个二元运 算符,则 3、2 依次出栈,2 为第一操作数,3 为第二操作数,执行加法,和为 5,入栈;加号后面的 6 是操作数入栈;之后的乘号“*”是二元运算符,则 6、5 依次出栈,5 为第一操作数,6 为第二操作数,执行乘法,积为 30,入栈;之 后可以使用打印栈顶元素的操作(该次实验中使用命令“p”),将最后结果在屏幕上输出。
       程序要求从键盘接收字符串,然后按照上面的思想,求解该字符串对应的逆波兰式表达式的值。参与计算的操作 数是实数或整数,可以是负数(将负号“n”当做是一元运算符),为了便于解析,从键盘输入的内容被分成很多行, 如上面的例子在本次实验中输入是:

2
 3
 +
 6
 *
 P

输出结果是:
30
       程序应该提供下面的合法命令: +:弹出栈中两项元素,相加后和入栈。
-:弹出栈中两项元素,相减后差入栈。
*:弹出栈中两项元素,相乘后积入栈。
/:弹出栈中两项元素,相除后商入栈,注意如果除数为 0,系统应该通过下面的方式输出信息:

cout << "Divide by zero\n";

       同时,栈恢复到该操作之前,程序不退出。
n:表示相反数操作,弹出一项栈中元素,乘以(-1)后入栈。
d:表示复制栈顶元素操作,取出栈中一项元素,然后两次入栈。
r:表示栈顶元素与次栈顶元素交换次序,即连续出栈两项元素,再交错入栈,先出栈元素先入栈,后出栈元素后 入栈。
p:打印栈顶元素后换行,但栈中内容不变。
a:打印栈中所有元素,各元素输出时不换行,最先输出栈顶元素,最后输出栈底元素,全部输完后换一行,任务 完成后,栈中数据要维护成与操作前一致的内容。
c:清空栈中所有元素。
q:退出逆波兰式求值的程序。 注意,如果用户输入了错误的命令,则程序通过下面的方式输出信息:
cout << "Bad input\n";        栈不发生任何变化,程序不退出。 如果程序扫描碰到运算符,而栈中不存在足够的操作数弹出时,程序通过下面的方式输出信息:

cout << "Not enough operands\n";

栈恢复到该操作之前,程序不退出。

Code

Dlist.h

#ifndef __DLIST_H__
#define __DLIST_H__
// Get a definition for NULL
#include <iostream>;
using namespace std;
class emptyList {
	// OVERVIEW: an exception class
public:
	emptyList() {}
};

template <typename T>
class Dlist {
	// OVERVIEW: contains a double-ended list of Objects
public:
	// Operational methods
	bool isEmpty() const;
	// EFFECTS: returns true if list is empty, false otherwise
	void insertFront(T* o);
	// MODIFIES this
	// EFFECTS inserts o at the front of the list
	void insertBack(T* o);
	// MODIFIES this
	// EFFECTS inserts o at the back of the list
	T* removeFront();
	// MODIFIES this
	// EFFECTS removes and returns first object from non-empty list
	// throws an instance of emptyList if empty
	T* removeBack();
	// MODIFIES this
	// EFFECTS removes and returns last object from non-empty list
	// throws an instance of emptyList if empty
	// Maintenance methods
	Dlist(); // constructor
	Dlist(const Dlist& l); // copy constructor
	Dlist& operator=(const Dlist& l); // assignment
	~Dlist(); // destructor
private:
	// A private type
	struct node {
		node* next;
		node* prev;
		T* o;
	};
	node* first; // The pointer to the first node (NULL if none)
	node* last; // The pointer to the last node (NULL if none)
	// Utility methods
	void makeEmpty();
	// EFFECT: called by constructors to establish empty list invariant
	void removeAll();
	// EFFECT: called by destructor/operator= to remove and destroy all list elements
	void copyAll(const Dlist& l);
	// EFFECT: called by copy constructor/operator= to copy elements
	// from a source instance l to this instance
};
template<class T>
void Dlist<T>::insertFront(T* o)
{
	node* temp = new node();
	temp->o = o;
	temp->prev = nullptr;
	temp->next = first;
	if (first)
		first->prev = temp;
	else
		last = temp;
	first = temp;
}
template<class T>
void Dlist<T>::insertBack(T* o) {
	node* temp = new node;
	temp->o = o;
	temp->next = nullptr;
	temp->prev = last;
	if (last)
		last->next = temp;
	else
		first = temp;
	last = temp;
}
template<class T>
bool Dlist<T>::isEmpty() const {
	return first == nullptr;
}
template<class T>
T* Dlist<T>::removeFront() {
	if (first) {
		node* temp = first;
		first = first->next;
		if (first)
			first->prev = nullptr;
		else {
			first = nullptr;
			last = nullptr;
		}
		return temp->o;
	}
	else {
		try {
			emptyList* e = new emptyList();
			throw(e);
		}
		catch (emptyList * that) {
			cout << "Not enough operands" << endl;
		}
		return nullptr;
	}
}
template<class T>
T* Dlist<T>::removeBack() {
	if (last) {
		node* temp = last;
		last = last->prev;
		if (last)
			last->next = nullptr;
		else {
			first = nullptr;
			last = nullptr;
		}
		return temp->o;
	}
	else
	{
		try {
			emptyList* e = new emptyList();
			throw(e);
		}
		catch (emptyList * that) {
			cout << "Not enough operands" << endl;
		}
		return nullptr;
	}
}
template<class T>
Dlist<T>::Dlist() {
	makeEmpty();
}
template<class T>
Dlist<T>::Dlist(const Dlist& l) {
	copyAll(l);
}
template<class T>
Dlist<T>& Dlist<T>::operator=(const Dlist& l) // assignment
{
	removeAll();
	copyAll(l);
	return *this;
}
template<class T>
Dlist<T>::~Dlist() {
	removeAll();
}
template<class T>
void Dlist<T>::makeEmpty() {
	first = nullptr;
	last = nullptr;
}
template<class T>
void Dlist<T>::removeAll() {
	node* p = first;
	while (p) {
		node* temp = p;
		p = p->next;
		delete temp;
	}
}
template<class T>
void Dlist<T>::copyAll(const Dlist& l) {
	if (l.first) {
		//makeEmpty();
		node* p = l.first;
		node* q = new node;
		first = q;
		node* pq = nullptr;
		while (p) {
			q->o = p->o;
			q->prev = pq;
			pq = q;
			if (!p->next)
			{
				last = q;
				q->next = nullptr;
				break;
			}
			q->next = new node;
			q = q->next;
			p = p->next;
		}
	}
}
#endif /* __DLIST_H__ */

main.cpp

#include<iostream>
#include"Dlist.h"
using namespace std;
void BadExcepution() {
	cout << "Bad input\n";
}
int main()
{
	Dlist<int>integ;
	Dlist<char>opera;
	string str;
	while (1)
	{
		cin >> str;
		if (str == "+")
		{
			int* t1 = new int;
			int* t2 = new int;
			t1 = integ.removeFront();
			t2 = integ.removeFront();
			if (!t1 || !t2)
			{
				if (!t1 && !t2)
				{
					integ.insertFront(t2);
					integ.insertFront(t1);
				}
				else if (!t1)
					integ.insertFront(t2);
				else if (!t2)
					integ.insertFront(t1);
			}
			else
			{
				int* sum = new int;
				*sum	= *t1 + *t2;
				integ.insertFront(sum);
			}
		}
		else if (str == "-") {
			int* t1 = new int;
			int* t2 = new int;
			t1=integ.removeFront();
			t2 = integ.removeFront();
			if (!t1 || !t2)
			{
				if (!t1 && !t2)
				{
					integ.insertFront(t2);
					integ.insertFront(t1);
				}
				else if (!t1)
					integ.insertFront(t2);
				else if(!t2)
					integ.insertFront(t1);
			}
			else
			{
				int* sub = new int;
				*sub = *t2 - *t1;
				integ.insertFront(sub);
			}
		}
		else if (str == "/") {
			int* t1 = new int;
			int* t2 = new int;
			t1 = integ.removeFront();
			t2 = integ.removeFront();
			if (!t1 || !t2)
			{
				if (!t1 && !t2)
				{
					integ.insertFront(t2);
					integ.insertFront(t1);
				}
				else if (!t1)
					integ.insertFront(t2);
				else if (!t2)
					integ.insertFront(t1);
			}
			else
			{
				int* ans = new int;
				*ans = *t2 / *t1;
				integ.insertFront(ans);
			}
		}
		else if (str == "*") {
			int* t1 = new int;
			int* t2 = new int;
			t1 = integ.removeFront();
			t2 = integ.removeFront();
			if (!t1 || !t2)
			{
				if (!t1 && !t2)
				{
					integ.insertFront(t2);
					integ.insertFront(t1);
				}
				else if (!t1)
					integ.insertFront(t2);
				else if (!t2)
					integ.insertFront(t1);
			}
			else
			{
				int* ans = new int;
				*ans = *t1 * *t2;
				integ.insertFront(ans);
			}
		}
		else if (str == "n") {//取反
			int* temp = new int;
			temp = integ.removeFront();
			if (temp)
			{
				*temp = *temp * -1;
				integ.insertFront(temp);
			}
		}
		else if (str == "d") {//重复
			int* temp = new int;
			temp = integ.removeFront();
			if (temp)
			{
				integ.insertFront(temp);
				integ.insertFront(temp);
			}
		}
		else if (str == "r") {//颠倒
			int* t1 = new int;
			int* t2 = new int;
			t1 = integ.removeFront();
			t2 = integ.removeFront();
			if (!t1 && !t2)
			{
				integ.insertFront(t2);
				integ.insertFront(t1);
			}
			else if (!t1)
				integ.insertFront(t2);
			else if (!t2)
				integ.insertFront(t1);
			else
			{
				integ.insertFront(t1);
				integ.insertFront(t2);
			}
		}
		else if (str == "p") {//输出
		int* temp = new int;
		temp = integ.removeFront();
			if (temp)
			{
				cout << *temp << endl;
				integ.insertFront(temp);
			}
		}
		else if (str == "a") {//全部输出
			Dlist<int>* temp=new Dlist<int>();
			Dlist<int>* temp2 = new Dlist<int>();
			*temp = integ;
			while (!temp->isEmpty()) {
				temp2->insertBack(temp->removeFront());
			}
			while (!temp2->isEmpty()) {
				cout << *(temp2->removeFront()) << " ";
			}
			cout << endl;
		}
		else if (str == "c") {//清空
			while (!integ.isEmpty()) {
				cout << *(integ.removeFront()) << " ";
			}
		}
		else if (str == "q")//退出
			break;
		else
		{
		int* ans = new int(0);
		bool flag = 1;
			for (int i = 0; i < str.size(); i++)
			{
				if (str[i] > '9' || str[i] < '0')
				{
					BadExcepution();
					flag = false;
					break;
				}
				else
				{
					*ans *= 10;
					*ans += str[i] - '0';
				}
			}
			if (flag)
				integ.insertFront(ans);
		}
	}
	return 0;
}


标签:temp,int,t2,integ,t1,insertFront,C++,求值,模拟
From: https://blog.51cto.com/u_16165815/6520507

相关文章

  • P1203 [USACO1.1]坏掉的项链Broken Necklace(C++_模拟_暴力枚举_优化)
    题目描述你有一条由n个红色的,白色的,或蓝色的珠子组成的项链,珠子是随意安排的。这里是n=29的两个例子:第一和第二个珠子在图片中已经被作记号。图片A中的项链可以用下面的字符串表示:brbrrrbbbrrrrrbrrbbrbbbbrrrrb假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集......
  • P1582 倒水(C++_数论_进制)
    题目描述一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)显然在某些情况下CC无法达到目标,比......
  • P1478 陶陶摘苹果(升级版)(C++_贪心)
    题目描述又是一年秋季时,陶陶家的苹果树结了n个果子。陶陶又跑去摘苹果,这次他有一个a公分的椅子。当他手够不着时,他会站到椅子上再试试。这次与NOIp2005普及组第一题不同的是:陶陶之前搬凳子,力气只剩下s了。当然,每次摘苹果时都要用一定的力气。陶陶想知道在s<0s<0之前最多......
  • CCF_201612-4 压缩编码(C++_区间DP)
    问题描述       给定一段文字,已知单词a1,a2,…,an出现的频率分别t1,t2,…,tn。可以用01串给这些单词编码,即将每个单词与一个01串对应,使得任何一个单词的编码(对应的01串)不是另一个单词编码的前缀,这种编码称为前缀码。使用前缀码编码一段文字是指将这段文字中的每......
  • PAT_Advanced Level_1078 Hashing (25分)(C++_Hush_平方探测法)
    Thetaskofthisproblemissimple:insertasequenceofdistinctpositiveintegersintoahashtable,andoutputthepositionsoftheinputnumbers.ThehashfunctionisdefinedtobeH(key)=key%TSizewhereTSizeisthemaximumsizeofthehashtable.Qu......
  • 数据结构代码整理_队列Queue(C++)
    所谓队列,就是先进先出规则的实现。基于链表实现main.cpp#include<iostream>#include"Queue.h"usingnamespacestd;intmain(){ Queueq; q.append(1); q.append(2); Queue_entrya; q.retrieve(a); cout<<a<<""<<q.empty(); return......
  • PTA_乙级_1001 害死人不偿命的(3n+1)猜想 (C++_数论)
    卡拉兹(Callatz)猜想:对任何一个正整数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹......
  • 数据结构代码整理_栈Stack(C++)
           所谓栈,就是先进后出规则的实现,这种数据结构在DFS等算法体现的较为明显,因为课程要求不得不进行各种数据结构实现代码整理,就发出来与大家分享。下面有两种实现方法一个是基于数组实现的,另一个是基于链表实现的。基于数组实现源码main.cpp//main.cpp:定义控制台应用程......
  • C++使用ranges库解析INI文件
    C++使用ranges库解析INI文件引言C++20引入了<ranges>头文件,C++23对其进行了完善,本文将使用该头文件提供的adaptor编写一个简单的ini解析器。ini文件格式介绍一般的ini文件由section和entry部分,比如[section]key=value;Thisisentry.section和entry均独占一行,其中sectio......
  • C++四种类型转换
    篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++四种类型转换相关的知识,希望对你有一定的参考价值。const_cast主要用于删除变量的const属性,便于赋值constinta=2;int*p=const_cast<int*>(&a);*p=3;reinterpret_cast仅仅是重新解释类型,没有二进制的......