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

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 html5 qrcode 扫描器
  • ¥15 爬取网页信息并保存需要完整代码
  • ¥15 一分十不等功分器阻设计问题,请问这个56Ω怎么得到的
  • ¥15 (标签-matlab)
  • ¥100 求看看这个数学建模,有偿
  • ¥15 深度学习目标检测现在框架加注意力的创新可以投几区?
  • ¥15 PdfiumViewer pdf转图片
  • ¥15 利用Java连接API接口总是出问题
  • ¥15 请教一个关于镜头标定,棋盘格格子大小的问题(畸变测试)
  • ¥15 安装GroudingDINO RuntimeError: Error compiling objects for extension