| | |
wrong output
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Oct 2005
Posts: 38
Reputation:
Solved Threads: 0
The code below compiles but produces the wrong output. The code is supposed to convert an infix string to postfix. the current output is only the arithmetic operator, unless there are parenthesis then it will only show the right parenthesis. I have been woking on this for hours and am getting nowhere. Please help.
C++ Syntax (Toggle Plain Text)
#ifndef H_stackType #define H_stackType #include <iostream> #include <cassert> using namespace std; template<class Type> class stackType { public: void initializeStack(); bool isEmptyStack(); bool isFullStack(); void push(const Type& newItem); Type top(); void pop(); stackType(int stackSize); ~stackType(); private: int maxStackSize; int stackTop; Type *list; }; template<class Type> void stackType<Type>::initializeStack() { stackTop = 0; } template<class Type> bool stackType<Type>::isEmptyStack() { return(stackTop == 0); } template<class Type> bool stackType<Type>::isFullStack() { return(stackTop == maxStackSize); } template<class Type> void stackType<Type>::push(const Type& newItem) { if(!isFullStack()) { list[stackTop] = newItem; stackTop++; } else cerr<<"Cannot add to a full stack." << endl; } template<class Type> Type stackType<Type>::top() { assert(stackTop != 0); return list[stackTop - 1]; } template<class Type> void stackType<Type>::pop() { if(!isEmptyStack()) stackTop--; else cerr<<"Cannot remove from an empty stack."<<endl; } template<class Type> stackType<Type>::stackType(int stackSize) { if(stackSize <= 0) { cerr<<"Size of the array to hold the stack must " <<"be positive."<<endl; cerr<<"Creating an array of size 50."<<endl; maxStackSize = 50; } else maxStackSize = stackSize; stackTop = 0; list = new Type[maxStackSize]; assert(list != NULL); } template<class Type> stackType<Type>::~stackType() { delete [] list; } #endif #include <iostream> #include <string> #include "stackType.h" using namespace std; string rpn(string infix); int main() { string infix; cout << "NOTE: Enter ! for infix expression to exit." << endl; for (;;) { cout << "Infix Expression? "; getline(cin, infix); if (infix == "!") break; cout << "RPN Expression is: " << rpn(infix) << endl; } return 0; } string rpn(string infix) { char stackOpr; string RPNexp; const string BLANK = " "; stackType<char> stack(50); stack.initializeStack(); for (unsigned i = 0; i < infix.length(); i++) { switch(infix[i]) { case ' ' : break; case '(' : stack.push(infix[i]); break; case ')' : stackOpr = stack.top(); stack.pop(); if(!stack.isEmptyStack()) { stackOpr = stack.top(); stack.pop(); } else break; case '+' : case '-' : case '*' : case '/' : for (;;) { if (stack.isEmptyStack() || stack.top() == '(' || (infix[i] == '*' || infix[i] == '/') && (stack.top() == '+' || stack.top() == '-') ) { stack.push(infix[i]); break; } else { stackOpr = stack.top(); stack.pop(); } } break; default : RPNexp.append(BLANK + stackOpr); } } for (;;) { if (stack.isEmptyStack()) break; stackOpr = stack.top(); stack.pop(); if (stackOpr != '(') { RPNexp.append(BLANK + stackOpr); } else { cout << " *** Error in infix expression ***\n"; break; } } return RPNexp; }
These things are more easily done using yacc and bison... I have a vague recollection about some statements of implementability of these types of grammar on a stack based machine so I suppose it should be possible... You probably want to save full tokens on the stack instead of just characters thought, thats what you got yacc for but it can easily be done manually thought... Damn it, you don't construct these adlib, try the recursive method first it tends to beasier to think that way, then if you need the stack based solution think about what you use the stack for there (It should result in a proper stack finite state machine, I have seen it somewhere I think)... The proper solution ofcourse would be to construct the finite state machine from the grammar by hand and then write the machine from that (if you have please post) or just use yacc/bison and let it do it for you...
Well my grammar is a little rustly... I usually just run it through till the result is what I would expect (and this has not been tested what so ever)...
C++ Syntax (Toggle Plain Text)
~.l - { return ADD } + { return SUB } / { return DIV } * { return MUL } ( { return LEFT } ) { return RIGHT } [0-9]\.?[0-9]* { yyval = $1 /* ??? */ ; return NUM ; } . { } ~.y // setup code LINE = EXPR { print( $1 ) ; } EXPR = EXPR DIV EXPR { $$ = $1 + ' ' + $3 + ' ' + $2 ; } | EXPR MUL EXPR { $$.left = $1 ; $$.op = MUL ; $$.right = $2 ; } | TERM { $$ = $1 ; } TERM = TERM SUB EXPR { $$ = $1 + ' ' + $3 + ' ' + $2 ; } TERM = LEFT EXPR RIGHT { $$ = " ( " + $2 + " ) " ; } TERM = NUM { $$ = $1 ; }
/pern.*/i
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Well it does not output numbers since you dont print them (obviously) currently whenever a number is encountered the switch statement will fall through to the output stackopt statement producing the last encountered stackop instead of the current number...
/pern.*/i
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
•
•
Join Date: Oct 2005
Posts: 38
Reputation:
Solved Threads: 0
•
•
•
•
Originally Posted by perniciosus
Well it does not output numbers since you dont print them (obviously) currently whenever a number is encountered the switch statement will fall through to the output stackopt statement producing the last encountered stackop instead of the current number...
Well I have been thinking about this one, I _could_ make a full parser (which would essentially parse the full expression tree and the spit it out after some tinkering)... however this solution you are thinking about may very well work since you only need to move the operator to the back...
practically you can put
As long as you can guarantee the operators come in the right order this _could_ produce correct results (I have yet to figure out a example which would require relocation of number tokens, but that does not mean it does not exist)...
I imagine you have to be explicit about operator precedence
(consider 2+2*2 = 2 (2 2 *) +, but then again I'm not sure I am all into postfix
syntax, 2 2 2 * + might be a valid line aswell, it would still require modification so
that * is put before + when seen next to it in the stack, or so it feels anyway.
*Edit) I believe that is what you are trying to do in your +-*/ case, but it looks a little off... once you get it running thought you should be able to see if it works or not.
practically you can put
C++ Syntax (Toggle Plain Text)
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // handle numbers here, perhaps like this RPNexp.append( infix[i] ) ; // or char buf[2] ; buf[0] = infix[ i ] ; buf[1] = 0 ; RPNexp.append(buf)
I imagine you have to be explicit about operator precedence
(consider 2+2*2 = 2 (2 2 *) +, but then again I'm not sure I am all into postfix
syntax, 2 2 2 * + might be a valid line aswell, it would still require modification so
that * is put before + when seen next to it in the stack, or so it feels anyway.
*Edit) I believe that is what you are trying to do in your +-*/ case, but it looks a little off... once you get it running thought you should be able to see if it works or not.
/pern.*/i
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
•
•
•
•
Well I have been thinking about this one, I _could_ make a full parser (which would essentially parse the full expression tree and the spit it out after some tinkering
So this is wat i wud do. It can't be that hard to make a tree can it?
*Voted best profile in the world*
Thoughts:
The Big if statement on operators should probably be broken up, empty and '(' cases looks correct, but precedence rules should probably be something like
since all operators but + has precedence over + and similary for other ones (you need to tell me if I have understood this part of the code right thought).
I dont really get the need to store stackOpr and output it on default, it makes little sence to me (feel free to elaborate).
Nope, once you've done it it feels like the most natural way to do parsing
A shorter step might be to do it recursivly, that is rather intuative, probably the first thing I would have done (before seeing the beauty of syntax trees), let the compiler handle the stack for you... thought since you were using a stack i guessed it was part of the assignment...
case ')': Should probably output all ops untill a '(' is found on the stack.The Big if statement on operators should probably be broken up, empty and '(' cases looks correct, but precedence rules should probably be something like
(infix[i] == '+' && stack.top() != '+') for +since all operators but + has precedence over + and similary for other ones (you need to tell me if I have understood this part of the code right thought).
I dont really get the need to store stackOpr and output it on default, it makes little sence to me (feel free to elaborate).
•
•
•
•
Yes i wud forget your method. It may not work. if u use an expression tree it will like perniciosus said.
So this is wat i wud do. It can't be that hard to make a tree can it?
A shorter step might be to do it recursivly, that is rather intuative, probably the first thing I would have done (before seeing the beauty of syntax trees), let the compiler handle the stack for you... thought since you were using a stack i guessed it was part of the assignment... /pern.*/i
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
•
•
Join Date: Oct 2005
Posts: 38
Reputation:
Solved Threads: 0
•
•
•
•
Originally Posted by perniciosus
Thoughts:
case ')':Should probably output all ops untill a'('is found on the stack.
Note: Uses a stack to store operators.
1. Initialize an empty stack of operators.
2. While no error has occurred and the end of the infix expression has not been reached, do the following:
a. Get the next input token (constant, variable, arithmetic operator, left parenthesis, right parenthesis) in the infix expression.
b. If token is
i. a left parenthesis: Push it onto the stack.
ii. a right parenthesis: Pop and display stack elements until a left parenthesis is encountered, but do not display it. (It is an error if the stack becomes empty with no left parenthesis found.)
iii. an operator: If the stack is empty or token has a higher priority than the top stack element, push token onto the stack.
Otherwise, pop and display the top stack element: then repeat the comparison of token with the new top stack item.
Note: A left parenthesis in the stack is assumed to have a lower priority than that of operators
iv. an operand: Display it.
3. When the end of the infix expression is reached, pop and display stack items until the stack is empty.
•
•
Join Date: Oct 2005
Posts: 38
Reputation:
Solved Threads: 0
made a few changes now the program outputs in prefix (i need postfix) and crashes if i use parenthesis? can someone look at the code and tell me what i am doing wrong? same .h file posted above
C++ Syntax (Toggle Plain Text)
#include <iostream> #include <string> #include "stackType.h" using namespace std; int precedence (char x ); string rpn(string infix); int main() { string infix; cout << "Note: Enter ! for infix expression to exit." << endl; for (;;) { cout << "Infix Expression? "; getline(cin, infix); if (infix == "!") break; cout << "RPN Expression is: " << rpn(infix) << endl; } return 0; } int precedence (char x ) { switch ( x ) { case '+': case '-': return 1; case '*': case '/': return 2; } return 0; } string rpn(string infix) { string rpnExp; stackType<char> stack; for (unsigned i = 0; i < infix.length(); i++) { switch(infix[i]) { case ' ' : break; case '(' : stack.push(infix[i]); break; case ')' : while ( stack.top() != '(' ){ rpnExp += stack.top(); stack.pop(); } stack.pop(); break; default : while ( !stack.isEmptyStack() && precedence( infix[i]) <= precedence( stack.top() ) ){ rpnExp += stack.top(); stack.pop(); } stack.push( infix[i] ); } } while ( !stack.isEmptyStack() ) { rpnExp += stack.top(); stack.pop(); } return rpnExp; }
![]() |
Similar Threads
- Boot up problem (Windows NT / 2000 / XP)
- wrong output , but i am sure that code is correct (Assembly)
- wrong output in c program (C++)
Other Threads in the C++ Forum
- Previous Thread: C++ Errors Pls Help!!
- Next Thread: help!
| Thread Tools | Search this Thread |
api array based beginner binary bitmap c++ c/c++ calculator char char* class code coding compile compiler console conversion count database delete deploy desktop developer dll download dynamic dynamiccharacterarray email encryption error file forms fstream function functions game givemetehcodez google graph gui homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib linkedlist linker list loop looping loops map math memory multiple news node number numbertoword output parameter pointer problem program programming project python random read recursion recursive reference rpg sorting string strings struct temperature template test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






