取名字好难-_- 2022-05-06 16:51 采纳率: 58.3%
浏览 520
已结题

C++;用栈实现简易计算器

本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。如上图所示,计算器由两个堆栈组成,一个堆栈 S1存放数字,另一个堆栈 S2存放运算符。计算器的最下方有一个等号键,每次按下这个键,计算器就执行以下操作:
从 S1中弹出两个数字,顺序为 n1和 n2;
从 S2中弹出一个运算符 op;
执行计算 n2opn1;
将得到的结果压回 S1。
直到两个堆栈都为空时,计算结束,最后的结果将显示在屏幕上。

输入格式:
输入首先在第一行给出正整数 N(1<N≤10 3),为 S1中数字的个数。
第二行给出 N 个绝对值不超过 100 的整数;第三行给出 N−1 个运算符 —— 这里仅考虑 +、-、*、/ 这四种运算。一行中的数字和符号都以空格分隔。

输出格式:
将输入的数字和运算符按给定顺序分别压入堆栈 S1 和 S2将执行计算的最后结果输出。注意所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过 109 。
如果执行除法时出现分母为零的非法操作,则在一行中输出:ERROR: X/0,其中 X 是当时的分子。然后结束程序。
输入样例 1:
5
40 5 8 3 2
/ * - +
输出样例 1:
2
输入样例 2:
5
2 5 8 4 4

  • / - +
    输出样例 2:
    ERROR: 5/0
#include<iostream>
using namespace std;

typedef struct StackNode
{
    int data;
    struct StackNode *next;
}StackNode,*LinkStack;

void InitStack(LinkStack S)
{
    S=NULL;
}
void Push(LinkStack &S, int e) {
    LinkStack p=new StackNode;
    p->data =e;
    p->next =S;
    S=p;

}
int Pop(LinkStack &S) {
    int e;
    LinkStack p=new StackNode;
    e=S->data;
    p=S;
    S=p->next;
    delete p;
    return e;
}
void yunsuan(LinkStack S1,LinkStack S2)
{
    int n1,n2,ans;
    char op;
    n1=Pop(S1);
    printf("n1=%d\n",n1);
    n2=Pop(S1);
    printf("n2=%d\n",n2);
    op=Pop(S2)+'0';
    printf("op=%c\n",op);
    switch(op)
    {
        case '+':
            ans=n2+n1;
            Push(S1,ans);
            break;
        case '-':
            ans=n2-n1;
            Push(S1,ans);
            break;
        case '*':
            ans=n2*n1;
            Push(S1,ans);
            break;
        case '/':
            ans=n2/n1;
            Push(S1,ans);
            break;         
    }
    printf("ans=%d",ans);
    if(Pop(S2)==NULL)
    {
        cout<<Pop(S1);
    }
}
int main()
{
    LinkStack S1,S2;
    InitStack(S1);
    InitStack(S2);
    int n,a;
    cin>>n;
    int i,j,integer;
    for(i=0;i<n;i++)
    {
        cin>>integer;
        Push(S1,integer);
    }
    char ch,b;
    for(i=0;i<n-1;i++)
    {
        cin>>ch;
        Push(S2,ch-'0');
    }
    for(j=0;j<n-1;j++)
    {
        yunsuan(S1,S2);
    }
}

img


运算始终报错,应该是指针指向空了,但是这是为什么啊?

  • 写回答

2条回答 默认 最新

  • 关注

    (1)pop函数中,
    p=S;
    S=p->next;
    delete p;
    已经更改了p的值,所以delete p的时候,实际上删除的是S,在pop函数中,p不需要new的。

    
    
    int Pop(LinkStack& S) {
        int e;
        //LinkStack p = new StackNode;
        e = S->data; //在使用pop函数前,必须保证S非空,否则这里会崩
        S = S->next;
        //p = S;
        //S = p->next;
        //delete p;
        return e;
    }
    
    

    (2)InitStack函数中,参数是指针,函数操作也是指针,InitStack函数没有任何作用,把参数改成引用

    void InitStack(LinkStack &S)
    {
        S = NULL;
    }
    
    

    (3)yunsuan函数的参数,也需要改成引用,最后的if(pop(s2)==NULL)这里删掉

    void yunsuan(LinkStack &S1, LinkStack &S2)
    
    

    (4)你的代码中,除法运算中,没有对分母是0的情况的判断。

    完整代码如下:

    #include<iostream>
    using namespace std;
    
    typedef struct StackNode
    {
        int data;
        struct StackNode* next;
    }StackNode, * LinkStack;
    
    void InitStack(LinkStack &S)
    {
        S = NULL;
    }
    void Push(LinkStack& S, int e) {
        LinkStack p = new StackNode;
        p->data = e;
        p->next = S;
        S = p;
    
    }
    int Pop(LinkStack& S) {
        int e;
        //LinkStack p = new StackNode;
        e = S->data; //这里必须保证S非0,所以最好再加一个empty函数来判断S非空
        S = S->next;
        //p = S;
        //S = p->next;
        //delete p;
        return e;
    }
    int yunsuan(LinkStack &S1, LinkStack &S2)
    {
        int n1, n2, ans;
        char op;
        n1 = Pop(S1);
        printf("n1=%d\n", n1);
        n2 = Pop(S1);
        printf("n2=%d\n", n2);
        op = Pop(S2);
        printf("op=%c\n", op);
        switch (op)
        {
        case '+':
            ans = n2 + n1;
            Push(S1, ans);
            break;
        case '-':
            ans = n2 - n1;
            Push(S1, ans);
            break;
        case '*':
            ans = n2 * n1;
            Push(S1, ans);
            break;
        case '/':
            if (n1 == 0)
            {
                printf("ERROR:%d/0\n", n2);
                return 0;
            }
            ans = n2 / n1;
            Push(S1, ans);
            break;
        }
        printf("ans=%d\n", ans);
        return 1;
        /*if (Pop(S2) == NULL)
        {
            cout << Pop(S1);
        }*/
    }
    int main()
    {
        LinkStack S1, S2;
        InitStack(S1);
        InitStack(S2);
        int n, a;
        cin >> n;
        int i, j, integer;
        for (i = 0; i < n; i++)
        {
            cin >> integer;
            Push(S1, integer);
        }
        cin.clear();
        cin.sync();
        char ch, b;
        
        for (i = 0; i < n - 1; i++)
        {
            cin >> ch ;
            
            Push(S2, ch );
        }
        for (j = 0; j < n - 1; j++)
        {
            int res = yunsuan(S1, S2);
            if (res == 0)
                break;
        }
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月14日
  • 已采纳回答 5月6日
  • 创建了问题 5月6日

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么