Infix-to-Postfix Conversion - C++ Data Structure

C++ examples for Data Structure:Stack

Description

Infix-to-Postfix Conversion

Demo Code

#include <iostream>
#include <string>

template <typename NODETYPE>
class List;/*from   w  w w. j a va 2 s . com*/

template <typename NODETYPE>
class ListNode {
    friend class List<NODETYPE>;  // make List a friend

 public:
    explicit ListNode(const NODETYPE& info) : data(info), nextPtr(0) {}

    // return copy of data in node
    NODETYPE getData() const { return data; }

    // return pointer to next node
    ListNode<NODETYPE>* next() const { return nextPtr; }

 private:
    NODETYPE data;
    ListNode<NODETYPE> *nextPtr;
};


template <typename NODETYPE>
class List {
 public:
    List();
    ~List();

    void insertAtFront(const NODETYPE &);
    void insertAtBack(const NODETYPE &);
    bool removeFromFront(NODETYPE &);
    bool removeFromBack(NODETYPE &);
    void concatenate(List<NODETYPE> &);
    // is List empty
    bool isEmpty() const { return firstPtr == 0; }
    void print() const;
    // print sz of list
    int size() const { return sz; }

    // return pointer to first node
    ListNode<NODETYPE>* begin() const { return firstPtr; }
    // return pointer to last node
    ListNode<NODETYPE>* end() const { return lastPtr; }

 private:
    ListNode<NODETYPE> *firstPtr;  // pointer to first node
    ListNode<NODETYPE> *lastPtr;   // pointer to last node

    int sz;

    // utility function to allocate new node
    ListNode<NODETYPE> *getNewNode(const NODETYPE &);
};

template <typename NODETYPE>
List<NODETYPE>::List() : firstPtr(0), lastPtr(0), sz(0) {}

template <typename NODETYPE>
List<NODETYPE>::~List() {
    if (!isEmpty()) {
        ListNode<NODETYPE> *currentPtr = firstPtr;

        // delete remaining nodes
        while (currentPtr != 0) {
            ListNode<NODETYPE> *tempPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
            delete tempPtr;
        }
    }
}

template <typename NODETYPE>
void List<NODETYPE>::insertAtFront(const NODETYPE &value) {
    ListNode<NODETYPE> *newPtr = getNewNode(value);

    if (isEmpty()) {
        firstPtr = lastPtr = newPtr;  // new list only has one node
    } else {
        newPtr->nextPtr = firstPtr;  // point new node to previous list node
        firstPtr = newPtr;
    }
    ++sz;
}

template <typename NODETYPE>
void List<NODETYPE>::insertAtBack(const NODETYPE &value) {
    ListNode<NODETYPE> *newPtr = getNewNode(value);

    if (isEmpty()) {
        firstPtr = lastPtr = newPtr;  // new list has only one node
    } else {
        lastPtr->nextPtr = newPtr;
        lastPtr = newPtr;
    }
    ++sz;
}

template <typename NODETYPE>
bool List<NODETYPE>::removeFromFront(NODETYPE &value) {
    if (isEmpty()) {  // list is empty
        return false;
    } else {
        ListNode<NODETYPE> *tempPtr = firstPtr;

        if (firstPtr == lastPtr)
            firstPtr = lastPtr = 0;  // no nodes remain after removal
        else
            firstPtr = firstPtr->nextPtr;  // point to previous 2nd node

        value = tempPtr->data;
        delete tempPtr;

        --sz;

        return true;
    }
}

template <typename NODETYPE>
bool List<NODETYPE>::removeFromBack(NODETYPE &value) {
    if (isEmpty()) {  // list is empty
        return false;
    } else {
        ListNode<NODETYPE> *tempPtr = lastPtr;

        if (firstPtr == lastPtr) {   // list has one element
            firstPtr = lastPtr = 0;  // no nodes remain after removal
        } else {
            ListNode<NODETYPE> *currentPtr = firstPtr;

            // locate second to last element
            while (currentPtr->nextPtr != lastPtr)
                currentPtr = currentPtr->nextPtr;  // move to next node

            lastPtr = currentPtr;     // remove last node
            currentPtr->nextPtr = 0;  // this is now the last node
        }

        value = tempPtr->data;
        delete tempPtr;

        --sz;
        return true;
    }
}

template <typename NODETYPE>
void List<NODETYPE>::concatenate(List<NODETYPE> &listSecond) {
    ListNode<NODETYPE> *currentPtr = listSecond.firstPtr;

    while (currentPtr != 0) {
        insertAtBack(currentPtr->getData());
        currentPtr = currentPtr->nextPtr;
    }
}

template <typename NODETYPE>
ListNode<NODETYPE> *List<NODETYPE>::getNewNode(const NODETYPE &value) {
    return new ListNode<NODETYPE>(value);
}

template <typename NODETYPE>
void List<NODETYPE>::print() const {
    if (isEmpty()) {
        std::cout << "The list is empty\n\n";
        return;
    }

    ListNode<NODETYPE> *currentPtr = firstPtr;

    while (currentPtr != 0) {
        std::cout << currentPtr->getData() << ' ';
        currentPtr = currentPtr->nextPtr;
    }
}

template <typename STACKTYPE>
class Stack : private List<STACKTYPE> {
 public:
    void push(const STACKTYPE &data) { this->insertAtBack(data); }
    bool pop(STACKTYPE data) { return this->removeFromBack(data); }
    bool isStackEmpty() const { return this->isEmpty(); }
    void printStack() const { this->print(); }
    STACKTYPE stackTop() const { return this->end()->getData(); }
};

bool isOperator(const char& c) {
    switch (c) {
        case '+':
        case '-':
        case '*':
        case '/':
        case '^':
        case '%':
            return true;
            break;
        default:
            return false;
            break;
    }
}

bool precedence(const char& operator1, const char& operator2) {
    switch (operator1) {
        case '+':
        case '-':
            return ((operator2 == '-') || (operator2 == '+'));
        case '*':
        case '/':
        case '%':
            return ((operator2 == '*') || (operator2 == '/') ||
                    (operator2 == '%') || (operator2 == '+') ||
                    (operator2 == '-'));
        case '^':
            return true;
        default:
            return false;
    }
}

std::string convertToPostfix(std::string& infix) {
    std::string postfix;        // final expression
    Stack<char> postfixStack;

    postfixStack.push('(');

    infix += ')';

    for (char& c : infix) {
        if (isdigit(c))
            postfix += c;
        if (c == '(')
            postfixStack.push(c);

        if (isOperator(c)) {
            while (isOperator(postfixStack.stackTop())
                   && precedence(postfixStack.stackTop(), c)) {
                postfix += postfixStack.stackTop();
                postfixStack.pop(postfixStack.stackTop());
            }
            postfixStack.push(c);
        }
        if (c == ')') {
            while (postfixStack.stackTop() != '(') {
                postfix += postfixStack.stackTop();
                postfixStack.pop(postfixStack.stackTop());
            }
            postfixStack.pop(')');
        }
    }

    return postfix;
}

int main(int argc, const char* argv[]) {
    std::string infix;          // original expression

    std::cout << "Enter infix expression: ";
    std::getline(std::cin, infix);

    std::cout << convertToPostfix(infix) << std::endl;

    return 0;
}

Result


Related Tutorials