中缀到Postfix Stack C ++输出

时间:2018-03-17 19:03:02

标签: c++ algorithm

#include<iostream>
#include<cstring>
#include<string>
#include "linkedStack.h"
#include <fstream>
#include <iomanip>
#include "ArgumentManager.h"
using namespace std;


int getPrecedence(char ch) //this function will decide and return precedence for the operators and operand
{
    switch (ch) 
    {
    case '/':return 2;
    break;
    case '*': return 2;
    break;
    case '+': return 1;
    break;
    case '-': return 1;
    break;
    default: return 0;
    }
}


string infixToPostfix(const string& expression) // this function will convert the infix expression to postfix by passing the infix expression string

{
    int size = expression.size(); //size of infix string
    char infix[expression.size()]; //converting string into array of chars
    strncpy(infix, expression.c_str(), sizeof(infix)); 
    infix[sizeof(infix)] = '\0'; //adding 0 for array ending
    char postfix[strlen(infix)]; // create a char array with the size of the infix string length

    linkedStack s;
    int precedence;
    int i = 0;
    int k = 0;
    char ch;
    //iterate the infix expression  
    while (i < size) 
    {
        ch = infix[i];
        //push opening parenthesis to stack
        if (ch == '(') 
        {
            s.push(ch);
            i++;
            continue;
        }
        if (ch == ')') 
        {
            while (!s.empty() && s.top() != '(') // if closing parenthesis is found pop of all the elements and append it to the postfix expression till we encounter an opening parenthesis
            {
                postfix[k++] = s.top();
                s.pop();
            }

            if (!s.empty()) 
            {
                s.pop(); // pop the opening parenthesis
            }
            i++;
            continue;
        }
        precedence = getPrecedence(ch);
        if (precedence == 0) 
        {
            postfix[k++] = ch; // if an operand is found add it to the postfix expression
        }
        else 
        {
            if (s.empty()) 
            {
                s.push(ch); //push operator onto stack if the stack is empty
            }
            else 
            {
                while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
                {
                    postfix[k++] = s.top();
                    s.pop();
                }

                s.push(ch);  // push the current operator to stack
            }
        }
        i++;
    }

    while (!s.empty())          // pop all of the the remaining operators in the stack and add it to postfix 
    {
        postfix[k++] = s.top();
        s.pop();
    }

    postfix[k] = '\0'; // add null character to end of character array for c string
    string postfixStr = postfix; //covert the final postfix char array to a string
    return postfixStr;  // returns the final postfix expression as a string
}





int main(int argc, char* argv[]) 
{
    ArgumentManager am(argc, argv);
    string infilename = am.get("A");
    string outfilename = am.get("C");
    string expression1;

    ifstream infile;
    infile.open(infilename);
    if (infile.good())
    {
        getline(infile, expression1);       //gets the infix string from file
    }
    infile.close(); //close the infile stream

    string expression2 = "12 + 3 / 4";
    string postfix1 = infixToPostfix(expression1);
    string postfix2 = infixToPostfix(expression2);
    cout << expression1 << endl;
    cout <<  postfix1 << endl;
    cout <<  expression2 << endl;
    cout <<  postfix2 << endl;
    return 0;
}

嗨,我使用我的中缀输出使用堆栈修复转换器时出现问题。例如,在&#34; 12 + 3/4&#34;输出应为&#34; 12 3 4 / +&#34;字符均匀地间隔一个空格。但是,它会添加不必要的空格或根本不添加空格。对于上面的测试用例,您可以看到我在附加图片或下面的图片中遇到的问题。第一行是中缀,第二行是后置修复输出。这里有两种情况。Output Example

25 + ( 4 * 5 ) - 12
25   4  5 * + 12-
12 + 3 / 4
12  3  4/+

2 个答案:

答案 0 :(得分:0)

1)此代码:

int size = expression.size(); //size of infix string
char infix[expression.size()]; //converting string into array of chars
strncpy(infix, expression.c_str(), sizeof(infix)); 
infix[sizeof(infix)] = '\0'; //adding 0 for array ending

可以替换为:

char * infix = new char [expression.length()+1];
std::strcpy (infix, expression.c_str());

2)此代码弹出值没有将它们重新压入s之后。

while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
{
     postfix[k++] = s.top();
     s.pop();
}

答案 1 :(得分:0)

感谢您的所有建议。最后,我做了一些事情来实现所需的输出。首先,我增加了后缀数组。接下来,在循环中的两个特定点,每当它附加到后缀数组时,我也会添加一个空格。

下面:

while (!s.empty() && s.top() != '(' && precedence <= getPrecedence(s.top())) // pop of all the operators from the stack to the postfix expression till we see an operator with a lower precedence than the current operator
                {
                    postfix[k++] = s.top();
                    postfix[k++] = ' ';
                    s.pop();
                }

在这里:

while (!s.empty())          // pop all of the the remaining operators in the stack and add it to postfix 
    {
        postfix[k++] = s.top();
        postfix[k++] = ' ';
        s.pop();
    }

最后,我使用了一个单独的函数来修剪最终字符串中的任何多余空格。 有点乱,但完成工作。