While循环在一次迭代后终止



我正试图用C++编写一个函数来计算后缀表示法方程。我的一般策略是扫描字符串(以正确的格式,例如"10 20+30-")
我通过递增索引变量I来实现这一点。每次递增时,我都会检查字符是数字、运算符还是两者都不是。如果它是一个数字,我使用getNextNum()函数来获取以下所有数字,将其转换为浮点值,然后将其推送到堆栈中。我还将I乘以捕获的数字的长度。如果这个字符是一个运算符,我会得到堆栈的前两个元素,进行运算,然后将结果推回到堆栈。

问题是,我的while循环似乎只通过一次。函数只返回字符串中的第一个数字。我不知道出了什么问题,如果有任何帮助,我将不胜感激!我在while循环中插入了cout语句,并且我只递增到第一个数字之后的索引。

编辑:好的,我添加了getNextNum()函数。此外,我用strLength的cout更新了evalPostfix(),并在while循环的每次迭代后更新了I。当运行给定的代码时,我得到的是:

Running…
Please enter an expression in postfix notation: 555 666+
3
555
3
Your expression evaluates to: 555

strLength似乎被设置为小于它应该设置的值。为什么会这样?

#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
string getNextNum(string equation, int i);
float evalPostfix(string postfix);
float doOperation(float x, float y, char op);
float doOperation(float x, float y, char op)
{
    switch (op) {
        case '+':
            return x + y;
        case '-':
            return x - y;
        case '*':
            return x * y;
        case '/':
            return x / y;
        default:
            return 0.0;
    }
}

string getNextNum(string equation, int i)
{
    string num = "";
    const string DELIM = "+-*/%^ ";
    while (i<equation.length()) {
        // Iterate through equation until you hit a delimiter.
        if (DELIM.find(equation[i]) != -1) {
            break;
        }
        num += equation[i];
        i++;
    }
    return num;
}
float evalPostfix(string postfix)
{
    const string OPS = "+-*/%^";
    const string NUMS = "0123456789";
    int strLength = postfix.length();
    stack<float> numStack;
    int i = 0;
    cout << strLength << endl;
    while (i<strLength) {
        if (NUMS.find(postfix[i]) != -1) {
            // If a character is a digit, then you should get the 
            // value and push it to the stack (could be multiple characters long).
            string sNextNum = getNextNum(postfix, i);
            float fNextNum = atof(sNextNum.c_str());
            numStack.push(fNextNum);
            cout << sNextNum << endl;
            i += (sNextNum.length() - 1);
            }
        else if (OPS.find(postfix[i] != -1)) {
            // Otherwise, pop the top two elements of the stack, perform the
            // operation, then push the result back to the stack.
            char op = postfix[i];
            float x = numStack.top();
            numStack.pop();
            float y = numStack.top();
            numStack.pop();
            float z = doOperation(x, y, op);
            numStack.push(z);
            }
        i++;
        cout << i << endl;
    };
    // Once the entire string has been scanned through, there should be a float
    // left in the stack, simply return that.
    return numStack.top();
}
int main ()
{
    cout << "Please enter an expression in postfix notation: ";
    string postfix;
    cin >> postfix;
    float eval = evalPostfix(postfix);
    cout << "Your expression evaluates to: " << eval;
    return 0;
}

您有一些问题,其中一个主要问题是打字错误,您有一个放错地方的) this:

else if (OPS.find( postfix[i] != -1 ) ) {
                 ^                  ^ 

应该是:

else if (OPS.find( postfix[i] ) != std::string::npos) {
                 ^            ^  

所以您将位置i处的char-1进行比较,然后对布尔结果执行find。接下来,您应该使用-1来比较findstd::string::npos 的结果

正如Jonathan所指出的:

cin >> postfix ;

只读到第一个黑色或换行符。使用getline可以解决这个问题:

if (getline(cin, postfix))

一个主要问题是输入cin >> postfix;语句只读取第一个单词。回显输入,以确保程序看到您认为它正在看到的内容。

Shafik Yaghmour指出了另一个问题。

学习要点:

  1. echo输入,以确保程序正在看到您认为它正在看到的内容
  2. 用合适的打印消息跟踪关键变量
  3. 后SSCCE(简短、自包含、正确示例)——可以编译的代码
  4. 张贴示例输入和您从中得到的输出

此代码适用于输入555 666+:

#include <iostream>
#include <string>
#include <stack>
using namespace std;
static float doOperation(float x, float y, char op)
{
    cout << "doOp: x = " << x << ", y = " << y << ", op = " << op << endl;
    if (op == '+')
        x += y;
    return x;
}
string getNextNum(string equation, int i)
{
    string num = "";
    const string DELIM = "+-*/%^ ";
    while (i<equation.length()) {
        // Iterate through equation until you hit a delimiter.
        if (DELIM.find(equation[i]) != -1) {
            break;
        }
        num += equation[i];
        i++;
    }
    return num;
}
float evalPostfix(string postfix)
{
    const string OPS = "+-*/%^";
    const string NUMS = "0123456789";
    int strLength = postfix.length();
    stack<float> numStack;
    int i = 0;
    while (i<strLength) {
        cout << "Top - i: " << i << ", strLength: " << strLength << endl;
        if (NUMS.find(postfix[i]) != -1) {
            // If a character is a digit, then you should get the 
            // value and push it to the stack (could be multiple characters long).
            string sNextNum = getNextNum(postfix, i);
            float fNextNum = atof(sNextNum.c_str());
            numStack.push(fNextNum);
            cout << sNextNum << endl;
            i += (sNextNum.length() - 1);
            }
        else if (OPS.find(postfix[i])!= -1) {
            // Otherwise, pop the top two elements of the stack, perform the
            // operation, then push the result back to the stack.
            char op = postfix[i];
            float x = numStack.top();
            numStack.pop();
            float y = numStack.top();
            numStack.pop();
            float z = doOperation(x, y, op);
            numStack.push(z);
            }
        i++;
        cout << "End - i: " << i << ", strLength: " << strLength << endl;
    }
    cout << "After - i: " << i << ", strLength: " << strLength << endl;
    // Once the entire string has been scanned through, there should be a float
    // left in the stack, simply return that.
    return numStack.top();
}
int main ()
{
    cout << "Please enter an expression in postfix notation: ";
    string postfix;
    //cin >> postfix;
    if (getline(cin, postfix))
    {
        cout << "Evaluating: " << postfix << endl;
        float eval = evalPostfix(postfix);
        cout << "Your expression evaluates to: " << eval << endl;
    }
    return 0;
}

样品痕迹:

Please enter an expression in postfix notation: 555 666+
Evaluating: 555 666+
Top - i: 0, strLength: 8
555
End - i: 3, strLength: 8
Top - i: 3, strLength: 8
End - i: 4, strLength: 8
Top - i: 4, strLength: 8
666
End - i: 7, strLength: 8
Top - i: 7, strLength: 8
doOp: x = 666, y = 555, op = +
End - i: 8, strLength: 8
After - i: 8, strLength: 8
Your expression evaluates to: 1221

很明显,一旦你正在解决的特定问题得到解决,你可能会失去很多诊断输出,但准备好按照所示的方式添加它可以大大加快解决过程。

最新更新