while循环在一次迭代后终止

时间:2013-07-07 01:54:00

标签: c++

我正在尝试用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;
}

2 个答案:

答案 0 :(得分:1)

你有一些问题,其中一个主要问题是拼写错误,你错了)这个:

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

应该是:

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

因此,您要将位置char的{​​{1}}与i进行比较,然后对布尔结果执行-1。接下来,您应该使用find来比较find的结果,但std::string::npos

正如乔纳森指出的那样:

-1

仅读取第一个黑色或换行符。使用cin >> postfix ; 将解决该问题:

getline

答案 1 :(得分:0)

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

Shafik Yaghmour指出另一个problem

要学习的内容:

  1. 回显输入以确保程序看到您认为它看到的内容;
  2. 使用合适的打印消息跟踪关键变量;
  3. 发布SSCCE(Short, Self-Contained, Correct Example) - 可以编译的代码;
  4. 发布示例输入和您从中获取的输出。
  5. 此代码适用于输入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
    

    显然,一旦您解决的具体问题得到解决,您可能会丢失大部分诊断输出,但是准备按照显示的方式添加它可以大大加快解决它的过程。