首页 > 其他分享 >北林OJ基于栈的后缀表达式求值

北林OJ基于栈的后缀表达式求值

时间:2023-10-17 13:07:07浏览次数:36  
标签:ch return OJ int double OPND 北林 求值 Stack

思路1:(较易理解)

#include<iostream>
#include <iomanip>
using namespace std;
#define OK 1
#define ERROR 0
#define MaxSize 100
typedef double ElemType;
//定义栈_顺序栈

struct Stack
{
	ElemType* top;
	ElemType* base;
	int stacksize;
};
int IsFull(Stack s);
int IsEmpty(Stack s);
//初始化
int InitStack(Stack& s)
{
	s.base = new ElemType[MaxSize];
	if (!s.base)
		return ERROR;
		s.top = s.base;
	s.stacksize = MaxSize;
	return OK;
}
//入栈
int PushbackStack(Stack& s, ElemType e)
{
	//判断栈是否满
	if (IsFull(s))
		return ERROR;
	*(s.top) = e;//error
	(s.top)++;
	return OK;
}
//出栈
ElemType Popback(Stack& s)
{
	//判断栈是否空
	if (IsEmpty(s))
		return ERROR;
	s.top--;
	return *(s.top);
}
//判满
int IsFull(Stack s)
{
	if (s.top - s.base == s.stacksize)
		return 1;
	return 0;
}
//判空
int IsEmpty(Stack s)
{
	if (s.base == s.top)
		return 1;
	return 0;
}
//获取栈顶元素
ElemType StackTop(Stack s)
{
	//判断栈是否空
	if (IsEmpty(s))
		return ERROR;
	return *(s.top - 1);
}
//清除栈
int ClearStack(Stack& s)
{
	s.top = s.base;
	return OK;
}

int Destroy(Stack& s)
{
	delete s.base;
	s.top = s.base = NULL;
	return OK;
}
//计算
double calculating(double num1, char s, double num2)
{
	switch (s)
	{
	case'+':
		return (double)(num1 + num2)*(1.0);
	case'-':
		return (double)(num1 - num2) * (1.0);
	case'*':
		return (double)(num1 * num2) * (1.0);
	case'/':
		return (double)((num1*1.00) /(double) num2) * (1.0);
	}
}
double EvaluateExpressionSuffix(int &flag)
{
	//OPND:存放数字
	Stack OPND;
	char ch;
	
	InitStack(OPND);
	cin >> ch;
	if (ch == '=')
	{
		flag = 0;
		return ERROR;
	}
	do
	{
		if (isdigit(ch))
		{
			PushbackStack(OPND, (double)(ch - 48));//将字符转为数字,如果是ch,结果为-1
			cin >> ch;
		}
		else
		{
			
			PushbackStack(OPND, calculating(Popback(OPND),
				ch, Popback(OPND)));//计算结果并入栈
			cin >> ch;
		}
	} while (ch != '=');
	return Popback(OPND);
	
}
void test1()
{
	int flag = 1;
	while (1)
	{
		double outcome=EvaluateExpressionSuffix(flag);
		if (!flag)
			return;
		cout << fixed << setprecision(2) << outcome << endl;
	}
}
int main()
{

	test1();
	
	return 0;
}

遇到的问题:类型的转换:从char类型转换到其他类型

double类型数据精度:保留两位小数

思路二:将每行输入存放到数组里,从数组中读取

栈的操作与之前相同,下面便不再写了

//计算
double calculating(double num1, char s, double num2)
{
	switch (s)
	{
	case'+':
		return (double)(num1 + num2)*(1.0);
	case'-':
		return (double)(num1 - num2) * (1.0);
	case'*':
		return (double)(num1 * num2) * (1.0);
	case'/':
		return (double)((num1*1.00) /(double) num2) * (1.0);
	}
}
Status EvaluateExpressionSuffix(char *s)
{
	//OPND:存放数字
	Stack OPND;
	InitStack(OPND);
	int i = 0;
	if (s[i] == '=')//防止死循环
		return ERROR;
	while (s[i] != '='&&s[i]!='\0')
	{
		if (isdigit(s[i]))
		{
			PushbackStack(OPND, (double)(s[i] - 48));//将字符转为数字,如果是ch,结果为-1

		}
		else if (s[i] == ' ')
			;
		else
		{
			//error
			PushbackStack(OPND, calculating(Popback(OPND),
				s[i], Popback(OPND)));//计算结果并入栈
		}
		i++;
	} 
	cout << fixed << setprecision(2) << Popback(OPND) << endl;
	return OK;
}
void test1()
{
	while (1)
	{
		char s[MaxSize];//死循环打印0.00,为什么??
		//因为cin.get操作后会在缓冲区存留0
		cin.get(s, MaxSize);//读入数据并存放到数组s中,在字符串尾部加'\0'
		char ch = cin.get();//	清除缓冲区结尾残留的字符\0
		int flag = EvaluateExpressionSuffix(s);
		if (!flag )
			break;
	}
	
	return;
}
int main()
{

	test1();
	
	return 0;
}

