c语言实现表达式求值的方法

发布时间:2020-06-22 16:45:46

来源:亿速云

阅读:82

作者:Leah

这期内容当中小编将会给大家带来有关c语言实现表达式求值的方法,以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

一.不包括括号运算#include

#include

#include

#include

#include

#define STACK_INIT_SIZE 100

using namespace std;

typedef struct

{

char date[STACK_INIT_SIZE];

int top;

}OptrStack; //操作符结构体

typedef struct

{

double date[STACK_INIT_SIZE];

int top;

}OpndStack; //操作数结构体

//操作符相关操作

OptrStack *Init_OptrStack(); //置栈空

int Empty_OptrStack(OptrStack *s);//判空栈

int Push_OptrStack(OptrStack *s, char x);//入栈(注意:判断栈是否已满)

char Pop_OptrStack(OptrStack *s, char x);//出栈(注意:判断栈是否已空)

char GetTop_OptrStack(OptrStack *s, char x);//取栈顶元素,先判空

//操作数相关操作

OpndStack *Init_OpndStack();//置栈空

int Empty_OpndStack(OpndStack *t);//判空栈

int Push_OpndStack(OpndStack *t, double y);//入栈(注意:判断栈是否已满)

double Pop_OpndStack(OpndStack *t, double y);//出栈(注意:判断栈是否已空)

double GetTop_OpndStack(OpndStack *t, double y);//取栈顶元素

//表达式求值函数

void Error(char *s); //错误处理函数

int Judge_optr(char ch); //用于判断字符ch是否是运算符

int Operate(int a, int b, char top); //用于计算当前的值,并将该值返回

void Jsbds_operate(char str[]); //读入一个简单算术表达式的值

//操作符函数实现部分

OptrStack *Init_OptrStack()

{

OptrStack *s;

s = (OptrStack *)malloc(sizeof(OptrStack));

s->top = -1;

return s;

}

int Empty_OptrStack(OptrStack *s)//判空栈

{

if (s->top != -1)

return 1;

else

return 0;

}

int Push_OptrStack(OptrStack *s, char x)//入栈(注意:判断栈是否已满)

{

if (s->top == (STACK_INIT_SIZE - 1))

{

return 0;

}

else

s->date[++s->top] = x;

return 1;

}

char Pop_OptrStack(OptrStack *s, char x)//出栈(注意:判断栈是否已空)

{

if (!Empty_OptrStack(s))

{

return 0;

}

else

x = s->date[s->top];

s->top--;

return x;

}

char GetTop_OptrStack(OptrStack *s, char x)//取栈顶元素,先判空

{

if (!Empty_OptrStack(s))

{

return 0;

}

else

x = s->date[s->top];

return x;

}

//操作数函数实现部分

OpndStack *Init_OpndStack()//置栈空

{

OpndStack *t;

t = (OpndStack*)malloc(sizeof(OpndStack));

t->top = -1;

return t;

}

int Empty_OpndStack(OpndStack *t)//判空栈

{

if (t->top != -1)

return 1;

else

return 0;

}

int Push_OpndStack(OpndStack *t, double y)//入栈(注意:判断栈是否已满)

{

if (t->top == (STACK_INIT_SIZE - 1))

{

return 0;

}

else

t->date[++t->top] = y;

return 1;

}

double Pop_OpndStack(OpndStack *t, double y)//出栈(注意:判断栈是否已空)

{

if (!Empty_OpndStack(t))

{

return 0;

}

else

y = t->date[t->top];

t->top--;

return y;

}

double GetTop_OpndStack(OpndStack *t, double y)//取栈顶元素

{

if (!Empty_OpndStack(t))

{

return 0;

}

y = t->date[t->top];

return y;

}

//表达式求值函数实现

void Error(char *s) //错误处理函数

{

std::cout << s << endl;

exit(1);

}

int Judge_optr(char top)//用于判断字符ch是否是运算符

{

int x;

//cout << top << "test" << endl;

switch (top)

{

case '+':

case '-':

x = 1; break;

case '*':

case '/':

x = 2; break;

}

return x;

}

