I am currently working on a RPN calculator, it takes an infix expression converts it to postfix and shows the answer. I mostly got it right, but when I pop the answer from the stack if shows only the last digit of the result
ex
Enter infix: (1+1)*13+10/2
Postfix: 11+13*102/+
Result is: 1
Enter infix: 2*13+10/2
Postfix: 213*102/+
Result is:1
It gets it right for this kind of inputs
Enter infix: 3*2+5
Postfix: 32*5+
Result is : 11
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
class infix2postfix
{
public:
void push(int symbol);
int pop();
void infix_to_postfix();
int priority(char symbol);
int isEmpty();
int white_space(char);
int eval_post();
};
char infix[100], postfix[100];
int stack[100];
int top;
int main()
{
infix2postfix ip;
top=-1;
cout<<"Enter infix : ";
gets(infix);
ip.infix_to_postfix();
cout<<"Postfix : "<<postfix<<endl;
cout<<"Result is : "<<ip.eval_post()<<endl;
return 1;
}
void infix2postfix :: infix_to_postfix()
{
int i,p=0;
char next;
char symbol;
for(i=0; i<strlen(infix); i++)
{
symbol=infix[i];
if(!white_space(symbol))
{
switch(symbol)
{
case '(':
push(symbol);
break;
case ')':
while((next=pop())!='(')
postfix[p++] = next;
break;
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
while( !isEmpty( ) && priority(stack[top])>= priority(symbol) )
postfix[p++]=pop();
push(symbol);
break;
default: /*if an operand comes*/
postfix[p++]=symbol;
}
}
}
while(!isEmpty( ))
postfix[p++]=pop();
postfix[p]='\0'; /*End postfix with'\0' to make it a string*/
}
/*This function returns the priority of the operator*/
int infix2postfix :: priority(char symbol)
{
switch(symbol)
{
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '^':
return 3;
default :
return 0;
}
}
void infix2postfix :: push(int symbol)
{
if(top>100)
{
cout<<"Stack overflow\n";
exit(1);
}
stack[++top]=symbol;
}
int infix2postfix :: pop()
{
if( isEmpty() )
{
cout<<"Stack underflow\n";
exit(1);
}
return (stack[top--]);
}
int infix2postfix :: isEmpty()
{
if(top==-1)
return 1;
else
return 0;
}
int infix2postfix :: white_space(char symbol)
{
if( symbol == ' ' || symbol == '\t' )
return 1;
else
return 0;
}
int infix2postfix :: eval_post()
{
int a,b,i,temp,result;
for(i=0; i<strlen(postfix); i++)
{
if(postfix[i]<='9' && postfix[i]>='0')
push(postfix[i]-'0');
else
{
a=pop();
b=pop();
switch(postfix[i])
{
case '+':
temp=b+a;
break;
case '-':
temp=b-a;
break;
case '*':
temp=b*a;
break;
case '/':
temp=b/a;
break;
case '%':
temp=b%a;
break;
case '^':
temp=pow(b,a);
}
push(temp);
}
}
result=pop();
return result;
}
Consider what happens when eval_post() is given 213*102/+ to work with. Let's start in the middle, with the '1' after the asterisk. The '1' is a digit, so push it [stack ends with: 1]. Similarly, the 0 and 2 get pushed [stack ends with: 1, 0, 2]. Then the division symbol is encountered, so pop 2 and 0, then push 0/2 = 0 [stack ends with: 1, 0]. Finally, the addition symbol is encountered, so pop 0 and 1, then push 1+0=1, which is then popped as your answer.
One symptom of your problem is that, if things work, the stack should be empty when eval_post() returns. However, it is not empty when your infix includes numbers with more than one digit. Note that "10" gets pushed onto the stack as two numbers: "1" followed by "0". You want the value 10 pushed.
There are also some style problems with the code, but this appears to be the main functional problem.
Related
void scoreBoardHelper(Grid<char>& board, Lexicon& lex, Set<string>& visitedPrefixes, string current, GridLocation location, Set<string>& foundWords, Set<GridLocation> visitedTiles){
if(lex.contains(current) && current.size()>3){
foundWords.add(current);
}
if(current == ""){
current += board[location];
visitedTiles.add(location);
}
//check neighbors
GridLocation neighbor = location;
for(int i = 0; i<8; i++){
switch (i) {
case 0:
neighbor.col++;
break;
case 1:
neighbor.col--;
break;
case 2:
neighbor.row++;
break;
case 3:
neighbor.row--;
break;
case 4:
neighbor.col++;
neighbor.row++;
break;
case 5:
neighbor.col--;
neighbor.row--;
break;
case 6:
neighbor.col--;
neighbor.row++;
break;
case 7:
neighbor.col++;
neighbor.row--;
break;
}
if(board.inBounds(neighbor) && board[neighbor]!=current[current.size()-2] && !visitedTiles.contains(neighbor) && lex.containsPrefix(current + board[neighbor]) && !visitedPrefixes.contains(current + board[neighbor])){
visitedPrefixes.add(current + board[neighbor]);
visitedTiles.add(neighbor);
scoreBoardHelper(board, lex, visitedPrefixes, current + board[neighbor], neighbor, foundWords, visitedTiles);
}
neighbor = location;
}
}
int scoreBoard(Grid<char>& board, Lexicon& lex) {
Set<string> visitedPrefixes;
Set<GridLocation> visitedTiles;
string current = "";
GridLocation location;
Set<string> foundWords;
for(int r=0;r<board.numRows();r++){
location.row=r;
for(int c=0;c<board.numCols();c++){
location.col=c;
scoreBoardHelper(board, lex, visitedPrefixes, current, location, foundWords, visitedTiles);
}
}
int previousPoints = 0;
for(string word : foundWords){
cout<<"found word: "<<word<<endl;
previousPoints += points(word);
}
return previousPoints;
}
I wrote these 2 functions but they don't seem to solve boggle. When I remove the !visitedTiles.contains(neighbor) check, it works as expected but it finds extra words that it should discard. When it has this check it narrows the solution unexpectedly and finds 2 words where it should find many more. Note: The points function works fine.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Hey guys I'm pretty new into coding...
so my code won't run and i don't know what is wrong.
one of the errors that Im getting is that in my
void animal::petDataInfo(animal maxEntry[], int counter)
the counter is saying that it isn't being initialized...
basically i don't know whats wrong....
animal.h
#ifndef Database_animal_h
#define Database_animal_h
struct animal
{
char petName[20];
char lastName[30];
char color[12];
int month, day, year;
void petDataInfo(animal [], int &counter);
void displayInfo(animal [], int &counter);
}; animal maxEntry[100];
#endif
main.cpp
#include <iostream>
#include <string>
using namespace std;
#include "animal.h"
enum animalSpecies {Dog, Cat, Bird, Reptile, Other};
animalSpecies getAnimal();
void print(animalSpecies entered);
void menuInfo(animal [], int &counter);
void petDataInfo(animal [], int &counter);
void displayInfo(animal [], int &counter);
void quitInfo(int &counter);
int main()
{
int counter=0;
counter++;
menuInfo(maxEntry, counter);
system ("PAUSE");
return 0;
}
/********************************************************************************************************/
void menuInfo(animal maxEntry[], int& counter)
{
char letter;
do
{
cout<<"\nWhat would you like to do?"<<endl;
cout<<"(E)nter"<<endl;
cout<<"(S)earch"<<endl;
cout<<"(D)isplay"<<endl;
cout<<"(C)lear"<<endl;
cout<<"(Q)uit"<<endl;
cout<<"\n";
cout<<"Please enter a letter: "<<endl;
cin>>letter;
cout<<"\n";
cout<<"\n";
if (!((letter=='e')|| (letter=='E') || (letter=='s') || (letter=='S') || (letter=='d') || (letter=='D') || (letter=='c') || (letter=='C') || (letter=='q') || (letter=='Q')))
{
cout<<"Not a valid letter. Try again."<<endl;
cout<<"\n";
}
}
while (!((letter=='e')|| (letter=='E') || (letter=='s') || (letter=='S') || (letter=='d') || (letter=='D') || (letter=='c') || (letter=='C') || (letter=='q') || (letter=='Q')));
{
switch (letter)
{
case'e': case 'E':
petDataInfo(maxEntry, counter);
if ((letter=='e') || (letter=='E'))
{
cout<<"Entry number: "<<counter++;
}
break;
case 's': case 'S':
cout<<"goes to search database"<<endl;
break;
case 'd': case 'D':
displayInfo(maxEntry, counter);
break;
case 'c': case 'C':
if ((letter=='c') || (letter=='C'))
{
counter--;
}
break;
case 'q': case 'Q':
quitInfo(counter);
break;
default:
cout<<"Try again. \n";
}
}
}
/********************************************************************************************************/
void animal::petDataInfo(animal maxEntry[], int counter)
{
for(int i=0; i<counter; i++)
{
cout<<"What is the pets first name? "<<endl;
cin>>maxEntry[i].petName;
cout<<"What is the owners last name? "<<endl;
cin>>maxEntry[i].lastName;
getAnimal();
cout<<"What month is your pets date of birth? "<<endl;
cin>>maxEntry[i].month;
cout<<"What day is your pets date of birth? "<<endl;
cin>>maxEntry[i].day;
cout<<"What year is your pets date of birth? "<<endl;
cin>>maxEntry[i].year;
cout<<"What color is your pet? "<<endl;
cin>>maxEntry[i].color;
}
menuInfo(maxEntry, counter);
}
/********************************************************************************************************/
animalSpecies getAnimal()
{
animalSpecies entered = Dog;
char species;
cout<<"Species of Animal:\n (D)og\n (C)at\n (B)ird\n (R)eptile\n (O)ther\n "<<endl;
cin>>species;
switch (species)
{
case 'd':
case 'D':
entered = Dog;
break;
case 'c':
case 'C':
entered = Cat;
break;
case 'b':
case 'B':
entered = Bird;
break;
case 'r':
case 'R':
entered = Reptile;
break;
case 'o':
case 'O':
entered = Other;
break;
default:
cout<<"Error: Try again. "<<endl;
}
return entered;
}
/********************************************************************************************************/
void print(animalSpecies entered)
{
switch (entered)
{
case Dog:
cout<<"Dog"<<endl;
break;
case Cat:
cout<<"Cat"<<endl;
break;
case Bird:
cout<<"Bird"<<endl;
break;
case Reptile:
cout<<"Reptile"<<endl;
break;
case Other:
cout<<"Other"<<endl;
break;
}
}
/********************************************************************************************************/
void animal::displayInfo(animal maxEntry[], counter)
{
for(int i=0; i<100; i++)
{
cout<<"Pet name: "<<maxEntry[i].petName<<"\n";
cout<<"Owners last name: "<<maxEntry[i].lastName<<"\n";
cout<<"Pet species: ";
animalSpecies entered;
entered = getAnimal();
print(entered);
cout<<"Pets DOB: ";
if (month<10)
{
cout<<"0"<<maxEntry[i].month<<"/"; //if month is less than 10 it will add a '0' in front
}
else
{
cout<<maxEntry[i].month<<"/";
}
if (day<10)
{
cout<<"0"<<maxEntry[i].day<<"/";
}
else
{
cout<<maxEntry[i].day<<"/";
}
cout<<maxEntry[i].year<<"\n";
menuInfo(maxEntry, counter); //goes back to the menu
}
}
/********************************************************************************************************/
void quitInfo(int& counter)
{
int ans;
do
{
cout<<"Are you sure you want to quit? (y/n)"<<endl;
cin>>ans;
if ((ans=='n') || (ans=='N'))
{
menuInfo(maxEntry, counter); //goes back to the menu function
}
else if ((ans=='y') || (ans=='Y'))
{
exit(0); //exits the program
}
else
{
cout<<"Error: Try again. "<<endl;
}
}
while (!(ans=='n') || !(ans=='N') || !(ans=='y') || !(ans=='Y'));
}
Issues I found in your code:
You have declared petDataInfo and displayInfo in two places, once inside the definition of animal and once in main.cpp. Looking at your code, I don't think you need them inside animal.
You are missing the type of counter in the definition of displayInfo.
void animal::displayInfo(animal maxEntry[], counter)
You need to add the type in that line. Also, since the function is not a member function of animal, it can be written as:
void displayInfo(animal maxEntry[], int& counter)
The type of counter is different in the declaration and the definition of petDataInfo. I the declaration, you are using int& counter. In the definition, you are using int counter. Make sure that they match. Also, the class scope can be removed from the definition since it's no longer a member function of animal.
void petDataInfo(animal maxEntry[], int& counter)
You are missing the object when trying to access the month and day. Change the line
if (month<10)
to
if (maxEntry[i].month<10)
and change
if (day<10)
to
if (maxEntry[i].day<10)
I haven't verified the logic of your program. If there are any, hopefully you can track and fix them.
my input file:
QT, Quan Tri, 4
KT, Kinh Te, 4
DT, Dien Tu, 5
MT, My Thuat, 4.5
NN, Ngoai Ngu, 4
my method:
void ReadFileDT(fstream &file)
{
char c;
CarneerDT dt;
int i=0;
int t=0;// position attributes
int k=0;
char number[10];
while(!file.eof())
{
c=file.get(); //get a letter in the file
//end of line processing
if(c=='\n')
{
break;
}
if(c!=',')
{
switch(t)
{
case 0: dt.id[i++]=c;break;
case 1: number[k++]=c;break;
case 2: number[k]=c;number[k+1]='\0';dt.year=atof(number);t++;break;
}
}
else
{
switch(t)
{
case 0:dt.id[i]='\0';break;
case 1:number[k]='\0';strcpy(dt.name,number); k=0;break;
}
t++;
}
}
cout<<endl;
XuatDT(dt);
}
void ReadAllDT(char *tenfile)
{
char c;
fstream file;
file.open("NganhDT.txt",ios::in);
if(file.fail())
{
cout<<"File Error!";
exit(1);
}
while(!file.eof())
{
ReadFileDT(file);
}
file.close();
}
it show "Run-Time Check Failure #2 - Stack around the variable 'number' was corrupted." and year always equal to 0.00000000000. Was I wrong in line:"case 2: number[k]=c;number[k+1]='\0';dt.year=atof(number);t++;break;"?
This code is structured slightly wrong
if(c!=',')
{
switch(t)
{
case 0: dt.id[i++]=c;break;
case 1: number[k++]=c;break;
case 2: number[k]=c;number[k+1]='\0';dt.year=atof(number);t++;break;
}
}
else
{
switch(t)
{
case 0:dt.id[i]='\0';break;
case 1:number[k]='\0';strcpy(dt.name,number); k=0;break;
}
t++;
}
it should be
if(c!=',')
{
switch(t)
{
case 0: dt.id[i++]=c;break;
case 1: number[k++]=c;break;
case 2: number[k++]=c;break;
}
}
else
{
switch(t)
{
case 0:dt.id[i]='\0';break;
case 1:number[k]='\0';strcpy(dt.name,number); k=0;break;
case 2: number[k]='\0';dt.year=atof(number); k=0;break;
}
t++;
}
But I must admit I don't immediately see why your code would lead to stack corruption.
How do I parse and evaluate expressions in an infix calculator grammar? I thought of two ways.
The 1st involves using two stacks. One is for numbers and the other is for operators, and I would assess the operator precedence and association in order to figure out how to evaluate an expression.
The second method involves converting the infix expression to postfix which I have no idea how I'd go about doing. It was just an idea. Currently I set up my program with the intention to use the 1st method.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
bool die(const string &msg);
//stack class
class Stack{
public:
Stack();
void push(const double &val);
void push(const string &oper);
double popnum();
string popop();
double getopele();
double getnumele();
private:
static const unsigned MAX=30;
string opstack[MAX];
double numstack[MAX];
unsigned opele;
unsigned numele;
};
//operator type
struct OP{
string name;
void * func;
unsigned arity;
unsigned prec;
bool lass;
string descrip;
};
//operator table
OP op[]={{"+", add, 2, 4, true, "2+3 is 5"},
{"-", subtract, 2, 4, true, "2-3 is -1"},
{"*", multiply, 2, 6, true, "2*3 is 6"},
{"/", divide, 2, 6, true, "2/3 is 0.666666..., div by 0 illegal"}};
unsigned OPELE =sizeof(op)/sizeof(op[0]);
//operators
bool add(double &r, double &x, double &y);
bool subtract(double &r, double &x, double &y);
bool multiply(double &r, double &x, double &y);
bool divide(double &r, double &x, double &y);
//Manip
unsigned findindex(string token, OP op[], unsigned OPELE);
bool parse(double &t, const string &token);
bool evaluate(double &result, string line);
bool weird(double x);
int main(){
for(string line; getline(cin, line);){
if(line=="QUIT") break;
if(line.empty()) continue;
if(line=="DOC")
for(unsigned i=0; i<OPELE; i++)
cout<<op[i].name<<" | "<<op[i].descrip<<'\n';
double result;
if(evaluate(result, line)){
cout<<result<<'\n';
}else{
cout<<"Could not understand input\n\n";
}
}
}
Stack::Stack(){
opele=0;
numele=0;
}
void Stack::push(const double &val){
if(MAX) die("Stack Overflow");
numstack[numele++]=val;
}
void Stack::push(const string &oper){
if(MAX) die("Stack Overflow");
opstack[opele++]=oper;
}
double Stack::popnum(){
if(!numele) die("Stack Underflow");
return numstack[--numele];
}
string Stack::popop(){
if(!opele) die("Stack Underflow");
return opstack[--opele];
}
double Stack::getopele(){
return opele;
}
double Stack::getnumele(){
return numele;
}
bool add(double &r, double &x, double &y){
double t = x + y;
if( weird(t) ) return false;
r = t;
return true;
}
bool subtract(double &r, double &x, double &y){
double t = x - y;
if( weird(t) ) return false;
result = t;
return true;
}
bool multiply( double & r, double& x, double &y ){
double t = x * y;
if( weird(t) ) return false;
result = t;
return true;
}
bool divide( double & result, double &x, double &y ){
double t = x / y;
if( weird(t) ) return false;
result = t;
return true;
}
unsigned findindex(string token, OP op[], unsigned OPELE){
for(unsigned i=0l i<OPELE; i++)
if(op[i].name==token)
return i;
return UINT_MAX;
}
bool parse(double &t, const string &token){
istringstream sin( token );
double t;
if( !(sin >>t) ) return false;
char junk;
if( sin >>junk ) return false;
value = t;
return true;
}
bool evaluate(double &result, string line){
istringstream sin(line);
Stack s;
for(string token; sin>>token;){
double t;
if(parse(t, token)){
s.push(t);
}else if(
}
}
bool weird( double x ){
return x != x || x != 0 && x == 2*x;
}
This will be a long read, but anyway, I will share with you the algorithm I use to parse an infix expression and store it as a binary tree. Not Stack, but binary tree. Parsing that will give the postfix order easily. I don't say this is the best algorithm out there, but this works for my scripting language.
The algorithm:
We have a method which operates on a "current node" of a binary tree and a "current expression". The nodes contain a "data" field and a "type" field.
Stage 1: Simple things, such as "4" go directly into the node, and we specify the type to be as "DATA", ie. use this information as it is.
Stage 2: Now, Let's consider the following expression:
a) 2 + 3
this will be transformed into the following binary tree:
+
/ \
2 3
So, the operators go into the nodes and the operands go into the leafs. Transofrming the expression a) into the tree is pretty simple: find the operator, put in the "current" node of the tree, specify the type of the node to be operator "PLUS", and what is left of it goes into the tree to the left part of the node, what is right of it goes into the right tree. Nice and simple, using the information from Stage 1 the two leafs will be "DATA" leafs with value 2 and 3.
Stage 3: But for a more complex expression:
b) 2 * 3 + 4
The tree will be:
+
/ \ 4
*
/ \
2 3
So we need to modify the algorithm above to the following: Find the first operator which has the highest precedence (considering c++ guidelines... precedence of + (plus) and - (minus) is 6, while precedence of * (multiply), / (divide) and % (modulo) is 5) in the expression, divide the expression into two parts (before operand with highest precedence and after operand with highest precedence) and call recursively the method for the two parts, while placing the operator with the highest precedence into the current node. So, we do create a tree wit hdata like:
+
/ \
/ call method with "4"
call method with "2*3"
and at this stage we fall back to "Stage 2" for the call ("2*3") and "Stage 1" for the call "4".
Stage 4: What if there are paranthesis in the expression? Such as
c) 2 * (3 + 4)
This will give us the tree:
*
/ \
2 +
/ \
3 4
We modify the algorithm to be like:
while the current expression is enclosed in a paranthesis remove the paranthesis from it and restart the algorithm. Be careful. (2 + 3 * 4 + 5) is considered to be enclosed in a parnethesis while (2+3)*(4+5) is NOT. So, it's not just the starting and ending characters of the expression, but you effectively need to count the parantheses. (this is a recursive method, don't be afraid of the first step...)
now find the first operator with the highest precedence outside the parantheses of the expression. Again, take the left and right sides of the expression and call the method again and again till you end up at "Stage 1" ie. with a single data element.
Now this is an algorithm for an expression which consists of plain numbers and operators. For more complex information you might need to refine it to suit your needs. If you consider it worth, take a look at https://sourceforge.net/p/nap-script/mercurial/ci/default/tree/compiler/interpreter.cpp . This contains a full implementation (in C) of the algorithm above with regard to more complex notions (variables, method calls, postfix/prefix operators, etc...) The method is build_expr_tree, starts at line 1327.
The method of recursive descent is the simplest way to implement a correct expression parser by hand. Here the programming language stack does the same thing as the explicit stack you're trying to use. There are many RD examples to be found with google, and any good compiler book will have some.
The linked Wikipedia page shows a parser, but not how to add evaluation. So below is a complete rudimentary expression evaluator in C. It could be easily wrapped in a C++ class with the globals becoming instance variables. It's missing features you'd need in a production system. For example, when it finds an error, it just exits. C++ exceptions will easily allow you to unwind the recursion and continue. It also needs protections against numerical overflow, divide-by-zero, etc., which you obviously know how to do.
The idea of recursive descent is to transform the grammar of the desired language into a form called LL(1). When that's done, there are fixed rules - guarenteed to work every time - for transforming the grammar rules into procedures. I've done this below by hand. There are tools to do it automatically.
So this evaluator is very easy to extend. Just add the necessary grammar rule, then implement the needed enhancements to scanner, parser, and evaluation code. For example, a built-in function rule would be unsigned_factor -> FUNCTION_NAME ( expr ), where the scanner recognizes all function names as the same token and the unsigned_factor C function is augmented to parse and compute values.
I had to include a small scanner to get a working program. Note more than half the code is the scanner. Basic RD parsers are simple.
They get more complex if you add error recovery: the intelligent ability to skip just past an error and continue parsing, while emitting only one precisely worded error message. But then again, this adds lots of complexity to any parser.
// Bare bones scanner and parser for the following LL(1) grammar:
// expr -> term { [+-] term } ; An expression is terms separated by add ops.
// term -> factor { [*/] factor } ; A term is factors separated by mul ops.
// factor -> unsigned_factor ; A signed factor is a factor,
// | - unsigned_factor ; possibly with leading minus sign
// unsigned_factor -> ( expr ) ; An unsigned factor is a parenthesized expression
// | NUMBER ; or a number
//
// The parser returns the floating point value of the expression.
#include <stdio.h>
#include <stdlib.h>
// The token buffer. We never check for overflow! Do so in production code.
char buf[1024];
int n = 0;
// The current character.
int ch;
// The look-ahead token. This is the 1 in LL(1).
enum { ADD_OP, MUL_OP, LEFT_PAREN, RIGHT_PAREN, NUMBER, END_INPUT } look_ahead;
// Forward declarations.
void init(void);
void advance(void);
double expr(void);
void error(char *msg);
// Parse expressions, one per line.
int main(void)
{
init();
while (1) {
double val = expr();
printf("val: %f\n", val);
if (look_ahead != END_INPUT) error("junk after expression");
advance(); // past end of input mark
}
return 0;
}
// Just die on any error.
void error(char *msg)
{
fprintf(stderr, "Error: %s. I quit.\n", msg);
exit(1);
}
// Buffer the current character and read a new one.
void read()
{
buf[n++] = ch;
buf[n] = '\0'; // Terminate the string.
ch = getchar();
}
// Ignore the current character.
void ignore()
{
ch = getchar();
}
// Reset the token buffer.
void reset()
{
n = 0;
buf[0] = '\0';
}
// The scanner. A tiny deterministic finite automaton.
int scan()
{
reset();
START:
switch (ch) {
case ' ': case '\t': case '\r':
ignore();
goto START;
case '-': case '+':
read();
return ADD_OP;
case '*': case '/':
read();
return MUL_OP;
case '(':
read();
return LEFT_PAREN;
case ')':
read();
return RIGHT_PAREN;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
read();
goto IN_LEADING_DIGITS;
case '\n':
ch = ' '; // delayed ignore()
return END_INPUT;
default:
error("bad character");
}
IN_LEADING_DIGITS:
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
read();
goto IN_LEADING_DIGITS;
case '.':
read();
goto IN_TRAILING_DIGITS;
default:
return NUMBER;
}
IN_TRAILING_DIGITS:
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
read();
goto IN_TRAILING_DIGITS;
default:
return NUMBER;
}
}
// To advance is just to replace the look-ahead.
void advance()
{
look_ahead = scan();
}
// Clear the token buffer and read the first look-ahead.
void init()
{
reset();
ignore(); // junk current character
advance();
}
double unsigned_factor()
{
double rtn = 0;
switch (look_ahead) {
case NUMBER:
sscanf(buf, "%lf", &rtn);
advance();
break;
case LEFT_PAREN:
advance();
rtn = expr();
if (look_ahead != RIGHT_PAREN) error("missing ')'");
advance();
break;
default:
error("unexpected token");
}
return rtn;
}
double factor()
{
double rtn = 0;
// If there is a leading minus...
if (look_ahead == ADD_OP && buf[0] == '-') {
advance();
rtn = -unsigned_factor();
}
else
rtn = unsigned_factor();
return rtn;
}
double term()
{
double rtn = factor();
while (look_ahead == MUL_OP) {
switch(buf[0]) {
case '*':
advance();
rtn *= factor();
break;
case '/':
advance();
rtn /= factor();
break;
}
}
return rtn;
}
double expr()
{
double rtn = term();
while (look_ahead == ADD_OP) {
switch(buf[0]) {
case '+':
advance();
rtn += term();
break;
case '-':
advance();
rtn -= term();
break;
}
}
return rtn;
}
And running the program:
1 + 2 * 3
val: 7.000000
(1 + 2) * 3
val: 9.000000
Here's the previous thread where I got help with this same lab. My stack is misbehaving, to say the least, when I add an item to stack, to print out later, it doesn't seem to add right. I always print out plus'(+), not matter if I enter another operand(*,/,+).
I am using a stack to convert a, user inputed, infix express to postfix. It seems to work fine except printing out the operands in the stack at the end.
#include <iostream>;
#include <vector>
using namespace std;
class DishWell{
public:
char ReturnFront(){
return Well.front();
}
void Push(char x){
Well.push_back(x);
}
void Pop(){
Well.pop_back();
}
bool IsEmpty(){
return Well.empty();
}
private:
vector<char> Well;
};
bool Precidence(char Input, char Stack){
int InputPrecidence,StackPrecidence;
switch (Input){
case '*':
InputPrecidence = 4;
break;
case '/':
InputPrecidence = 4;
break;
case '+':
InputPrecidence = 3;
break;
case '-':
InputPrecidence = 3;
break;
case '(':
InputPrecidence = 2;
break;
default:
InputPrecidence = 0;
}
switch (Stack){
case '*':
StackPrecidence = 4;
break;
case '/':
StackPrecidence = 4;
break;
case '+':
StackPrecidence = 3;
break;
case '-':
StackPrecidence = 3;
break;
case '(':
StackPrecidence = 2;
break;
default:
StackPrecidence = 0;
}
if(InputPrecidence>StackPrecidence) return true;
else return false;
}
int main(int argc, char** argv) {
DishWell DishTray;
char Input;
bool InputFlag;
InputFlag = true;
cout<<"Enter Input, invalid input will terminate"<<endl;
while(InputFlag){
cout<<"Input: ";
cin>>Input;
cout<<endl;
if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||Input>='0'&&Input<='9')))//If Digit or Number
cout<<Input;
if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand
if(DishTray.IsEmpty())
DishTray.Push(Input);
else if(Precidence(Input,DishTray.ReturnFront()))
DishTray.Push(Input);
else if(!Precidence(Input,DishTray.ReturnFront()))
cout<<"Output: "<<Input<<endl;
}
else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||(Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand
InputFlag = false;
}
int counter = 0;
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnFront()<<endl;
DishTray.Pop();
}
return 0;
Thank you, Macaire Bell
Your loop calls front(), but then calls pop_back(). This will always return the first element in the vector, until all elements are popped, since you are never erasing the front element. Your ReturnFront() method should probably be:
char ReturnBack(){
return Well.back();
}
And then your loop at the end:
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnBack()<<endl; // will return last element
DishTray.Pop(); // actually pop the element printed
}
When you're working with a stack, you usually want to be able to see the value on the top of the stack. Your class only allows the very first item pushed (i.e. the bottom of the stack) to be visible. Your ReturnFront() should probably return Well.back() and perhaps it should be called something like ReturnTop().
Wouldn't you want to see the value returned from pop_back() instead if discarding it as you're currently doing?