解决后缀表示法方程c ++

时间:2015-04-27 02:53:38

标签: c++

对于我的输出,我收到无效的分配错误。以下是评论中编辑过的代码。我没有做的唯一编辑是使用断言宏更改“顶部”函数,这是因为它未定义到我的编译器。非常感谢你们所有的帮助,我看到了光明!我只需要清除无效的分配错误,当我在调试期间打破它时,编译器指向push函数。

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;


void solvePostfix(string postfixStr);

class OperandStack
{
private:
    double * s;  //pointer to 1D dynamic array for storing stack elements
    int capacity,  //stack capacity
        t;  //index of the top element on stack
    void growStack(int newCapacity);  //increases the stack if it is full
                        //must be called from the push function if the stack is full

 public:
    OperandStack(){ capacity = 1; s = NULL; t = -1; };
     OperandStack(int capacity);
     ~OperandStack();
     int size() const;  //return the number of elements in the stack
     bool isFull() const; 
     bool isEmpty() const;
     double top() const;  //returns the element at the top of the stack
                 //without removing it from the stack
     void push(double x);
     void pop();

};

OperandStack :: OperandStack(int capacity)
{ 
    capacity = capacity;
    s = new double [capacity];
    t = -1;
}

OperandStack :: ~OperandStack()
{
    while(this->isEmpty() == false)
    {
        for(int i = 0; i < this->size(); i++)
        {
            this->pop();     
        }
    }
    delete []s;
}

int OperandStack :: size () const
{

    return t+1;
}

bool OperandStack :: isFull() const
{
    return this->size() == capacity;

}

bool OperandStack :: isEmpty() const
{
    if(t == -1) return true;
    else return false;
}

double OperandStack :: top() const
{
    if(this->isEmpty() == false) return s[t];

}


void OperandStack :: push( double x) 
{
    if(this->isFull())
    {
        this->growStack(capacity+(capacity/2));
    }

    else if(this->isEmpty())
    { 
        t = 0; 
        s[t] = x;
    }
    else
    {
        ++t;
        s[t] = x;
    }
}

void OperandStack :: pop()
{
    s[t] = NULL;
    t--;
}

void OperandStack :: growStack(int newCapacity)
{
    double *copyStack = new double[newCapacity];
    for(int i = 0; i < capacity; i++) //Deep copy 
    {
        copyStack[i] = s[i];
    }

    if(s != NULL) delete[] s;
    s = copyStack;
    capacity = newCapacity;
}


void solvePostfix(string postfixStr)
{   
    int i = 0; //The index of a number in the string
    double x, y; //Represent the numbers from the string
    char symbol; //The operator from the string
    OperandStack tempStack;

    while(i < postfixStr.length())
    {
        if(postfixStr[i] >= '0' && postfixStr[i] <= '9')
        {
            tempStack.push(postfixStr[i]-'0');
        }
        else if(postfixStr[i] == '+' || postfixStr[i] == '-'  
            || postfixStr[i] == '*' || postfixStr[i] == '/')
        {
            y = tempStack.top();
            tempStack.pop();
            x = tempStack.top();
            tempStack.pop();
            switch(postfixStr[i])
            {
                case '+': tempStack.push(x + y); break;
                case '-': tempStack.push(x - y); break;
                case '/': tempStack.push(x / y); break;
                case '*': tempStack.push(x * y); break;
            }
        }
        else
        {
            cout << "error- malformed expression.";
        }
        i++;
    }
    cout << "Result: " << tempStack.top() << endl;

}




int main()
{
    OperandStack myStack(8);
    string inputPostfixStr;

    cout << "Enter a postfix expression: ";
    std::getline(cin, inputPostfixStr);

    solvePostfix(inputPostfixStr);

    system("pause");
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我看到的问题:

  1. 在默认构造函数中,您正在将capacity初始化为0。然后,您使用以下语句来增加大小。

    this->growStack(capacity+(capacity/2));
    

    由于capacity已初始化为0,因此您的规模确实不会增加。

    对此问题的一个简单修复是从初始容量1开始,或将调用中的逻辑更改为growStack

    这是导致您访问不应该访问的内存的主要问题。结果就是未定义的行为。

  2. 您有几个函数在所有路径中都没有return语句。

    bool OperandStack :: isFull() const
    {
       if(this->size() == capacity) return true;
       else if(this->size() != capacity) return false;
    }
    

    可以使用以下方法修复:

    bool OperandStack :: isFull() const
    {
       return (this->size() == capacity);
    }
    

    double OperandStack :: top() const
    {
       if(this->isEmpty() == false) return s[t];
    }
    

    可以使用以下方法修复:

    double OperandStack :: top() const
    {
       assert(this->isEmpty() == false);
       return s[t];
    }
    
  3. 您在push的调用中使用了错误的参数。

     tempStack.push(postfixStr[i]);
    

    应该是:

     tempStack.push(postfixStr[i]-'0');
    
  4. 以字符串形式读取表达式的代码不正确。

     cin >> inputPostfixStr;
    

    在遇到空格时会停止读取输入。当您的输入为“1 1 +”时,执行该行后,inputPostfixStr的值将为"1"。将该行更改为:

    std::getline(cin, inputPostfixStr);
    
  5. OperandStack(int capacity)的实施不对。

    OperandStack :: OperandStack(int capacity)
    { 
        capacity = capacity;
        s = new double [capacity];
        t = -1;
    }
    

    你有两个名为capacity的变量 - 函数的参数和类的成员变量。但是,在函数内部,成员函数会隐藏成员变量。因此,成员变量未初始化。如果你最终使用这个构造函数,你将遇到未定义的行为。

    更改行

        capacity = capacity;
    

        this->capacity = capacity;
    
  6. if-else中的push逻辑不正确。

    void OperandStack :: push( double x) 
    {
        if(this->isFull())
        {
            // this->growStack(capacity+(capacity/2));
            // This will be a problem if the initial size is zero or 1
            // 1/2 == 0. Change it appropriately.
        }
    
        // Using the `else` here is a problem.
        // If you do, when the stack is full, the stack is grown but 
        // nothing is added to the stack.
        // else if(this->isEmpty())
    
        if(this->isEmpty())
        { 
            t = 0; 
            s[t] = x;
        }
        else
        {
            ++t;
            s[t] = x;
        }
    }
    

答案 1 :(得分:0)

错误来自您将数据放入堆栈的方式

        if(postfixStr[i] >= '0' && postfixStr[i] <= '9')
        {
            tempStack.push(postfixStr[i]);
        }

编译器应该给你一个警告。 postfixStr[i]char,将其隐式转换为double是没有意义的。这就是为什么你得到完全错误的x和y值(以及最终结果不好)的原因。