double Operate(double b, double a, char top) //用于计算当前的值,并将该值返回

{

double c = 0;

switch (top)

{

case '+':

c = b + a;

break;

case '-':

c = b - a;

break;

case '*':

c = b * a;

break;

case '/':

if (a == 0)

{

printf("分母为零!\n");

return 0;

}

else

c = b / a;

break;

default:

printf("输入的字符非法!\n");

break;

}

return c;

}

void Jsbds_operate(char str[]) //读入一个简单算术表达式,并将计算结果返回到主函数

{

OptrStack *optr = Init_OptrStack(); //初始化操作符栈

OpndStack *opnd = Init_OpndStack(); //初始化操作数栈

int i, j; //i,j为循环变量,a,b接收从操作数栈中出栈的元素

double f; //接收将字符数转换为浮点数的值

double a = 0;

double b = 0;

double c = 0;

char d[100]; //储存字符串中连续的‘数’

char top = 0; //接收从操作符栈中出栈的元素

for (i = 0; str[i]; i++) //将字符串中的元素按顺序入到栈中

{

switch (str[i])

{

case '+':

case '-':

/*先判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;

小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,

再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,

并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。*/

if (!Empty_OptrStack(optr)) //当操作符栈为空的时候压栈保存

{

Push_OptrStack(optr, str[i]);

}

else

{

a = Pop_OpndStack(opnd, a); //接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b); //接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

Push_OptrStack(optr, str[i]);

}

break;

case '*':

case '/':

if ((!Empty_OptrStack(optr))||(Judge_optr(str[i]) > Judge_optr(GetTop_OptrStack(optr, top))))

{ //当操作符栈为空或者该操作符的优先级大于栈顶元素的优先级是入栈保存

Push_OptrStack(optr, str[i]);

}

else

{

a = Pop_OpndStack(opnd, a);//接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b);//接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

Push_OptrStack(optr, str[i]);

}

case '\0':

break;

default:

j = 0;

do

{

d[j++] = str[i];

i++;

} while (str[i] >= '0' && str[i] <= '9'); //可存入一个或多个数字字符

d[j] = '\0'; //将输入的连续多个数字字符拼成了字符串

i--;

f = atof(d); //调用库函数atoi()将字符数转换为浮点数

Push_OpndStack(opnd, f); //将转换后的数压入操作数栈中

break;

}

}

while (Empty_OptrStack(optr)) //当操作符栈不为空的时候执行

{

a = Pop_OpndStack(opnd, a);//接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b);//接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

}

cout << "该表达式的计算结果为:";

std::cout << GetTop_OpndStack(opnd, c) << endl;//将操作数栈中的元素(即表达式的最终结果)打印出来

}

int main()

{

char str[100];

std::cout << "请输入算术表达式(功能:+,-,*,/)" << endl;

cin >> str;

Jsbds_operate(str);

return 0;

}

二.包括括号运算(粘贴修改部分)int Judge_optr(char top)//用于判断字符ch是否是运算符

{

int x;

//cout << top << "test" << endl;

switch (top)

{

case '(':

x = 0; break;

case '+':

case '-':

x = 1; break;

case '*':

case '/':

x = 2; break;

case ')':

x = 3; break;

}

return x;

}

double Operate(double b, double a, char top) //用于计算当前的值,并将该值返回

{

double c = 0;

switch (top)

{

case '+':

c = b + a;

break;

case '-':

c = b - a;

break;

case '*':

c = b * a;

break;

case '/':

if (a == 0)

{

printf("分母为零!\n");

return 0;

}

else

c = b / a;

break;

default:

printf("输入的字符非法!\n");

break;

}

return c;

}

void Jsbds_operate(char str[]) //读入一个简单算术表达式,并将计算结果返回到主函数

