wrong output

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Oct 2005
Posts: 38
Reputation: btech is an unknown quantity at this point 
Solved Threads: 0
btech btech is offline Offline
Light Poster

wrong output

 
0
  #1
Dec 5th, 2005
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.

  1.  
  2. #ifndef H_stackType
  3. #define H_stackType
  4.  
  5. #include <iostream>
  6. #include <cassert>
  7.  
  8. using namespace std;
  9.  
  10. template<class Type>
  11. class stackType
  12. {
  13. public:
  14. void initializeStack();
  15. bool isEmptyStack();
  16. bool isFullStack();
  17. void push(const Type& newItem);
  18. Type top();
  19. void pop();
  20. stackType(int stackSize);
  21. ~stackType();
  22.  
  23. private:
  24. int maxStackSize;
  25. int stackTop;
  26. Type *list;
  27.  
  28. };
  29.  
  30. template<class Type>
  31. void stackType<Type>::initializeStack()
  32. {
  33. stackTop = 0;
  34. }
  35.  
  36. template<class Type>
  37. bool stackType<Type>::isEmptyStack()
  38. {
  39. return(stackTop == 0);
  40. }
  41.  
  42. template<class Type>
  43. bool stackType<Type>::isFullStack()
  44. {
  45. return(stackTop == maxStackSize);
  46. }
  47.  
  48. template<class Type>
  49. void stackType<Type>::push(const Type& newItem)
  50. {
  51. if(!isFullStack())
  52. {
  53. list[stackTop] = newItem;
  54. stackTop++;
  55. }
  56. else
  57. cerr<<"Cannot add to a full stack." << endl;
  58. }
  59.  
  60. template<class Type>
  61. Type stackType<Type>::top()
  62. {
  63. assert(stackTop != 0);
  64. return list[stackTop - 1];
  65. }
  66.  
  67. template<class Type>
  68. void stackType<Type>::pop()
  69. {
  70. if(!isEmptyStack())
  71. stackTop--;
  72. else
  73. cerr<<"Cannot remove from an empty stack."<<endl;
  74. }
  75.  
  76. template<class Type>
  77. stackType<Type>::stackType(int stackSize)
  78. {
  79. if(stackSize <= 0)
  80. {
  81. cerr<<"Size of the array to hold the stack must "
  82. <<"be positive."<<endl;
  83. cerr<<"Creating an array of size 50."<<endl;
  84.  
  85. maxStackSize = 50;
  86. }
  87. else
  88. maxStackSize = stackSize;
  89.  
  90. stackTop = 0;
  91. list = new Type[maxStackSize];
  92. assert(list != NULL);
  93. }
  94.  
  95. template<class Type>
  96. stackType<Type>::~stackType()
  97. {
  98. delete [] list;
  99. }
  100.  
  101. #endif
  102.  
  103. #include <iostream>
  104. #include <string>
  105. #include "stackType.h"
  106.  
  107. using namespace std;
  108.  
  109. string rpn(string infix);
  110.  
  111. int main()
  112. {
  113. string infix;
  114.  
  115. cout << "NOTE: Enter ! for infix expression to exit." << endl;
  116. for (;;)
  117. {
  118. cout << "Infix Expression? ";
  119. getline(cin, infix);
  120. if (infix == "!") break;
  121. cout << "RPN Expression is: " << rpn(infix) << endl;
  122. }
  123. return 0;
  124. }
  125.  
  126. string rpn(string infix)
  127. {
  128. char stackOpr;
  129. string RPNexp;
  130. const string BLANK = " ";
  131. stackType<char> stack(50);
  132. stack.initializeStack();
  133. for (unsigned i = 0; i < infix.length(); i++)
  134. {
  135. switch(infix[i])
  136. {
  137. case ' ' : break;
  138.  
  139. case '(' : stack.push(infix[i]);
  140. break;
  141.  
  142. case ')' : stackOpr = stack.top();
  143. stack.pop();
  144. if(!stack.isEmptyStack())
  145. {
  146. stackOpr = stack.top();
  147. stack.pop();
  148. }
  149. else
  150. break;
  151.  
  152. case '+' : case '-' :
  153. case '*' : case '/' :
  154. for (;;)
  155. {
  156. if (stack.isEmptyStack() ||
  157. stack.top() == '(' ||
  158. (infix[i] == '*' || infix[i] == '/') &&
  159. (stack.top() == '+' || stack.top() == '-')
  160. )
  161. {
  162. stack.push(infix[i]);
  163. break;
  164. }
  165. else
  166. {
  167. stackOpr = stack.top();
  168. stack.pop();
  169. }
  170. }
  171. break;
  172.  
  173. default : RPNexp.append(BLANK + stackOpr);
  174. }
  175.  
  176. }
  177.  
  178. for (;;)
  179. {
  180. if (stack.isEmptyStack()) break;
  181.  
  182. stackOpr = stack.top();
  183. stack.pop();
  184. if (stackOpr != '(')
  185. {
  186. RPNexp.append(BLANK + stackOpr);
  187. }
  188. else
  189. {
  190. cout << " *** Error in infix expression ***\n";
  191. break;
  192. }
  193. }
  194. return RPNexp;
  195. }
