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

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

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Java Lambda表达式的使用详解

《JavaLambda表达式的使用详解》:本文主要介绍JavaLambda表达式的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言二、Lambda表达式概述1. 什么是Lambda表达式?三、Lambda表达式的语法规则1. 无参数的Lambda表

正则表达式r前缀使用指南及如何避免常见错误

《正则表达式r前缀使用指南及如何避免常见错误》正则表达式是处理字符串的强大工具,但它常常伴随着转义字符的复杂性,本文将简洁地讲解r的作用、基本原理,以及如何在实际代码中避免常见错误,感兴趣的朋友一... 目录1. 字符串的双重翻译困境2. 为什么需要 r?3. 常见错误和正确用法4. Unicode 转换的

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

Java如何根据文件名前缀自动分组图片文件

《Java如何根据文件名前缀自动分组图片文件》一大堆文件(比如图片)堆在一个目录下,它们的命名规则遵循一定的格式,混在一起很难管理,所以本文小编就和大家介绍一下如何使用Java根据文件名前缀自动分组图... 目录需求背景分析思路实现代码输出结果知识扩展需求一大堆文件(比如图片)堆在一个目录下,它们的命名规

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

SpringBoot @Scheduled Cron表达式使用方式

《SpringBoot@ScheduledCron表达式使用方式》:本文主要介绍SpringBoot@ScheduledCron表达式使用方式,具有很好的参考价值,希望对大家有所帮助,如有... 目录Cron 表达式详解1. 表达式格式‌2. 特殊字符解析3. 常用示例‌4. 重点规则5. 动态与复杂场景‌

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启