{

OptrStack *optr = Init_OptrStack(); //初始化操作符栈

OpndStack *opnd = Init_OpndStack(); //初始化操作数栈

int i, j; //i,j为循环变量,a,b接收从操作数栈中出栈的元素

double f; //接收将字符数转换为浮点数的值

double a = 0;

double b = 0;

double c = 0;

char d[100]; //储存字符串中连续的‘数’

char top = 0; //接收从操作符栈中出栈的元素

for (i = 0; str[i]; i++) //将字符串中的元素按顺序入到栈中

{

switch (str[i])

{

case '(':

case '+':

case '-':

/*先判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;

小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,

再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,

并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。*/

if ((!Empty_OptrStack(optr)) || (Judge_optr(str[i]) > Judge_optr(GetTop_OptrStack(optr, top)))||(str[i]=='(')) //当操作符栈为空的时候压栈保存

{

Push_OptrStack(optr, str[i]);

}

else

{

a = Pop_OpndStack(opnd, a); //接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b); //接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

Push_OptrStack(optr, str[i]);

}

break;

case '*':

case '/':

if ((!Empty_OptrStack(optr)) || (Judge_optr(str[i]) > Judge_optr(GetTop_OptrStack(optr, top))) || (str[i] == '('))

{ //当操作符栈为空或者该操作符的优先级大于栈顶元素的优先级是入栈保存

Push_OptrStack(optr, str[i]);

}

else

{

a = Pop_OpndStack(opnd, a);//接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b);//接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

Push_OptrStack(optr, str[i]);

}

break;

case ')':

Push_OptrStack(optr, str[i]);

break;

case '\0':

break;

default:

j = 0;

do

{

d[j++] = str[i];

i++;

} while (str[i] >= '0' && str[i] <= '9'); //可存入一个或多个数字字符

d[j] = '\0'; //将输入的连续多个数字字符拼成了字符串

i--;

f = atof(d); //调用库函数atoi()将字符数转换为浮点数

Push_OpndStack(opnd, f); //将转换后的数压入操作数栈中

break;

}

}

while (Empty_OptrStack(optr)) //当操作符栈不为空的时候执行

{

if ((GetTop_OptrStack(optr, top) == ')') || (GetTop_OptrStack(optr, top) == '('))

{

top=Pop_OptrStack(optr, top);

}

else

{

a = Pop_OpndStack(opnd, a);//接收从操作数栈中出栈的元素

b = Pop_OpndStack(opnd, b);//接收从操作数栈中出栈的元素

top = Pop_OptrStack(optr, top);//接收从操作符栈中出栈的元素

c = Operate(b, a, top);

Push_OpndStack(opnd, c);

//将计算后的值压入操作数栈中

}

}

cout << "该表达式的计算结果为:";

std::cout << GetTop_OpndStack(opnd, c) << endl;//将操作数栈中的元素(即表达式的最终结果)打印出来

}

上述就是小编为大家分享的c语言实现表达式求值的方法了,如果您也有类似的疑惑,不妨参照上述方法进行尝试。如果想了解更多相关内容,请关注亿速云行业资讯。

