zoukankan      html  css  js  c++  java
  • 数据结构作业

                                                  Basic Calculator

    一.题意描述

       题目要求解析一个含有数字,加号减号和括号的表达式,并算出其值,不能使用eval库函数。

    二.解题思路
          将整个表达式以括号分隔开,在从左到右扫描的过程中使字符依次进栈。只要遇到右括号,就将该括号中的值计算出来,将原来括号中的内容出栈,计算出的结果进栈。
          具体来讲,只要不是右括号就进栈,否则先将一个变量(括号内的值,程序中为temp2)置为零,每次弹出两个元素,若第二个为+(-),则将temp2加(减)上第一个元素,若为(,将temp2加上第一个元素,并将所得结果进栈。由于每出现一个右括号就进行一次操作,栈中根本不会出现右括号,故不会出现括号内还嵌套括号的情况。一致扫描到字符串末尾即可。
           过程中有三点值得说明:
               1.为了避免在去掉所有括号之后还要将余下的所有数相加(减)的步骤,在扫描开始前现将左括号压栈, 扫描完成后将一个右括号压栈。
               2.由于栈中既会有字符(+-()),也会有数字,故将字符采用负整数的方式存储,即(:-1  ):-2  +:-3  -:-4,这样只需使用一个int型的栈就好了。
               3.对于数字不止一位的情况,由于扫描是从高位开始,故采用“原数*10+下一位”的方法,只将最后结果压栈。
    由于整个字符串只扫描一遍,故该算法的复杂度为O(n).
    三.一个问题
          通过的程序是使用stack类来实现的,原来准备用自己写的QStack类的,但由于测试用例中有的的字符串很长,开始时需要分配的内存很大(栈的深度至少要550),在测评系统中会导致奇怪的错误。当栈的大小为520时可以通过34/37个测试用例,而只是转为使用stack类就可以通过了。
     
    下面是源代码:
     
    QStack版: 
    #include <iostream>
    using namespace std;
    
    typedef struct
    {
        int* data;
        int to;
    }QStack;//在栈中-1,-2表示括号,-3,-4表示加减号
    
    void Push(QStack* &q,int num)
    {
        q->data[q->to] = num;
        q->to++;
    }
    
    void init(QStack* &q)
    {
        q->to = 0;
        q->data = new int[600];
    }
    
    int Pop(QStack* &q)
    {
        q->to--;
        return q->data[q->to];
    }
    
    int Top(QStack* &q)
    {
        return q->data[q->to-1];
    }
    
    class Solution {
    public:
        int calculate(string s) {
            int i;
            int temp;
            int temp2;
            int temp1;
            QStack *q = new QStack;
            init(q);
            Push(q,-1);
            for(i = 0;i <= s.length();i++)
            {
                if(i == s.length())
                {
                    temp2 = 0;
                    while(1)
                    {
                        temp1 = Pop(q);
                        temp = Pop(q);
                        if(temp == -3)
                            temp2 += temp1;
                        else if(temp == -4)
                            temp2 -= temp1;
                        else
                        {
                            temp2+=temp1;
                            Push(q,temp2);
                            break;
                        }
                    }
                }
                else
                {
                    if(s[i] == ' ' || s[i] == '"')
                        continue;
                    else if(s[i] == '(')
                        Push(q,-1);
                    else if(s[i] == '+')
                        Push(q,-3);
                    else if(s[i] == '-')
                        Push(q,-4);
                    else if(s[i] == ')')
                    {
                        temp2 = 0;
                        while(1)
                        {
                            temp1 = Pop(q);
                            temp = Pop(q);
                            if(temp == -3)
                                temp2 += temp1;
                            else if(temp == -4)
                                temp2 -= temp1;
                            else
                            {
                                temp2+=temp1;
                                Push(q,temp2);
                                break;
                            }
                        }
                    }
                    else
                    {
                        if(Top(q) >= 0)
                        {
                            temp = Pop(q)*10 + s[i] - 48;
                            Push(q,temp);
                        }
                        else
                            Push(q,s[i]-48);
                    }
                }
            }
            return Pop(q);
        }
    };
    
    int main()
    {
        char temp[10000];
        Solution calc;
        cin >> temp;
        string s(temp);
        cout << calc.calculate(s);
    }

    内置stack版

    #include <iostream>
    #include <stack>//在栈中-1,-2表示括号,-3,-4表示加减号
    using namespace std;
    
    class Solution {
    public:
        int calculate(string s) {
            int i;
            int temp;//弹出的第二个数
            int temp1;//弹出的第一个数        
            int temp2;
            stack<int> q;
            q.push(-1);
            for(i = 0;i <= s.length();i++)
            {
                //最后加一个右括号
                if(i == s.length())
                {
                    temp2 = 0;
                    while(1)
                    {
                        temp1 = q.top();
                        q.pop();
                        temp = q.top();
                        q.pop();
                        if(temp == -3)
                            temp2 += temp1;
                        else if(temp == -4)
                            temp2 -= temp1;
                        else
                        {
                            temp2+=temp1;
                            q.push(temp2);
                            break;
                        }
                    }
                }
                else
                {
                    if(s[i] == ' ' || s[i] == '"')
                        continue;
                    else if(s[i] == '(')
                        q.push(-1);
                    else if(s[i] == '+')
                        q.push(-3);
                    else if(s[i] == '-')
                        q.push(-4);
                    else if(s[i] == ')')
                    {
                        temp2 = 0;
                        while(1)
                        {
                            temp1 = q.top();
                            q.pop();
                            temp = q.top();
                            q.pop();
                            if(temp == -3)
                                temp2 += temp1;
                            else if(temp == -4)
                                temp2 -= temp1;
                            else
                            {
                                temp2+=temp1;
                                q.push(temp2);
                                break;
                            }
                        }
                    }
                    else//输入的是数字
                    {
                        if(q.top() >= 0)
                        {
                            temp = q.top()*10 + s[i] - 48;
                            q.pop();
                            q.push(temp);
                        }
                        else
                            q.push(s[i]-48);
                    }
                }
            }
            return q.top();
        }
    };
    
    int main()
    {
        char temp[10000];
        Solution calc;
        cin >> temp;
        string s(temp);
        cout << calc.calculate(s);
    }
     
  • 相关阅读:
    2017.04.05-2017.07.14封闭开发总结
    Android读取Manifest文件下Application等节点下的metadata自定义数据
    MyEclipse Hibernate Reverse Engineering 找不到项目错误
    web服务器决定支持多少人同时在线的因素
    配置servers时,错误:Setting property 'source' to 'org.eclipse.jst.jee.server:hczm' did not find a matching property
    查看端口被占用
    高德开发 android 出现 key 鉴权失败
    Android EventBus
    javascript 中的数据驱动页面模式
    读书笔记之
  • 原文地址:https://www.cnblogs.com/yukeyi14/p/4899664.html
Copyright © 2011-2022 走看看