在c ++中使用堆栈计算postfix时处理十进制值

时间:2012-12-03 15:47:32

标签: c++ evaluation decimal

我是新手,在c ++中编写相对较新的编码。

我的问题涉及: 在使用c ++ 中的堆栈评估postfix时处理十进制值。这是一项家庭作业,但我已经将我的代码用于基本要求。我的作业不是在寻求帮助。我的教授希望我们强制执行任务,因此我使用<stack>之类的特殊头文件避免了许多快捷方式。

我已经研究过这个问题,并且不满意给出的答案。似乎没有人像我一样分裂他们的代码。我有一个问题从内部循环传递一个值,该值检测到十进制值到主函数的其余部分。代码编译并运行,但我的最终结果是胡言乱语。我找到一个帖子,声明多个值不能从'return'的函数传递,但我确实需要从内部十进制函数返回至少两个值。我不理解'tuple''pair'命令。

我知道这是一个罗嗦的前奏,但我确实希望任何读者都明白我已经阅读了必备的材料,并且失去了研究。就个人而言,我讨厌蛮力方法。我知道答案可能没有及时帮助我的项目,但我已经做了几个星期的工作。我希望看到这种方法的运作符合我的意愿。建议和指示非常受欢迎。

以下是我的代码的链接: link

这是我的代码:

//*****************************************************************************
// Postfix expression evaluation
// 11/13/2012
// by DJH
//
// all applicable copyrights apply
//
// this program evaluates an input postfix string
// 
// created using Dev-C++ 5.2.0.3
//*****************************************************************************

// ----------------------------------libraries---------------------------------

#include <iostream>                     // For cin, cout and endl
#include <string>
#include <cctype>
#include <vector>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <iomanip>

using namespace std;
// ------------------------------ Globals -------------------------------------
string postfix;

// --------------------------- stack class ------------------------------------
class Stack {
public:
    enum {MaxStack = 50};
    void init() {top = -1;}
    void push( double p ) {
        if ( isFull() ) {
            cerr << "Full Stack. DON'T PUSH\n";
            return;
        }
        else {
            arr[ ++top ] = p;
            cout << "Just pushed " << p << endl;
            return;}
    }
    int pop() {
        if (isEmpty() ) {
            cerr << "\tEmpty Stack. Don't Pop\n\n";
            return 1;
        }
        else
        return arr[top--];
    }
    bool isEmpty() {return top < 0 ? 1 : 0;}
    bool isFull() {return top >= MaxStack -1 ? top : 0;}
    void dump_stack() {
        cout << "The Stack contents, from top to bottom, from a stack dump are: " << endl;
        for (int s = top; s >= 0; s--)
        cout << "\t\t" << arr[s] << endl;
    }
private:
    int top;
    double arr[MaxStack];
} pStack;
// ------------------------------ end stack class -----------------------------

// -----------------------------function prototypes----------------------------
void evalPostfix( string);
double decimalEvaluate( string, int, double);
// ----------------------------------------------------------------------------

// -----------------------------------Main()-----------------------------------
int main() {
    cout << "Enter a postfix expression\n\t (without spaces - using '_' for delimiters):\n\t";
    cout << "For example: 8_5_3_+_*_2_/_5_+\n" << endl;
    getline(cin, postfix);

    //  postfix = "7_2_*_5_+_2_*";
    cout << "You entered: " << postfix << endl;

    int c = 0;

    while (postfix[c] != '\0') {
        // this loop counts the characters in the input string including 
        // whitespace
        ++c;
    }

    cout << "\tThe string length is:\t" << c << endl;
    evalPostfix(postfix);
    int result = pStack.pop();
    cout << "The result of the postfix expression is: " << result << endl;

    /*
     stack commands:
     Stack a_stack;                  // creates new stack
     a_stack.init();                 // initializes top element
     a_stack.pop();                  // pops top of stack
     a_stack.push(n);                // push element to top of stack
     a_stack.dump_stack();           // displays the contents of the stack from top to bottom
     */
    return 0;
    cin.get();
}