Reply With Quote Quick reply to this message  
Join Date: Nov 2005
Posts: 78
Reputation: perniciosus is an unknown quantity at this point 
Solved Threads: 4
perniciosus's Avatar
perniciosus perniciosus is offline Offline
Junior Poster in Training

Re: wrong output

 
0
  #2
Dec 5th, 2005
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...

  1. ~.l
  2. - { return ADD }
  3. + { return SUB }
  4. / { return DIV }
  5. * { return MUL }
  6. ( { return LEFT }
  7. ) { return RIGHT }
  8. [0-9]\.?[0-9]* { yyval = $1 /* ??? */ ; return NUM ; }
  9. . { }
  10.  
  11. ~.y
  12. // setup code
  13. LINE = EXPR { print( $1 ) ; }
  14. EXPR = EXPR DIV EXPR { $$ = $1 + ' ' + $3 + ' ' + $2 ; }
  15. | EXPR MUL EXPR { $$.left = $1 ; $$.op = MUL ; $$.right = $2 ; }
  16. | TERM { $$ = $1 ; }
  17. TERM = TERM SUB EXPR { $$ = $1 + ' ' + $3 + ' ' + $2 ; }
  18. TERM = LEFT EXPR RIGHT { $$ = " ( " + $2 + " ) " ; }
  19. TERM = NUM { $$ = $1 ; }
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)...
/pern.*/i

Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Reply With Quote Quick reply to this message  
Join Date: Oct 2005
Posts: 38
Reputation: btech is an unknown quantity at this point 
Solved Threads: 0
btech btech is offline Offline
Light Poster

Re: wrong output

 
0
  #3
Dec 5th, 2005
This is a homework assignment and since we have never used yacc and bison I do not think I should do that for this assignment. I do thank you for your response though. What I need is to figure out why my alpha characters are not being outputed.
Reply With Quote Quick reply to this message  
Join Date: Nov 2005
Posts: 78
Reputation: perniciosus is an unknown quantity at this point 
Solved Threads: 4
perniciosus's Avatar
perniciosus perniciosus is offline Offline
Junior Poster in Training

Re: wrong output

 
0
  #4
Dec 5th, 2005
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
Reply With Quote Quick reply to this message  
Join Date: Oct 2005
Posts: 38
Reputation: btech is an unknown quantity at this point 
Solved Threads: 0
btech btech is offline Offline
Light Poster

Re: wrong output

 
0
  #5
Dec 5th, 2005
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...
so how can i fix this?
Reply With Quote Quick reply to this message  
Join Date: Nov 2005
Posts: 78
Reputation: perniciosus is an unknown quantity at this point 
Solved Threads: 4
perniciosus's Avatar
perniciosus perniciosus is offline Offline
Junior Poster in Training

