数据结构作业

                                              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);
}

 

 

 
posted @ 2015-10-22 00:35  yukeyi  阅读(161)  评论(0编辑  收藏  举报