此程序读取输入文件,并从该输入文件将每个传入中缀行更改为后缀表示法。除了我的main()中嵌套的while循环处理操作符号(* / + - )之外,所有东西似乎都在工作。当它被注释掉时,输出要好得多。我不确定它为什么会进入无限循环。
我将大部分伪代码保留在main上,以便读者可以看到我的思路,可能有更好的方法来执行此程序。
tests.txt包含:
4
5+7
7*5
(5-3)
5/5
8*5+3
8*(5+3)
8+3*5-7
(8+3)*(5-6)
((8+3)*(2-7))
((8+3)*2)-7
(8*5)+((3-2)-7*3)
((8*5+3)-7)-(5*3)
7*9+7-5*6+3-4
Node.h
#pragma once
template <class T>
struct Node
{
// Data members
T data;
Node<T>* next;
// Constructor
Node(T d);
};// End the Node struct
template<class T>
Node<T>::Node(T d)
{
data = d;
next = nullptr;
}
Stack.h
#pragma once
#include "Node.h"
template <class T>
class Stack
{
private:
Node<T>* head;
public:
// Constructor
Stack();
// Destructor
~Stack();
// push
void push(T);
// pop
void pop();
// top
T top();
// empty
bool empty();
};// End Stack template
template<class T>
Stack<T>::Stack()
{
head = nullptr;
}
template<class T>
Stack<T>::~Stack()
{
// While the stack is not empty
if (empty() != true)
{
// Create a temporary Node
Node<T>* temp;
// Set the temp to the next node
temp = head->next;
// Delete the first node
delete head;
// Set the first node to the next node
head = temp;
}
}
template<class T>
void Stack<T>::push(T value)
{
// Make a new node with value
Node<T>* incomingTop = new Node<T>(value);
// Set its pointer to the current top
incomingTop->next = head;
// Set the top to the new value
head = incomingTop;
}
template <class T>
void Stack<T>::pop()
{
// If the stack is not empty
if (empty() != true)
{
// Set a new pointer to the top
Node<T>* oldTop = head;
// Set the top to its next
head = head->next;
// Delete the oldTop
delete oldTop;
}
}
template <class T>
T Stack<T>::top()
{
// If the stack is not empty
if (empty() != true)
{
// Return the data in the top
return head->data;
}
}
template<class T>
bool Stack<T>::empty()
{
// If the top of the stack is null
if (head == nullptr)
{
// The stack is empty
// Return true
return true;
}
else // Otherwise
{
// The stack has data
// Return false
return false;
}
}
calc.cpp
// Include necessary files
#include "Stack.h"
#include <iostream>
#include <fstream>
#include <string>
#include <assert.h>
using namespace std;
typedef char valueType;
/* precedence function
Purpose: Determines if the passed in char is of higher precedence */
int precedence(char);
// main
int main()
{
cout << "Postfix expressions translated from ''tests.txt''";
Stack<valueType> storage;
ifstream input;
input.open("tests.txt");
if (input.fail())
{
cout << "Could not open input file." << endl;
}
// While not at the end of the file
while (input && input.peek() != EOF)
{
// Read and store a charachter from the input file
char testValue = input.get();
// If the value is a newline charachter
if (testValue == '\n')
{
// Then create a newline on the console
cout << endl;
// Empty the stack
while (storage.empty() == false)
{
// Display the top of the stack
cout << storage.top();
// Pop
storage.pop();
}
}// End if for newline charachter
// If the value is a left paren
else if (testValue == '(')
{
// Store it on the stack
storage.push(testValue);
}
// If the value is an operation symbol
else if (testValue == '+' || testValue == '-' || testValue == '*' || testValue == '/')
{
/* While:
The stack is not empty
Or the next symbol on the stack is not a left paren
Or the next symbol is not of higher precedence */
while (storage.empty() != true || storage.top() != '(' || precedence(testValue) >= precedence(storage.top()))
{
// Display the test value
cout << testValue;
// Make the test value the top of the stack
testValue = storage.top();
// Pop the top of the stack
storage.pop();
}// End nested while loop
/* If the above while loop is exited
Push test value onto the stack */
storage.push(testValue);
}// End else if for operation symbols
// If the value is a right paren
else if (testValue == ')')
{
// While the top is not a left paren
while (storage.top() != '(')
{
// If no left paren is encountered then halt the program
assert("There were unblanced parentheses. Halting the program.", storage.empty == true);
// Print the top operation
cout << storage.top();
// Pop the top value
storage.pop();
}// End nested while loop
// Pop the left paren
storage.pop();
}// End else if for the right paren
else // Otherwise if the value is an operand (number or variable)
{
// Write it out to the console
cout << testValue;
}
}// End outer while loop
input.close();
cout << endl;
system("PAUSE");
return 0;
}// End main
int precedence(char c)
{
if (c == '*' || c == '/')
{
return 2;
}
if (c == '+' || c == '-')
{
return 1;
}
else
{
return 0;
}
}