计算1+2*3=,这个程序还是比较绕的,先将程序简化,只做+-*/和=五个运算符的关系。首先,假定这五个运算符中,=号的优先级最低,其次是+-,最高为*/。接着约定,"1+2*3=",为字符串。

第一步,将=号入栈,作为栈底。然后,再依次进行后续的比较。
约定:栈顶符号<字符串符号,则字符串符号入栈。栈顶符号>=字符串符号的,则进行计算!

分步来说,首先取字符1,为数字,则入数据栈,接着取字符+,由于初始化时,栈中只有一个=号,也即为栈顶,两者比较,根据约定,+号入符号栈,接着为2,入数据栈。接着*号,由于栈顶小于字符串的优先级,因为此时的栈顶是+号,所以*号入符号栈,再接着3,入数据栈,最后是等号。

直到等号时,字符串的符号才小于栈顶,根据约定要计算。

计算规则
(1)符号栈,出(一个)栈顶符号
(2)数据栈取出两数据,配合栈顶符号进行计算。

根据计算规则,取出*号,然后,再取出3和2,得到6,并将之存入到数据栈中。
再拿栈顶与字符比较,此时,由于*号已经出栈,剩下+号,再比较,还是>字符串中的=号,所以再计算。得到1+6=7,将7入数据栈。此时,栈顶就是=号,然后再拿=号和=号进行比较,则循环判定结束,最后返回数据栈中的元素就是最后的结果!

/*-------------完整程序@映雪---2016/3/16-------------*/
#include <iostream>
using namespace std;
#define MAXSIZE 50
typedef struct stack
{
int data[MAXSIZE];
int top;
}Stack;
void init(Stack &s)
{
s.top=-;
}
void push(Stack &s,int e) /*入栈*/
{ s.data[++s.top]=e; } int pop(Stack &s) /*出栈*/
{ return s.data[s.top--];} int peek(Stack &s) /*取栈顶数据*/
{ return s.data[s.top];} int check(char c) //检查字符是否为运算符
{
switch(c)
{
case'+':
case'-':
case'*':
case'/':
case'=':
return ;
break;
default:
return ;
break;
}
} int compare(char x,char c) //判断两个运算符的优先级
// oper1大于oper2的优先级,返回1
//oper1小于oper2的优先级,返回-1
//oper1等于oper2的优先级,返回0
{
int pri;
switch(c) //判断运算符优先级
{
case '+':
case '-':
if(x=='('||x=='=') //为左括号或表达式开始符号
pri=-; //返回小于
else
pri=;
break;
case '*':
case '/':
if(x=='*'||x=='/'||x==')')
pri=;
else
pri=-;
break;
case '=' :
if(x=='(')
{
cout<<"括号不匹配!\n";
exit();
}else if(x=='=')
pri=;
else
pri=;
break;
}
return pri;
}
int Calc(int a,int oper,int b) //计算两个操作数的结果
{
switch(oper)
{
case'+':return a+b;
case'-':return a-b;
case'*':return a*b;
case'/':
if(b!=)
return a/b;
else
{
cout<<"除0溢出!\n";
exit();
}
}
}
int CalcExp(char exp[]) //表达式计算函数
{
Stack A,B;
int i=,flag=;
int a,b,t;/*a,b为数据栈中取出的数据,t为a与b的计算结果*/
int c,q,x,oper; init(A); //初始化两个栈
init(B); q=;
x='=';
push(B,x); //首先将等号(=)进入操作符栈
c=exp[i++];/*取字符串的第一个字符*/ while(c!='=' || x!='=')/*判定最终完成计算的条件*/
{
if(check(c)) //若输入的是运算符
{
if(flag) /*有未入栈的操作数,则操作数入栈*/
{
push(A,q);//将操作数入栈
q=;
flag=;
}
switch(compare(x,c)) //判断运算符的优先级
{
case -:
push(B,c);//运算符进栈
c=exp[i++];
break;
case :
c=pop(B); //运算符出栈 (抛弃)
c=exp[i++];
break;
case :
oper=pop(B); //运算符出栈
b=pop(A);//两个操作数出栈
a=pop(A);
t=Calc(a,oper,b);
push(A,t);//运算结果入栈
break;
}
}
else if(c>=''&&c<='') //若输入字符在0~9之间
{
c-='';
q=q*+c;/* 计算数字的总数 */
c=exp[i++];
flag=;
}
else
{
cout<<"输入错误!\n";
exit();
}
x=peek(B);//获取栈顶的运算符
} q=pop(A);/*出栈最终结果*/
return q;
} int main()
{
char exp[];
cout<<"请输入要计算的表达式(以=结束):";
cin>>exp;
cout<<exp<<CalcExp(exp);
return ;
}

