用于评估导致Segfault的后缀的功能

时间:2017-10-14 21:34:57

标签: c++ postfix

我对我的节目提出了一个小问题。所以,我有一个函数来计算后缀表达式并返回计算的整数或浮点数。以下是涉及的以下功能:

#include <iostream>
#include <sstream>
#include <cstring>
#include <stack>
#include <limits>

float postfixUtility::evaluatePostfix(string pexp)
{
stack<int> S;
int pexpLength = pexp.length();
cout << pexpLength << endl;
for (int i = 0; i < pexpLength; i++)
{
    if(pexp[i] == ' ' || pexp[i] == ',')
    { 
        continue;
    }     
    else if(isOperator(pexp[i]))
    { 
        int operand2 = S.top(); S.pop();
        int operand1 = S.top(); S.pop();
        int result = isOperate(pexp[i], operand1, operand2); 
        S.push(result);
    }
    else if(isDigit(pexp[i]))
    {   
        int operand = 0; 
        while(i<pexp.length() && isDigit(pexp[i]))
        {
            operand = (operand*10) + (pexp[i] - '0'); 
            i++;
        } 
        i--;
        S.push(operand);
    }
} 
return S.top();
}

bool postfixUtility::isDigit(char C) 
{
if(C >= '0' && C <= '9') 
{ 
    return true;
}
return false;
}

bool postfixUtility::isOperator(char C)
{
if(C == '+' || C == '-' || C == '*' || C == '/')
{
    return true;
}
return false;
}

int postfixUtility::isOperate(char operation, int operand1, int operand2)
{
if(operation == '+')
{   
    return operand1+operand2;
}
if(operation == '-')
{
     return operand1-operand2;
}
if(operation == '*')
{
     return operand1*operand2;
}
if(operation == '/')
{   
    return operand1/operand2;
} 
}

这些函数一起解决输入的后缀表达式。输入的表达式不为空,实际上保存了后缀表达式。但是,每次运行代码时,都会导致段错误。实际上我感到非常困惑,因为在我看来我的代码应该可行。

谢谢!

编辑#1:所以,我的功能的原始输入是:&#34;(4 + 3 * 12)/(12 + 3/2 + 46/4)&#34;

然后,我通过另一个函数将其转换为postfix。这就是这个功能:

int postfixUtility::priority(char a) 
{
int temp;
if (a == '^')
    temp = 1;
else  if (a == '*' || a == '/')
    temp = 2;
else  if (a == '+' || a == '-')
    temp = 3;
return temp;
}

string postfixUtility::getPostfix(string nexp)
{

stack<char> operator_stack;

stringstream output;

for (unsigned i = 0; i < nexp.length(); i++) {
    if (nexp[i] == '+' || nexp[i] == '-' || nexp[i] == '*' || nexp[i] == '/' || nexp[i] == '^') {
        while (!operator_stack.empty() && priority(operator_stack.top()) <= priority(nexp[i])) {
            output << operator_stack.top();
            operator_stack.pop();
        }
        operator_stack.push(nexp[i]);
    } else if (nexp[i] == '(') {
        operator_stack.push(nexp[i]);
    } else if (nexp[i] == ')') {
        while (operator_stack.top() != '(') {
            output << operator_stack.top();
            operator_stack.pop();
        }
        operator_stack.pop();
    } else {
        output << nexp[i];
    }
}

while (!operator_stack.empty()) {
    output << operator_stack.top();
    operator_stack.pop();
}

//cin.ignore(numeric_limits<streamsize>::max(), '\n');
return output.str();
}

将其转换为:&#34; 43 12 * + 12 3 2 / + 46 4 / + /&#34;,是错的?这就是我遇到段错误的原因吗?

编辑#2:所以,我在我的代码中注释掉了2行,而且我不再遇到段错误。

float postfixUtility::evaluatePostfix(string pexp)
{
stack<int> S;
int pexpLength = pexp.length();
for (int i = 0; i < pexpLength; i++)
{
    if(pexp[i] == ' ' || pexp[i] == ',')
    { 
        continue;
    }     
    else if(isOperator(pexp[i]))
    { 
        float operand2 = S.top(); 
        //S.pop();
        float operand1 = S.top(); 
        //S.pop();
        float result = isOperate(pexp[i], operand1, operand2); 
        S.push(result);
    }
    else if(isDigit(pexp[i]))
    {   
        int operand = 0; 
        while(i<pexp.length() && isDigit(pexp[i]))
        {
            operand = (operand*10) + (pexp[i] - '0'); 
            i++;
        } 
        i--;
        S.push(operand);
    }
} 
return S.top();
}

然而,答案应该是1.6,但我得到1.为什么会发生这种情况的原因?

编辑#3:我将isOperate函数更改为以下内容:

float postfixUtility::isOperate(char operation, float operand1, float operand2)
{
if(operation == '+')
{   
    return operand1+operand2;
}
else if(operation == '-')
{
     return operand1-operand2;
}
else if(operation == '*')
{
     return operand1*operand2;
}
else if(operation == '/')
{   
    return operand1/operand2;
} 
}

然而,我仍然得到1。

1 个答案:

答案 0 :(得分:0)

那些重要的流行音乐:

float operand2 = S.top(); 
//S.pop();
float operand1 = S.top(); 
//S.pop();

如果不弹出最后一个元素,operand1将始终等于operand2,并且将数字除以自身通常会产生1。

你首先得到段错误的原因是你的postfix转换器给你(非常)错误的结果(从输出包含其输入中不存在的数字这一事实应该清楚)。让我们看一下您发布的输出的第一部分:43 12*+。您的解析器会将4312标识为数字并将其推送到堆栈中。它将*标识为运算符,从堆栈中取出两个数字,将它们相乘并将结果推送到堆栈上。然后它将遇到+并尝试从堆栈中获取两个操作数。但是,堆栈中只有一个元素,即乘法的结果。在空堆栈上调用top()会导致您的段错误。

编辑:在执行可能导致错误输入的未定义行为的操作之前进行健全性检查通常是个好主意。这可以让您做一些事情来解决问题或者产生包含诊断信息的错误消息(例如,在您的情况下,操作员,字符串中的位置,字符串本身等)。这将有助于您更轻松地识别此类问题。

tl; dr:修复你的后缀转换器。