表达式计算(中缀表达式转后缀前缀表达式)

2024-09-02 18:38

本文主要是介绍表达式计算(中缀表达式转后缀前缀表达式),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给出一个由加减乘除和括号构成的表达式计算表达式的值和表达式的前缀和后缀表达式

#include<stdio.h>
#include<string.h>
#include<math.h>
#define Inf 1e9
struct tree
{double date;char ch;tree *l,*r;tree(){ch='\0';date=0;l=r=NULL;}
};
double judge(char *s,int x,int y,double &n)
{double num=0;int i,ok=0;for(i=x; i<y; i++)if(s[i]>='0'&&s[i]<='9'){if(!ok)num=num*10+s[i]-'0';else num+=(s[i]-'0')*pow(10,ok-i);}else if(s[i]=='.'){ok=i;}else return 0;return n=num;
}
tree *build(char *s,int x,int y)
{tree *now=new tree;double num=Inf;judge(s,x,y,num);//printf("%c\n",s[x]);if(num!=Inf){now->date=num;return now;}int p=0,c1=-1,c2=-1;for(int i=x; i<y; i++)switch(s[i]){case '(':p++;break;case ')':p--;break;case '+':case '-':if(!p)c1=i;break;case '*':case '/':if(!p)c2=i;break;}if(c1<0)c1=c2;if(c1<0)return build(s,x+1,y-1);now->l=build(s,x,c1);now->r=build(s,c1+1,y);now->ch=s[c1];return now;
}
double dfs(tree *p)
{if(!p)return 0;if(p->l==p->r&&p->l==NULL)return p->date;switch (p->ch){case '+':return p->date=dfs(p->l)+dfs(p->r);break;case '-':return p->date=dfs(p->l)-dfs(p->r);break;case '*':return p->date=dfs(p->l)*dfs(p->r);break;case '/':return p->date=dfs(p->l)/dfs(p->r);break;}return 0;
}
void dfs(tree *p,int choose)
{if(!p)return ;if(p->l==p->r&&p->l==NULL){printf(" %g",p->date);}if(!choose){printf("%c",p->ch);dfs(p->l,choose);dfs(p->r,choose);}else {dfs(p->l,choose);dfs(p->r,choose);printf("%c",p->ch);}
}
char s[1005];
int main()
{tree *root=NULL;while(gets(s)==NULL){root=NULL;int len=strlen(s);root=build(s,0,len);double ans=dfs(root);puts("前缀表达式:");dfs(root,0);puts("");puts("后缀表达式:");dfs(root,1);puts("");printf("%s=%g\n",s,ans);}return 0;
}

上面的不能计算5*-6这种,下面的进行了改正


#include<stdio.h>
#include<string.h>
#include<math.h>
#define Inf 1e9
struct tree
{double date;char ch;tree *l,*r;tree(){ch='\0';date=0;l=r=NULL;}
};
char st[1005];
double judge(char *s,int x,int y,double &n)
{double num=0;int i,ok=0;for(i=x; i<y; i++)if(s[i]>='0'&&s[i]<='9'){if(!ok)num=num*10+s[i]-'0';else num+=(s[i]-'0')*pow(10,ok-i);}else if(s[i]=='.'){ok=i;}else return 0;return n=num;
}
int is_operator(char c)
{if(c=='+'||c=='-'||c=='*'||c=='/')return 1;return 0;
}
tree *build(char *s,int x,int y)
{tree *now=new tree;double num=Inf;judge(s,x,y,num);//printf("%c\n",s[x]);if(num!=Inf){now->date=num;return now;}int p=0,c1=-1,c2=-1;for(int i=x; i<y; i++)if(s[i]=='-'&&is_operator(s[i-1])){int t=2;st[0]='(';st[1]='0';int k=0,ok=1;for(int j=i; j<y; j++){if(s[i]=='(')k++;else if(s[i]==')')k--;st[t++]=s[j];if((ok&&j==y-1)||(!k&&is_operator(s[i+1]))){ok=0;st[t++]=')';}}s[t]='\0';memcpy(s+i,st,sizeof(st));i--;y+=3;}elseswitch(s[i]){case '(':p++;break;case ')':p--;break;case '+':case '-':if(!p)c1=i;break;case '*':case '/':if(!p)c2=i;break;}if(c1<0)c1=c2;if(c1<0)return build(s,x+1,y-1);now->l=build(s,x,c1);now->r=build(s,c1+1,y);now->ch=s[c1];return now;
}
double dfs(tree *p)
{if(!p)return 0;if(p->l==p->r&&p->l==NULL)return p->date;switch (p->ch){case '+':return p->date=dfs(p->l)+dfs(p->r);break;case '-':return p->date=dfs(p->l)-dfs(p->r);break;case '*':return p->date=dfs(p->l)*dfs(p->r);break;case '/':return p->date=dfs(p->l)/dfs(p->r);break;}return 0;
}
void dfs(tree *p,int choose)
{if(!p)return ;if(p->l==p->r&&p->l==NULL){printf(" %g",p->date);}if(!choose){printf("%c",p->ch);dfs(p->l,choose);dfs(p->r,choose);}else{dfs(p->l,choose);dfs(p->r,choose);printf("%c",p->ch);}
}
char s[1005];
int main()
{tree *root=NULL;while(gets(s)!=NULL){root=NULL;int len=strlen(s);root=build(s,0,len);double ans=dfs(root);puts("前缀表达式:");dfs(root,0);puts("");puts("后缀表达式:");dfs(root,1);puts("");printf("%s=%g\n",s,ans);}return 0;
}



这篇关于表达式计算(中缀表达式转后缀前缀表达式)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130750

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成