Search code examples
c++postfix-notation

Infix to postfix - Including negative values


I'm making a function to convert a infix math-string to postfix. This is what I have:

std::string toPostfix(std::string& infixStr, std::string& postfixStr, std::string& first_nr, std::string& second_nr, char oper, char prev_oper) {

    //std::cout << "[" << infixStr << "]" << std::endl;

    if (infixStr == "") {
        if (second_nr == "") {
            second_nr = "0";
        }

        if (oper == '\0') {
            oper = prev_oper;

            if (prev_oper == '-') {
                second_nr = first_nr;
                first_nr = "0";
            }
        }


        postfixStr += first_nr + " " + second_nr + " " + oper;

        std::cout << " end: " << postfixStr << std::endl ;
        return postfixStr;
    }


    char c = infixStr[0];

    if (isOperator(c)) {
        ///////////////
        if (postfixStr == "") {
            if (c == '-') {

            }
        }
        //////////////////

        if (oper != '\0') {
            if (first_nr == "") {
                if (oper == '-') {
                    /////////////////////////
                }
            }

            postfixStr += first_nr + " " + second_nr + " " + oper + " ";

            first_nr = "";
            second_nr = "";
            oper = '\0';
            prev_oper = c;
        } else {

            oper = c;
        }
    } else {
        if (oper == '\0') {
            first_nr += c;
        } else {
            second_nr += c;
        }
    }

    infixStr = infixStr.erase(0, 1);
    return toPostfix(infixStr, postfixStr, first_nr, second_nr, oper, prev_oper);
}

This works in some cases, however for example this input string 0+1-5+2 the output is 0 1 + 5 2 +. The - gets ignored. The correct output should be 0 1 + -5 2 + What am I doing wrong? I think I need to differentiate a minus as in operator, and minus as in making a value negative.


Solution

  • /*
     * Function to convert an infix string to postfix notation
     * :param infix: Infix string
     * :return string: returns postfix string
     *
     * Example:
     * std::string s = "5+5";
     * toPostfix(s) == "5 5 +"
     *
     */
    std::string toPostfix(std::string& infix) {
        std::string postfix = "";
    
        //Stack to hold operators and nr is a helper string to
        //group digits in numbers
        std::stack<char> stack;
        std::string nr = "";
    
        //If first character is a minus-operator (AKA a negative number)
        //add "0"
        if (infix[0] == '-') {
            infix = "0" + infix;
        }
    
        //Looping over infix string
        for (int i = 0; i < infix.size(); i++) {
            //If current evaluated character ain't an operator, it's a digit
            if (!isOperator(infix[i])) {
                //If digit is in a group of digits (AKA a number) put the whole number in nr
                while (!isOperator(infix[i]) && i < infix.size()) {
                    nr += infix[i];
                    i++;
                }
    
                i--;
    
                //Append the number to the postfix string
                postfix += nr + " ";
                nr = "";
            } else {
                //This block is executed when evaluated character is an operator
    
                //If stack is empty, or the evaluated operator is higher than the one in the stack
                //push it to the stack (Needs to be appended to the postfix string later)
                if (stack.size() == 0 || precedence(infix[i]) > precedence(stack.top())) {
                    stack.push(infix[i]);
                } else {
                    //While the stack contacts a higher or equally high precedence as currently
                    //evaluated operator
                    while (precedence(stack.top()) >= precedence(infix[i])) {
                        //We append the top of the stack to the postfix string
                        postfix += stack.top();
                        postfix += ' ';
    
                        stack.pop();
                        if (stack.size() == 0) {
                            break;
                        }
                    }
    
                    //Push evaluated operator to stack
                    stack.push(infix[i]);
                }
            }
        }
    
        //Append all remaining operators to the postfix string
        while (stack.size() != 0) {
            postfix += stack.top();
            stack.pop();
        }
    
        return postfix;
    }