数据结构课程设计四则运算表达式求值(C语言版)
明人不说暗话,直接上百度网盘链接,输入提取码z3fy即可下载。
文件中包含程序,程序运行文件,设计报告和测试样例,应有尽有,欢迎小伙伴们在中下载使用。
本课程设计为四则运算表达式求值,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值。
注意事项:
1、请保证输入的四则表达式的合法性。输入的中缀表达式中只能含有英文符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及小数点“.”,输入“=”表示输入结束。例如9+(3-1)*3.567+10/2=,特别是请勿输入多余空格和中文左右括号。
2、输入的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。
3、请保证输入的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。本课程设计中操作数是C语言中的双精度浮点数类型。
4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。
下面的程序正常运行需要在上面的百度网盘中下载相应文件,否则无法正常使用哦。
/*本程序为四则运算表达式求值系统,用于计算带小括号的四则运算表达式求值。
具体算法:
先将字符串处理成操作单元(操作数或操作符),再利用栈根据四则运算
的运算法则进行计算,最后得出结果。*/ #include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h> const int Expmax_length = ;//表达式最大长度,可根据适当情况调整
struct Ope_unit
{//定义操作单元
int flag;//=1表示是操作数 =0表示是操作符 -1表示符号单元
char oper;//操作符
double real;//操作数,为双精度浮点数
}; void Display();//菜单
void Instru(); //使用说明
int Check(char Exp_arry[]);
void Evalua(); //先调用Conver操作单元化,再调用Calculate函数计算结果并输出
int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元
int Isoper(char ch);//判断合法字符(+ - * / ( ) =)
int Ope_Compar(char ope1,char ope2);//操作符运算优先级比较
double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//用栈计算表达式结果
double Four_arithm(double x,double y,char oper);//四则运算 int main()
{
int select;
while()
{
Display();
printf("请输入欲执行功能对应的数字:");
scanf("%d",&select);
printf("\n");
switch(select)
{
case : Evalua(); break;
case : Instru(); break;
case : return ;
default : printf("无该数字对应的功能,请重新输入\n");
system("pause");
}
}
return ;
} int Check(char Exp_arry[])
{//检查是否有非法字符,返回1表示不合法,0表示合法
int Explength=strlen(Exp_arry),i;
for(i=;i<Explength;i++)
{
if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))
return ;
if(isdigit(Exp_arry[i]))
{
int Dig_number=,Cur_positoin=i+;
while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')
{
Dig_number++;
Cur_positoin++;
}
if(Dig_number >= )//最多能够计算15位有效数字
return ;
}
}
return ;
} void Evalua()
{//先调用Conver函数将字符串操作单元化,再调用Calculate函数计算结果并输出
char Exp_arry[Expmax_length];
int flag=;//假设刚开始不合法,1表达式合法,0不合法
struct Ope_unit Opeunit_arry[Expmax_length]; getchar();//吃掉一个换行符
printf("请输入四则运算表达式,以=结尾:\n");
gets(Exp_arry);
flag=Check(Exp_arry);
if(flag)
printf("该表达式不合法!\n");
else
{
int Opeunit_count = Conver(Opeunit_arry,Exp_arry);
double ans = Calculate(Opeunit_arry,Opeunit_count,flag);
if(flag)
{
printf("计算结果为:\n");
printf("%s%lf\n",Exp_arry,ans);
}
else
printf("该表达式不合法!\n");
}
system("pause");
} int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])
{//将字符串操作单元化
int Explength=strlen(Exp_arry);
int i,Opeunit_count=;
for(i=;i<Explength;i++)
{
if(Isoper(Exp_arry[i]))//是操作符
{
Opeunit_arry[Opeunit_count].flag=;
Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];
}
else//是操作数
{
Opeunit_arry[Opeunit_count].flag=;
char temp[Expmax_length];
int k=;
for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)
{
temp[k++]=Exp_arry[i];
}
i--;
temp[k]='\0';
Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数 //负数
if(Opeunit_count == && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper=='-')
{
Opeunit_arry[Opeunit_count-].flag = -;
Opeunit_arry[Opeunit_count].real *= -;
}// -9
if(Opeunit_count >= && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper=='-' && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper !=')')
{
Opeunit_arry[Opeunit_count-].flag = -;
Opeunit_arry[Opeunit_count].real *= -;
}// )-9 //正数
if(Opeunit_count == && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper=='+')
{
Opeunit_arry[Opeunit_count-].flag = -;
}// +9
if(Opeunit_count >= && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper=='+' && Opeunit_arry[Opeunit_count-].flag==
&& Opeunit_arry[Opeunit_count-].oper !=')')
{
Opeunit_arry[Opeunit_count-].flag = -;
}// )+9
Opeunit_count++;
}
}
/*for(i=0;i<Opeunit_count;i++)
{//查看各操作单元是否正确,1是操作数,0是操作符
if(Opeunit_arry[i].flag == 1)
printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);
else if(Opeunit_arry[i].flag == 0)
printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);
else
printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);
}*/
return Opeunit_count;
} double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)
{//根据运算规则,利用栈进行计算
int i,dS_pointer=,oS_pointer=;//dS_pointer为操作数栈顶指示器,oS_pointer为操作符栈顶指示器
double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)
char Ope_stack[Expmax_length];//操作符栈 for(i=;i<Opeunit_count-;i++)
{
if( Opeunit_arry[i].flag != - )
{
if(Opeunit_arry[i].flag)//是操作数
{
Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//入操作数栈
//printf("%lf\n",Digit[dS_pointer-1]);
}
else//是操作符 + - * / ( )
{
//操作符栈为空或者左括号 入栈
if(oS_pointer== || Opeunit_arry[i].oper=='(')
{
Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);
}
else
{
if(Opeunit_arry[i].oper==')')//是右括号将运算符一直出栈,直到遇见左括号
{
oS_pointer--;//指向栈顶
dS_pointer--;//指向栈顶
while(Ope_stack[oS_pointer] != '(' && oS_pointer != )
{
Dig_stack[dS_pointer-] = Four_arithm(Dig_stack[dS_pointer-],Dig_stack[dS_pointer],
Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈 dS_pointer--;//前一个操作数出栈
//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);
}
oS_pointer--;//左括号出栈 oS_pointer++;//恢复指向栈顶之上
dS_pointer++;
}
else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-]))//和栈顶元素比较
{
Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);
}
else//运算符出栈,再将该操作符入栈
{
oS_pointer--;//指向栈顶
dS_pointer--;//指向栈顶
while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])== && oS_pointer != -)
{//当前操作符比栈顶操作符优先级高
Dig_stack[dS_pointer-]=Four_arithm(Dig_stack[dS_pointer-],Dig_stack[dS_pointer],
Ope_stack[oS_pointer--]);
dS_pointer--;
//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);
}
oS_pointer++;//恢复指向栈顶之上
dS_pointer++;
Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
}
}
}
}
}
/*for(i=0;i<oS_pointer;i++)
printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);
for(i=0;i<dS_pointer;i++)
printf("操作数栈%lf\n",Digit[i]);*/
oS_pointer--;//指向栈顶元素
dS_pointer--;//指向栈顶元素
while(oS_pointer != -)
{
Dig_stack[dS_pointer-]=Four_arithm(Dig_stack[dS_pointer-],Dig_stack[dS_pointer],
Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈
dS_pointer--;//前一个操作数出栈
//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);
}
//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);
if(oS_pointer==- && dS_pointer==)
flag=;//为1表示表达式合法
return Dig_stack[];
} int Ope_Compar(char ope1,char ope2)
{//操作符运算优先级比较
char list[]={"(+-*/"};
int map[][]={//先行后列,行比列的运算级优先级低为0,高为1
// ( + - * /
/* ( */ ,,,,,
/* + */ ,,,,,
/* - */ ,,,,,
/* * */ ,,,,,
/* / */ ,,,, };
int i,j;
for(i=;i<;i++)
if(ope1==list[i]) break;
for(j=;j<;j++)
if(ope2==list[j]) break;
return map[i][j];
} double Four_arithm(double x,double y,char oper)
{//四则运算
switch(oper)//保证不含其它运算符
{
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': return x/y;//y不能为0
default : return ;
}
} int Isoper(char ch)
{//判断合法字符 + - * / ( ) =
if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')
return ;
return ;
} void Display()
{//打印菜单
system("cls");
printf("/******************************************************************************/\n");
printf("\t\t 欢迎使用本四则运算表达式求值系统\n");
printf("\n\t说明:建议请您先阅读使用说明,再输入相应的数字进行操作,谢谢配合!\n");
printf("\n\t\t1 四则运算表达式求值\n");
printf("\n\t\t2 使用说明\n");
printf("\n\t\t0 退出\n");
printf("/******************************************************************************/\n");
} void Instru()
{//打印使用说明
FILE *fp;
char ch;
if( ( fp=fopen("使用说明.txt","r") ) == NULL)
{
printf("文件打开失败!\n");
exit();
}
for(; (ch = fgetc(fp)) != EOF; )
putchar(ch);
fclose(fp);
printf("\n");
system("pause");
}
数据结构课程设计四则运算表达式求值(C语言版)的更多相关文章
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- 数据结构--栈的应用(表达式求值 nyoj 35)
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...
- C语言之四则运算表达式求值(链栈)—支持浮点型数据,负数, 整型数据运算
运算符间的优先级关系: 链栈结构体定义: 数据域使用字符串长度为20的字符数组(故需要注意判断读取的字符串是运算符还是数值) 可支持浮点型数据,负数, 整型数据的运算 float EvaluateE ...
- 去空格的四则运算表达式求值-Java
笔记 package com.daidai.day4.demo1; import java.util.ArrayList; import java.util.Arrays; import java.u ...
- LeetCode150 逆波兰表达式求值
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...
- 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值
一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...
- C++表达式求值(利用数据结构栈)
唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行.这不经让我 想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的 ...
- 表达式求值--数据结构C语言算法实现
这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用. 数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题. 这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存 ...
- 用Python3实现表达式求值
一.题目描述 请用 python3 编写一个计算器的控制台程序,支持加减乘除.乘方.括号.小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算. 二.输入描 ...
随机推荐
- 学会C sharp计算机编程语言 轻松开发财务、统计软件
就像人们用同一种语言才可以顺畅交流一样,语言是计算机编程的根本,是IT世界交流的工具.运用这些计算机语言,人们可以创造出一个美妙的世界.你点击某个网页或是安装一个应用程序软件,这简简单单动作的背后,就 ...
- Golang 网络爬虫框架gocolly/colly 一
Golang 网络爬虫框架gocolly/colly 一 gocolly是用go实现的网络爬虫框架,目前在github上具有3400+星,名列go版爬虫程序榜首.gocolly快速优雅,在单核上每秒可 ...
- C/C++调用Golang 二
C/C++调用Golang 二 <C/C++调用Golang 一>简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用.本文总结具体项目中的使用场景,将介绍三种较复杂的 ...
- calling c++ from golang with swig--windows dll (四)
calling c++ from golang with swig--windows dll 四 前面讲述了windows环境下golang如何通过swig调用C++ dll.由于编译c++代码使用了 ...
- uEditor富文本编辑器
在配合vue和webpack使用时,在严格模式下注意会报错,需要修改配置. 我采用的方式:----不建议全部取消严格模式,因为一些插件必须要再严格模式才能运行的 对UEditor的严格模式报错文件,取 ...
- redis实现分布式可重入锁
利用redis可以实现分布式锁,demo如下: /** * 保存每个线程独有的token */ private static ThreadLocal<String> tokenMap = ...
- Debian安装fail2ban来防止扫描
vps的root密码不要设置的太简单,这样很容易被攻破,你可以安装如下软件来降低vps被攻破的机会. 输入如下命令: apt-get install fail2ban 提示如下表示安装完成: root ...
- Android应用程序启动时发生AndroidRuntime : ClassNotFoundException for Activity class的解决方法
在android应用程序启动时抛出下面异常导致启动失败:07-09 17:12:35.709: ERROR/AndroidRuntime(3866): Uncaught handler: thread ...
- pagelatch等待在tempdb的gsm页面上
Each data file has a gam page, sql will update it when allocate space in the file. Will see contenti ...
- LindDotNetCore~入门基础
回到目录 LindDotNetCore基础介绍 运行环境 配置文件 服务的注册 配置文件的注册 服务的使用 配置文件的使用 运行环境 vs2017+.netcore2.0,vs需要升级到最新包 配置文 ...