Re: wrong output

 
0
  #6
Dec 5th, 2005
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
  1. case '0': case '1': case '2': case '3': case '4':
  2. case '5': case '6': case '7': case '8': case '9':
  3. // handle numbers here, perhaps like this
  4. RPNexp.append( infix[i] ) ;
  5. // or char buf[2] ; buf[0] = infix[ i ] ; buf[1] = 0 ; RPNexp.append(buf)
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.
/pern.*/i

Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 5,264
Reputation: iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold iamthwee is a splendid one to behold 
Solved Threads: 377
Featured Poster
iamthwee's Avatar
iamthwee iamthwee is offline Offline
Posting Expert

Re: wrong output

 
0
  #7
Dec 5th, 2005
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
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?

*Voted best profile in the world*
Reply With Quote Quick reply to this message  
Join Date: Nov 2005
Posts: 78
Reputation: perniciosus is an unknown quantity at this point 
Solved Threads: 4
perniciosus's Avatar
perniciosus perniciosus is offline Offline
Junior Poster in Training

Re: wrong output

 
0
  #8
Dec 5th, 2005
Thoughts:
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?
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...
/pern.*/i

Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. Albert Einstein
Reply With Quote Quick reply to this message  
Join Date: Oct 2005
Posts: 38
Reputation: btech is an unknown quantity at this point 
Solved Threads: 0
btech btech is offline Offline
Light Poster

Re: wrong output

 
0
  #9
Dec 5th, 2005
Originally Posted by perniciosus
Thoughts:
case ')': Should probably output all ops untill a '(' is found on the stack.
This is exactly what i am looking to do below is the algorithm for this assignment. I think I am on the right path just a little lost. Please help me figure out tje next step.

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.
Reply With Quote Quick reply to this message  
Join Date: Oct 2005
Posts: 38
Reputation: btech is an unknown quantity at this point 
Solved Threads: 0
btech btech is offline Offline
Light Poster

Re: wrong output

 
0
  #10
Dec 5th, 2005
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

  1. #include <iostream>
  2. #include <string>
  3. #include "stackType.h"
  4.  
  5. using namespace std;
  6.  
  7. int precedence (char x );
  8. string rpn(string infix);
  9.  
  10. int main()
  11. {
  12. string infix;
  13.  
  14. cout << "Note: Enter ! for infix expression to exit." << endl;
  15. for (;;)
  16. {
  17. cout << "Infix Expression? ";
  18. getline(cin, infix);
  19. if (infix == "!") break;
  20. cout << "RPN Expression is: " << rpn(infix) << endl;
  21. }
  22. return 0;
  23. }
  24.  
  25. int precedence (char x )
  26. {
  27. switch ( x ) {
  28. case '+':
  29. case '-':
  30. return 1;
  31. case '*':
  32. case '/':
  33. return 2;
  34. }
  35. return 0;
  36. }
  37.  
  38. string rpn(string infix)
  39. {
  40. string rpnExp;
  41. stackType<char> stack;
  42.  
  43. for (unsigned i = 0; i < infix.length(); i++)
  44. {
  45. switch(infix[i])
  46. {
  47. case ' ' : break;
  48.  
  49. case '(' : stack.push(infix[i]);
  50. break;
  51.  
  52. case ')' : while ( stack.top() != '(' ){
  53. rpnExp += stack.top();
  54. stack.pop();
  55. }
  56. stack.pop();
  57. break;
  58. default :
  59. while ( !stack.isEmptyStack() && precedence( infix[i]) <= precedence( stack.top() ) ){
  60. rpnExp += stack.top();
  61. stack.pop();
  62. }
  63. stack.push( infix[i] );
  64. }
  65. }
  66.  
  67. while ( !stack.isEmptyStack() ) {
  68. rpnExp += stack.top();
  69. stack.pop();
  70. }
  71.  
  72. return rpnExp;
  73. }
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC