计算器(栈实现)

来源:互联网 发布:二叉树求节点双亲算法 编辑:程序博客网 时间:2024/06/10 20:32

算法:
1.先利用ARR[]存储所需要计算的表达式字符串;
opnd存储操作数的栈,optr存储运算符的栈;
arr[]存储连续的数字字符,然后转化的整型数;
2.依次读入ARR[]的每个字符(flag为标记),如果是数字字符转化后入opnd栈;
3.如果是运算符,则比较读入的字符与optr栈顶的运算符,根据事先确定的顺序决定是继续读入,是提取opnd的两个操作数计算,还是消除括号;
4.当读入’=’时,运算结束,输出opnd栈顶元素即为运算结果;

总结:对栈有进一步的理解,对结构的控制进一步掌握
漏洞:
1.由于创建optr时,事先存入了’=’所以,如果负数放在第一位则计算不对,其他漏洞没有发现
2.对析构函数的使用不对,加上析构函数会出现问题,需要进一步学习析构函数的使用

#include<iostream>#include<stdlib.h>//包含atoi()和itoa()函数using namespace std;#define MAX 50#define NULL 0typedef struct //运算符栈{    char arr[MAX];    int top;}OPTR;typedef struct //操作数栈{    int arr[MAX];    int top;}OPND;class A{public:    A();//构造函数    void load();//依次读入每个字符    void Create();    int Empty(OPTR *optr);//判空    int Empty(OPND *opnd);//判空    void Push(char ch);//运算符入栈    void Push(int num);//操作数入栈    int Pop(char *ch);//运算符出栈    int Pop(int *num);//操作数出栈    int bijiao(char ch);//比较算符优先级,确定是否计算    int jisuan(int a , int b , char ch);//计算    int get_opnd_top();//返回运算符的栈顶元素(结果数值)    int pankong();//判断运算符是否结束private:    char ARR[100] ;    OPTR *optr;    OPND *opnd;     int flag;};///////////////////////////构造函数/////////////////////////A::A(){    flag = 0;    optr = NULL;    opnd = NULL;    cout<<"输入计算的表达式:";    cin>>ARR;}///////////////////////////析构函数/////////////////////////A::~A()//{//  delete []ARR ;//  delete optr ;//  delete opnd;//}///////////////////////////依次读入每个字符////////////////void A::load(){    int  a = 0 , b = 0 ,length = strlen(ARR) ;    char arr[10] = {0} , ch ;     for (int i = 0 ; i < length; )    {           i = flag;         if (pankong()){ break;}        if (ARR[i] =='+'||ARR[i] =='-'||ARR[i] =='*'||ARR[i] =='/'||ARR[i] =='('||ARR[i] ==')'||ARR[i] =='=')//是运算符;        {            int n = bijiao(ARR[i]);//取得比较返回值            switch (n)            {            case 1:{    Push(ARR[i]);flag++;}break;//继续入栈,flag++读取下一个位置            case 0:{    Pop(&ch); ch = 0 ; flag++;}break;//')'遇到'(',把'('出栈,flag++读取下一个位置            case -1:{                                       //进行计算                            a = Pop(&a);                            b = Pop(&b);                            ch = Pop(&ch);                            Push(jisuan(b , a , ch));//计算结果入栈                    }break;            }        }        else    //是字符数        {            for (int j = 0 ; i < strlen(ARR) - 1;)            {                if (ARR[i] !='+'&&ARR[i] !='-'&&ARR[i] !='*'&&ARR[i] !='/'&&ARR[i] !='('&&ARR[i] !=')')//把字符保存在arr[]中                {                    arr[j] = ARR[i] ;                    j++;                }                else                    break;                i++;            }            flag = i ;  //标记读入位置            Push( atoi(arr) );//把arr[]字符数组,转化成int型数,入操作数栈            for (int i = 0 ;i < 10 ;i++)            {                arr[i] = 0;            }        }    }}///////////////////////////创建/////////////////////////void A::Create()//初始化运算符栈,并将'='输入进去!{    optr = new OPTR;    optr->top = 0;    optr->arr[optr->top] = '=' ;    opnd = new OPND;//初始化操作数栈!    opnd->arr[100] = 0 ;    opnd->top = -1;}///////////////////////////判断栈空/////////////////////////int A:: Empty(OPTR *optr)//判断操作数是否栈空{    if (optr->top == -1)        return 1;    else        return 0;}int A::Empty(OPND *opnd)//判断运算符是否栈空{    if (opnd->top == -1)        return 1;    else        return 0;}///////////////////////////入栈/////////////////////////void A::Push(char ch)//运算符入栈{    optr->top++;    optr->arr[optr->top] = ch;}void A::Push(int num)//操作数入栈{    opnd->top++;    opnd->arr[opnd->top] = num;}///////////////////////////出栈/////////////////////////int A::Pop(char *ch)//运算符出栈{    *ch = optr->arr[optr->top];    optr->top--;    return *ch;}int A::Pop(int *num)//操作数出栈{    *num = opnd->arr[opnd->top];    opnd->top--;    return *num;}///////////////////////////判断优先级/////////////////////////int A::bijiao(char ch){    int in_temp = 0 , out_temp = 0;    switch (ch)//栈外运算符    {    case '(':out_temp = 6;break;    case '+':    case '-':out_temp = 1;break;    case '*':    case '/':out_temp = 3;break;    case ')':out_temp = 0;break;    case '=':out_temp = -1;break;    }    switch (optr->arr[optr->top])//OPTR栈顶的运算符    {    case '(':in_temp = 0;break;    case '+':    case '-':in_temp = 2;break;    case '*':    case '/':in_temp = 4;break;    case ')':in_temp = 6;break;    case '=':in_temp = -2;break;    }    if (out_temp > in_temp){return 1;}//栈外运算符高返回1,继续入栈;    if (out_temp == in_temp){return 0;}//栈外运算符低返回0,进行消括号;    if (out_temp < in_temp){return -1;}//栈外运算符低返回-1,进行计算;}///////////////////////////计算/////////////////////////int A::jisuan(int a , int b , char ch){        switch (ch)        {        case '+':return (a + b);        case '-':return (a - b);        case '*':return (a * b);        case '/':return (a / b);        }}///////////////////////////判断是否结束('='遇到'=')//////////////////////int A::pankong(){    if (optr->arr[1] == '=')        return 1;    else        return 0;}///////////////////////////返回Opnd的栈顶元素(结果)////////////////int A::get_opnd_top(){    return opnd->arr[opnd->top];}///////////////////////////主函数/////////////////////////int main (){    A mess;//构造函数中提示输入ARR;    mess.Create();    mess.load();    cout<<mess.get_opnd_top()<<endl;    system ("pause");}

例图

0 0