北林OJ基于栈的后缀表达式求值_Stack

问题:计算1 2/=时,结果总是为0.00,

解决:将整数除法转化为小数除法,影响转换成double在计算,注意顺序

使用cin>>读取每一行时遇到空格会停止,所以要使用cin.get函数

对cin函数不够了解导致出错

解决:查找资料,并自己写一些简单的例子测试,多多调试加深理解

cin相关知识点:https://blog.csdn.net/a3192048/article/details/80303547

如果对cin及其函数不太了解,推荐第一种写法

标签:ch,return,OJ,int,double,OPND,北林,求值,Stack
From: https://blog.51cto.com/u_15805257/7901705

相关文章

  • 2023年10月最新全国省市区县和乡镇街道行政区划矢量边界坐标经纬度地图数据 shp geojs
    发现个可以免费下载全国 geojson 数据的网站,推荐一下。支持全国、省级、市级、区/县级、街道/乡镇级以及各级的联动数据,支持导入矢量地图渲染框架中使用,例如:D3、Echarts等geojson数据下载地址:https://geojson.hxkj.vip该项目github地址:https://github.com/TangSY/echarts-m......
  • 10_逆波兰表达式求值
    逆波兰表达式求值给你一个字符串数组tokens,表示一个根据逆波兰表示法表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。对应于leetcode150注意:有效的算符为'+'、'-'、'*'和'/'。每个操作数(运算对象)都可以是一个整数或者另一个表达式。两个整数......
  • 【ZROJ2730】简单题 可持久化分块题解
    Description给定一棵\(n\)个节点的树,每次询问编号为\([l,r]\)的点中有多少个是祖先关系。\(n,q\le10^5\)。Solution直接做的话树上的祖先关系不好统计,那么转化到\(\texttt{dfs}\)序上,如果\(u\)是\(v\)的祖先那么\(dfn_u\ledfn_v<dfn_u+siz_u\)。把\([d......
  • POJO
    POJO(PlainOrdinaryJavaObject)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。使用POJO名称是为了避免和EJB混淆起来,而且简称比较直接.其中有一些属性及其gettersetter方法的类,没有业务逻辑,有时可以作为VO(value-object)或dto(DataTransformObjec......
  • QOJ # 4588. Feeder Robot
    题面传送门有一个机器人初始在\(A\)点,每次会向左向右随机移动,并给所到位置的\(B\)值\(+1\),包括起点。当加\(m\)次后停止,设终点为\(t\),问最后\((t,B)\)二元组总共有多少种可能。\(n\leq10^5,m\leq2\times10^5\)。首先我们需要考虑如何找到一个\((t,B)\)二元组合......
  • LOJ2831
    JOISC2018Construction题目链接Statement给定$n$个点,初始时$i$号点的权值为$c_i$。接下来进行$n-1$次加边操作,每次连接一条边$(u,v)$,保证此时$u$与$1$号点连通,$v$与$1$号点不连通。对于每一次加边,求出$1$号点到$u$的简单路径上的逆序对数量,并在操作结束......
  • Python中生成GeoJSON数据
    要在Python中生成GeoJSON数据,可以使用GeoJSON库,例如geojson库或geopandas库。以下是使用这些库生成GeoJSON数据的简单示例:使用geojson库生成GeoJSON数据首先,确保已安装了geojson库,可以使用pip进行安装:pipinstallgeojson然后,可以按照以下方式生成GeoJSON数据:importgeojso......
  • poj 1742 coins
    DescriptionPeopleinSilverlandusecoins.TheyhavecoinsofvalueA1,A2,A3...AnSilverlanddollar.OnedayTonyopenedhismoney-boxandfoundthereweresomecoins.Hedecidedtobuyaverynicewatchinanearbyshop.Hewantedtopaytheexactprice(wi......
  • NOJ 8皇后问题 (n皇后问题)
    描述:输出8皇后问题所有结果。输入:没有输入。输出:每个结果第一行是Non:的形式,n表示输出的是第几个结果;下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格。不同的结果中,先输出第一个皇后位置靠前的结果;第一个皇后位置相同,先输出第二个皇后位置靠前的结果;依次类推。输出样例:输出......
  • JSONObject.toJSONString 详细介绍
    JSONObject.toJSONString详细介绍StringjsonString=JSONObject.toJSONString(sendMap,SerializerFeature.DisableCircularReferenceDetect);JSONObject.toJSONString:这是FastJSON中的一个方法,用于将Java对象转换为JSON字符串。sendMap:这是要被转换成JSON......