计算器(栈实现)

算法:
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 0
typedef 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");
}

例图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值