逆波兰表达式

逆波兰

16:00~22:00花了好久好久学了一下这个东西
逆波兰真的好强

 //逆波兰后缀表达式 利用堆栈实现 堆栈用数组实现 
#include<bits/stdc++.h>
using namespace std;
#define stack astack
char stack[500];//存符号 
char out[500],in[500];//输出 输入 
int dtop,top,len;
double dstack[500];//存数字 
int f1(int x)//阶乘 
{
	if(x==0||x==1)return 1; 
	else return x*f1(x-1);
}
bool isoperator(char ch)
{
	return (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^'||ch=='!');
}
int prior(char a){
	if(a=='+'||a=='-')return 1;
	if(a=='*'||a=='/')return 2;
	if(a=='^'||a=='!')return 3;
}//优先级赋值 
void rePolish(char* a)
{
	for(int i=0;i<strlen(a);i++)
	{
		if(isdigit(a[i]))
		{
			out[len++]=a[i];
			while(isdigit(a[i+1])&&i<strlen(a)-1){
				out[len++]=a[++i];
			}//是数 就输出 输出不用printf而是存到out数组里 
			out[len++]=' ';
		}
		if(a[i]=='('){
			stack[++top]=a[i];//左括号入栈 top要和指的地方一致 
		}
		if(a[i]==')'){
			while(stack[top]!='(')
			out[len++]=stack[top--];
			top--;
			out[len++]=' ';
		}//右括号不入栈 一直输出直到遇到左括号 栈顶top再减一下跳过左括号 
		
		while(isoperator(a[i])) //遇到操作符 如果优先级比栈顶的低 要把前面的优先级也高的全部弹出 因此必须用while 
		//if(isoperator(a[i])) 用if的话只能弹一下 如果是1*2*3+5 就只得到一个*号 
		{
			if(prior(a[i])>prior(stack[top])||top==0||stack[top]=='(')
			{
					stack[++top]=a[i];//栈空或者优先级高就入栈 当前栈顶是左括号也要入栈  
					break;//需要break掉 while下一轮循环 
				}
			
			else{
				out[len++]=stack[top--];//优先级低就出栈 有括号也是这个效果 
				out[len++]=' ';
			}	
		}
	}
	while(top)
	{
		out[len++]=stack[top--];
		out[len++]=' ';	
	}//弹出栈里剩余的东西 
	
}
double cal(double x,double y,char ch)
{
	if(ch=='+')return x+y;
	if(ch=='-')return x-y;
	if(ch=='*')return x*y;
	if(ch=='/')return x/y;
	if(ch=='^')return pow(x,y); 
}
double calculate(char *a)
{
	char d[100];//定义一个字符数组 存数 
	for(int i=0;a[i];i++)
	{
		if(a[i]!=' '){
			sscanf(a+i,"%s",d);//妙啊 利用前面打出的空格区分数 用sscanf读入一串数或者操作符到d里面 
			if(isdigit(d[0]))
				dstack[++dtop]=atof(d);//超有用的函数atof 将字符转化成double char类型的123.456变成了double型的123.456000 
			else{
				if(d[0]=='!'){
					dstack[dtop]=(double)f1((int)dstack[dtop]);//单目 对栈顶操作就行 
				}
				else{
					dstack[dtop-1]=cal(dstack[dtop-1],dstack[dtop],d[0]);//双目运算的话 计算栈顶的两个数 
					dtop--;
				}
			}
		}
		while(a[i]&&a[i]!=' ')i++;
		
		}
	return dstack[dtop];
}
int main()
{
	scanf("%s",in);
	rePolish(in);
	printf("%s\n",out);
	printf("%lf\n",calculate(out));
	return 0;
}

这就相当于一个计算器了吧 好棒啊~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值