c语言编程实现表达式求值,c语言实现表达式求值的方法相关推荐

  1. linux+下c语言编程项目,精通UNIX下C语言编程与项目实践

    cc -I  //include 目录 -L //静态库目录?动态也可以 -l //小写L,接静态库名称?动态也可以 -DXXX='"XXFF"' //-D直接定义宏 -c 只编译 ...

  2. c语言编程学多久,丰城c语言编程学习,丰城学c语言编程的学校,丰城学c语言编程一般要多久才能学会...

    丰城c语言编程学习,丰城学c语言编程的学校,丰城学c语言编程一般要多久才能学会 首页 > 软件 > 丰城c语言编程学习 作者:镀金池   发布时间:2018-04-09 16:40 在之后 ...

  3. c语言程序设计自学跟谁好,双辽c语言编程学习,双辽学c语言编程哪个好,双辽学c语言编程自学好还是报班好...

    双辽c语言编程学习,双辽学c语言编程哪个好,双辽学c语言编程自学好还是报班好 首页 > 软件 > 双辽c语言编程学习 作者:镀金池   发布时间:2017-12-07 05:48 一个C语 ...

  4. c语言程序设计需要学多久,九江c语言编程学习,九江学c语言编程报班,九江学c语言编程一般要多久才能学会...

    九江c语言编程学习,九江学c语言编程报班,九江学c语言编程一般要多久才能学会 首页 > C语言 > 九江c语言编程学习 作者:镀金池   发布时间:2017-10-18 14:11 据ID ...

  5. 成都c语言编程培训机构,成都学c语言编程,成都学c语言编程去哪里,成都学c语言编程需要报培训班吗...

    成都学c语言编程,成都学c语言编程去哪里,成都学c语言编程需要报培训班吗 首页 > 软件 > 成都学c语言编程 作者:镀金池   发布时间:2018-09-28 14:20 近似带有序布局 ...

  6. 汕头c语言培训班,汕头c语言编程学习,汕头学c语言编程哪个好,汕头学c语言编程需要报培训班吗...

    汕头c语言编程学习,汕头学c语言编程哪个好,汕头学c语言编程需要报培训班吗 首页 > C语言 > 汕头c语言编程学习 作者:镀金池   发布时间:2017-10-18 20:12 经历:若 ...

  7. 湛江C语言培训,湛江c语言编程学习,湛江学c语言编程报班,湛江学c语言编程自学好还是报班好...

    湛江c语言编程学习,湛江学c语言编程报班,湛江学c语言编程自学好还是报班好 首页 > C语言 > 湛江c语言编程学习 作者:镀金池   发布时间:2017-10-19 09:51 在Swi ...

  8. C语言编程b a化简,C语言编程,已知三角形的三边长a,b,c,计算求三角... 如果三角形三边长 a,b,c,满足( )那么这个三角形......

    导航:网站首页 > C语言编程,已知三角形的三边长a,b,c,计算求三角... 如果三角形三边长 a,b,c,满足( )那么这个三角形... C语言编程,已知三角形的三边长a,b,c,计算求三角 ...

  9. R语言编程艺术(3)R语言编程基础

    本文对应<R语言编程艺术> 第7章:R语言编程结构: 第9章:面向对象的编程: 第13章:调试 ============================================== ...

  10. c语言编程作业最大整数问题,C语言编程第六章作业答案.doc

    C语言编程第六章作业答案 1. 输入两个正整数m和n,求其最大公约数和最小公倍数. 辗除法--辗转相除法, 又名欧几里德算法(Euclidean algorithm)乃求两个正整数之最大公因子的算法. ...

最新文章

  1. 基于Spatial CNN的车道线检测和交通场景理解
  2. 快逸报表参数查询前报表不显示
  3. python打卡记录去重_python中对list去重的多种方法
  4. python大数据项目_(价值1280)大数据项目实战之Python金融应用编程
  5. 绝对经典的滑动门特效代码
  6. 不同用户同时并发测压_简单聊聊吞吐量(TPS)、QPS、并发数、响应时间(RT)概念...
  7. 安卓模拟器 Genymotion 安装
  8. JVM快速调优手册02:常见的垃圾收集器
  9. 关于SQL EXPRESS 2005的连接问题
  10. Android 四大组件学习之Activity七
  11. UNIX 环境高级编程之我见
  12. Excel 行列转换的最简方法
  13. 【Web】CSS(No.33)Css页面布局经典案例(三)《京东首页》
  14. 1020 月饼 (25分) 冒泡排序
  15. 父子进程终止顺序与僵死进程
  16. Tomcat启动错误-Unable to open debugger port (127.0.0.4322)一次性解决方式
  17. python绘制等值线图_使用python祏rfer绘制等值线图的方式适题。
  18. 大数据开发hive数据库常用命令汇总
  19. spring 动态数据源切换实例
  20. datagrip无法提示字段

热门文章

  1. 本地搭建gitlab服务器(Ubuntu)
  2. 游戏开发入门 一游戏开发概述
  3. 并发下php脚本执行,php命令行脚本多进程并发执行
  4. php教程数据库操作,php mysql数据库操作教程_PHP教程
  5. Linux fsync和fdatasync系统调用实现分析(Ext4文件系统)
  6. 鸿联九五26周年,追梦不止,犇赴未来
  7. Keil添加Cppcheck
  8. 最小二乘法的一阶、二阶辨识系统
  9. 数据结构-静态链表创建
  10. FLASH芯片入门资料 原装片与黑白片的区别(转贴)