#include <cstdio>

 #include <cstdlib>

 #include <cmath>

 #include <stack>

 #include <cstring>

 using namespace std;

 char Precede(char a, char b) { //判断运算符优先级

     int i, j;

     char Table[][] = {

         {' ','+','-','*','/','(',')','='},

         {'+','>','>','<','<','<','>','>'},

         {'-','>','>','<','<','<','>','>'},

         {'*','>','>','>','>','<','>','>'},

         {'/','>','>','>','>','<','>','>'},

         {'(','<','<','<','<','<','=',' '},

         {')','>','>','>','>',' ','>','>'},

         {'=','<','<','<','<','<',' ','='}

     };  //优先级表格

     for(i=; i<; i++)

         if(Table[][i]==a)  //寻找运算符a

             break;

     for(j=; j<; j++) //寻找运算符b

         if(Table[j][]==b)

             break;

     return Table[j][i];

 }

 bool Calcu_temp(double a, char theta, double b, double &r) { //计算二元表达式的值

     if(theta=='+')

         r = a + b;

     else if(theta=='-')

         r = a - b;

     else if(theta=='*')

         r = a * b;

     else {

         if(fabs(b-0.0)<1e-)  //如果除数为0,返回错误信息

             return false;

         else

             r = a / b;

     }

     return true;

 }

 bool IsOper(char ch) { //判断字符ch是否为运算符

     char ptr[] = {'+', '-', '*', '/', '(', ')', '='};

     int i;

     for(i=; i<; i++) {

         if(ch==ptr[i])

             return true;

     }

     return false;

 }

 bool Calculate(char s[], double &result) { //计算表达式的结果

     char theta;

     int i = , j, point = ;

     double a, b, r, num = ;

     stack<double> num_stack;  //数字栈

     stack<char> oper_stack;  //运算符栈

     oper_stack.push('=');

     while(s[i]!='=' || oper_stack.top()!='=') { //对表达式a进行计算

         if((s[i]>='' && s[i]<='') || s[i]=='.') { //字符是数字或者小数点

             num = ;  //初始化数字为0

             point = ;  //point用来标记是否出现小数点以及当前处于小数点后第x位,point==10^x

             if(s[i]=='.')

                 point = ;

             else

                 num = s[i] - ;

             j = i + ;

             while(!IsOper(s[j])) { //继续往后查找并记录该数字,直到该数字结束遇到运算符为止

                 if(s[j]=='.') {

                     point = ;

                     j++;

                     continue;

                 }

                 if(!point)  //整数部分

                     num = num *  + ( s[j] -  );

                 else {

                     num = num + 1.0 * ( s[j] -  ) / point;  //小数部分

                     point *= ;  //小数位数后移一位

                 }

                 j++;

             }

             i = j;

             num_stack.push(num);  //将该数字压入栈中

         }

         else if(IsOper(s[i])) { //字符是运算符

             switch(Precede(s[i],oper_stack.top())) { //该运算符和栈顶运算符进行优先级比较并做相关处理

             case '<':

                 oper_stack.push(s[i++]);

                 break;

             case '=':

                 oper_stack.pop();

                 i++;

                 break;

             case '>':

                 theta = oper_stack.top();  //从栈中弹出一个运算符进行计算

                 oper_stack.pop();

                 b = num_stack.top();  //弹出两个数字,注意顺序,先弹出的数是第二个操作数

                 num_stack.pop();

                 a = num_stack.top();

                 num_stack.pop();

                 if ( Calcu_temp(a, theta, b, r) )  //计算并判断是否有除数等于0的情况

                     num_stack.push(r);  //若正常,则将结果压入栈中

                 else

                     return false;  //出现除数为0的情况,返回错误信息

                 break;

             }

         }

     }

     result = num_stack.top();  //最后数字栈中的数即为表达式的最终结果

     return true;

 }

 bool Check(char s[]) { //检查表达式括号是否匹配

     int flag=, i;

     for(i=; s[i]!=; i++) {

         if(s[i]=='(')

             flag++;

         if(s[i]==')')

             flag--;

     }

     if(flag)

         return false;

     else

         return true;

 }

 int main() {

 //    freopen("in.txt", "r", stdin);

     int i, j;

     char s1[], s2[];

     double result;
printf("\t\t表达式求值(栈)\n");
printf("******************************************************************\n");
printf("请输入表达式,等号不用输入:\n"); while(gets(s1)!=NULL) { //输入表达式 if(strlen(s1)== && s1[]=='') break; for(i=,j=; s1[i]!=; i++) { //将表达式转换为规格化的表达式,并在末尾加上“=”,保存在s2中 if(s1[i]==' ') continue; s2[j++] = s1[i]; } s2[j++] = '='; s2[j] = '\0'; if(Check(s2)) { //检查括号是否匹配 if(Calculate(s2, result)) //计算并检查表达式中是否出现除数为0的情况 printf("%lf\n",result); else printf("除数不能为0\n"); } else printf("括号不匹配\n"); } return ; }

表达式求值 (栈) 用C++实现的更多相关文章

  1. 第四届河南省ACM 表达式求值 栈

    表达式求值 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 7 [提交][状态][讨论版] 题目描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简 ...

  2. Python解析 算数表达式求值 栈的使用

    使用Python实现一种算数表达式求值的算法,模拟这种使用栈的方式,这是由E.W.Dijkstra在20世纪60年代发明的一种非常简单的算法.代码模拟仅仅表现一种编程思想,代码的逻辑并不完全: if ...

  3. 2015 UESTC 数据结构专题N题 秋实大哥搞算数 表达式求值/栈

    秋实大哥搞算数 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1074 Des ...

  4. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  5. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  6. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  7. 【NYOJ-35】表达式求值——简单栈练习

    表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...

  8. 表达式求值(栈方法/C++语言描述)(二)

    上篇中完成了对表达式求值的整体过程,接下来看看如何处理不同类型的token. 对运算数的处理比较简单,它直接调用函数strtod(),将字符串中的运算数转换为浮点类型并将它压入运算数栈中: void ...

  9. Matrix Chain Multiplication(表达式求值用栈操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082 Matrix Chain Multiplication Time Limit: 2000/100 ...

随机推荐

  1. vim 支持gb2312

    vi  /etc/vimrc 中添加如下,并保存. set termencoding=encodingset fileencodings=utf-8,gbk,ucs-bom,cp936set shif ...

  2. CentOS安装rar、unrar解压缩软件的方法

    闲话不说,centos上如何安装rar.unrar在线解压缩软件呢?如果您的centos是32位的,执行如下命令: wget http://www.rarsoft.com/rar/rarlinux-3 ...

  3. 多项式求和 AC 杭电

    多项式求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  4. laravel框架——表单验证

    创建路由 Route::get('test','VerController@index'); Route::post('tosubmit','VerController@tosubmit'); 在控制 ...

  5. DC-DC转换器原理与应用

    DC/DC转换器为转变输入电压后,有效输出固定电压的电压转换器.DC/DC转换器分为三类:升压型DC/DC转换器.降压型DC/DC转换器以及升降压型DC/DC转换器.根据需求可采用三类控制.PWM控制 ...

  6. DC DC降壓變換器ic 工作原理

    目前DC/DC轉化器大致可分為:升壓型dc dc變化器.降壓型dc dc變化器及可升壓又可降壓dc dc變換器.我們今天主要提一下降壓型dc dc變換器的原理: 見下圖降壓變換器原理圖如圖1所示, 當 ...

  7. Win7 下用 VS2015 编译最新 openssl(1.0.2j)包含32、64位debug和release版本的dll、lib(8个版本)

    Win7 64位系统下通过VS2015编译好的最新的OpenSSL(1.0.2j)所有八个版本的链接库, 包含以下八个版本: 1.32位.debug版LIB: 2.32位.release版LIB: 3 ...

  8. Delphi应用程序的调试(十)调试器选项(在IDE中不要使用异常)

    可在两个级别上设置调试选项:工程级和环境级.在前面的讲解中讲解了工程级调试选项,通过主菜单[Project | Options…]打开如下对话框: 可在Debugger Options对话框中设置全局 ...

  9. HDOJ 2131 Probability

    Problem Description Mickey is interested in probability recently. One day , he played a game which i ...

  10. 关于echo `git branch | grep \*`

    本来想返回一个git当前的分支.但会将这个文件夹下的所有目录与分支一起输出. 原因是  echo `git branch | grep \*`  等价于   echo * master  , 而  e ...