6.<1>四则运算的研究[栈]的更多相关文章

  1. salesforce零基础学习(七十六)顺序栈的实现以及应用

    数据结构中,针对线性表包含两种结构,一种是顺序线性表,一种是链表.顺序线性表适用于查询,时间复杂度为O(1),增删的时间复杂度为O(n).链表适用于增删,时间复杂度为O(1),查询的时间复杂度为O(n ...

  2. LeetCode OJ 题解

    博客搬至blog.csgrandeur.com,cnblogs不再更新. 新的题解会更新在新博客:http://blog.csgrandeur.com/2014/01/15/LeetCode-OJ-S ...

  3. esp和ebp详解

    最近在研究栈帧的结构,但总是有点乱,所以写了一个小程序来看看esp和ebp在栈帧中的作用.这个程序如下: 这个程序很简单,就是求两个数的值,然后输出即可.所以首先把它用gcc编译链接成a.out,进入 ...

  4. (C/C++学习笔记) 十. 函数

    十. 函数 ● 基本概念 函数 函数定义 function definition: return_type function_name ( parameter list ) { Body of fun ...

  5. 深入浅出数据结构C语言版(8)——后缀表达式、栈与四则运算计算器

    在深入浅出数据结构(7)的末尾,我们提到了栈可以用于实现计算器,并且我们给出了存储表达式的数据结构(结构体及该结构体组成的数组),如下: //SIZE用于多个场合,如栈的大小.表达式数组的大小 #de ...

  6. C++做四则运算的MFC计算器(二)栈转换和计算后缀表达式

    上篇写了MFC界面搭建,这篇就写实现计算.涉及到数据结构,对新手很不友好. 虽然是MFC程序,但是能灵活地分离后台代码,自行构建控制台程序. 上篇文章链接:C++做四则运算的MFC计算器(一)MFC界 ...

  7. 三道题(关于虚表指针位置/合成64位ID/利用栈实现四则运算)

    第一题 C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的.请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面.  第二题 在游戏中所有物品的实例 ...

  8. java学习之—使用栈实现字符串数字四则运算

    /** * 使用栈存储后缀表达式 * Create by Administrator * 2018/6/13 0013 * 下午 2:25 **/ public class StackX { priv ...

  9. C语言之四则运算表达式求值(链栈)—支持浮点型数据,负数, 整型数据运算

     运算符间的优先级关系: 链栈结构体定义: 数据域使用字符串长度为20的字符数组(故需要注意判断读取的字符串是运算符还是数值) 可支持浮点型数据,负数, 整型数据的运算 float EvaluateE ...

随机推荐

  1. mysql 导入csv 转义

    TERMINATED :分隔符 ESCAPED :转义用什么标示,‘’ 不设置转义符 LOAD DATA LOCAL INFILE '/home/tmp/1999/holder.csv'  INTO ...

  2. Eletron 打开文件夹,截图

    1.shell.openItem(fullPath) var fullpath = path.join(processPath)+Math.random()+".png"; she ...

  3. MySql的基本架构演变

    [MySql的基本架构演变] 没有并发的增长,也就没有必要做高可扩展性的架构. Scale-up :  纵向扩展,通过替换为更好的机器和资源来实现伸缩,提升服务能力 Scale-out : 横向扩展, ...

  4. Windows下搭建appium(Android版)

    1.安装node.js 说明:安装node.js是为了可以使用它的npm,可以用npm install很方便的安装它包含的包,appium server使用node.js编写的 下载地址:https: ...

  5. Android 最火开发框架 xUtils

    xUtils简介 xUtils3 api变化较多, 已转至 https://github.com/wyouflf/xUtils3 xUtils 2.x对Android 6.0兼容不是很好, 请尽快升级 ...

  6. toString方法的用法

    public class JLDtoS {   public static void main(String[]args)   {    long a=123;    Long aa=new Long ...

  7. keras—神经网络CNN—CIFAR_10图像识别

    1 from keras.datasets import cifar10 from keras.utils import np_utils import matplotlib.pyplot as pl ...

  8. 38. Count and Say (String; DP)

    The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ...

  9. SVN服务器的安装和使用

    ------------------siwuxie095                                 SVN 服务器的安装         1.SVN 服务器,选择 VisualS ...

  10. 关于"undefined reference"错误

    这个错误换句话说: 链接的时候找不到实现的文件(谨记从这个入手!). 可能导致的原因有: 1. 没有链接库文件,包括静态库或动态库. 2. 链接文件的顺序问题,先后依赖问题,把被依赖的放后面. 3. ...