// --------------------------------end of Main()-------------------------------

// ------------------------------functions follow------------------------------
void evalPostfix( string) {
    double ch = 0, dc = 0, b = 0, a = 0, d = 0;
    double tempDC = 0;
    double tempDCD = 0;
    char op;
    int i = 0, j = 0, k = 0, m = 0, n = 0, q = 0;
    while (postfix[i] != '\0') {

        if (postfix[i] == '_') {
            i++;
        } else if (isdigit(postfix[i])) {
            ch = postfix[i] - '0';         // for numbers only
            j = i + 1;
            while (postfix[j] != '_') {
                if (isdigit(postfix[j])) {
                    ch = ch * 10 + (postfix[j] - '0');
                    k = j + 1;
                    // this accounts for decimals by skipping the '.' and
                    // conducting operations on trailing numbers
                    if (postfix[k] == '.') {
                        dc = 0;
                        decimalEvaluate(postfix, k, dc);
                        dc = tempDC / tempDCD;
                        d = ch + dc;
                        k++;
                    }
                    j = k - 1;
                    j++;
                }
            }
            cout << "Post decimal function k: " << k << endl;
            cout << "Post decimal function dc: " << setprecision(12) << dc
                    << endl;
            cout << "Post decimal function d: " << d << endl;
            pStack.push(d);
            i = j - 1;
            i++;
        } else if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*'
                || postfix[i] == '/' || postfix[i] == '^') {
            b = pStack.pop();
            a = pStack.pop();
            op = postfix[i];         // for operators only
            switch (op) {
            case '+':
                pStack.push(a + b);
                break;
            case '-':
                pStack.push(a - b);
                break;
            case '*':
                pStack.push(a * b);
                break;
            case '^':
                pStack.push(pow(a, b));
                break;
            case '/':
                if (b == 0) {
                    cout << "Division by zero not allowed!" << endl;
                    cin.get();
                    exit(0);
                }
                pStack.push(a / b);
            default:
                cout << "Invalid Operation" << endl;
            }
            i++;
        }

    }
}
// ----------------------------------------------------------------------------

double decimalEvaluate(string postfix, int k, double dc) {
    dc = 0;
    double tempDC = 0;
    double tempDCD = 0;
    int n = 0, m = 0, lenDC = 0;
    n = k;

    while (postfix[n] != '_') {
        if ((isdigit(postfix[n])) == false) {
            n++;
        }
        cout << "This step (1) n: " << n << endl;
        if (isdigit(postfix[n])) {
            m = n;
            // assumes characters between a '.' and '_' are all digits
            // (may need to check)
            while (postfix[m] != '_') {
                lenDC++;
                // this loop counts the digits in the input trailing a decimal
                // point
                m++; 
            }

            cout << "This step (2) m: " << m << endl;
            cout << "This step (2) lenDC: " << lenDC << endl;

            while ((postfix[n]) != '_') {
                tempDC = tempDC * 10 + (postfix[n]) - '0';
                n++;
            }

            cout << "This step (3) n: " << n << endl;
            cout << "This step (3) tempDC: " << tempDC << endl;
        }

        k = n;
        tempDCD = pow(10, lenDC);
        dc = tempDC / tempDCD;

        cout << "This step (4) k: " << k << endl;
        cout << "This step (4) tempDCD: " << tempDCD << endl;
        cout << "This step (4) tempDC: " << tempDC << endl;
        cout << "This step (4) dc: " << dc << endl;
    }

    return dc, k, tempDC, tempDCD;
}

1 个答案:

答案 0 :(得分:0)

通过引用传递变量:

void decimalEvaluate (string postfix, int& k, double& dc, double& tempDC, double& tempDCD)
{
    tempDC = 0.0;
    //...
}