trouble with for and stacks

Having a bit of trouble with my for loop putting the information in the stacks. One stack is for characters the other is for integers.

Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int Calculator::calculate ()
{
   cout << "Please enter an expression: " << endl;
   getline (cin,expression);
   cout << "Your expression is: " << expression << endl;
   cout << "The length of your expression " << expression.length() << endl;
   int i = 0;
   for(i; i <= expression.length(); i++)
   {
      cout << "i = " << i << endl;
      char op = expression[i];
      cout << "Is operator: " << isOperator(op) << endl;
      if(isOperator(op)== true)// if b
      {
         operators.push(op);
         cout << "operators stack: " << operators.peek() << endl;
      }//end if b
      else 
      {
         int tempOp = getOperand(i);
         operands.push(tempOp);
         cout << "operands stack: " << operands.peek() << endl;
      }//end else
   }//end for
}//end calculate() 


Here is the output I'm getting:
Please enter an expression:
2+4/2
Your expression is: 2+4/2
The length of your expression 5
i = 0
Is operator: 0
operands stack: 2
i = 2
Is operator: 0
operands stack: 4
i = 4
Is operator: 0
operands stack: 2
Could you please post the rest of the code?
I was provided the .h file and the main calls the calculate method but is required to be in it's own .cpp. I have tried everything I can think of but I can't get the operators to go into the operator stack.
Once they are in the stack, I have to check precedence each time I get a new operator and if the precedence is greater perform the operation and put the answer back on the operands stack.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <cstdlib>
#include <iostream>
#include "Calculator.h"

void Calculator::processOperator ()
{
   int temp;
   char op = operators.peek();

   if(!operators.isEmpty() && (higherPrecedence(op)== true))
   {
      int x = operands.peek();
      operands.pop();
      int y = operands.peek();
      operands.pop();
      operators.pop();
      switch (op)
      {
         case '+': temp = x + y;
            break;
         case '-': temp = x - y;
            break;
         case '*': temp = x * y;
            break;
         case '/': temp = x / y;
            break;
         default: cout << "Invalid operator, press any key to terminate.";
      }//end switch
      operands.push(temp);
   }//end if
}//end processOperator()


bool Calculator::higherPrecedence(char op)
{
   if(op >= operators.peek())
   { 
      return true;
   }// end if
   else
   {
      return false;
   }//end else
}//end higherPrecedence()
   

int Calculator::calculate ()
{
   cout << "Please enter an expression: " << endl;
   cin >> expression;
   cout << "Your expression is: " << expression << endl;
   cout << "The length of your expression " << expression.length() << endl;
   int i = 0;
   for(i; i <= expression.length(); i++)
   {
      char op = expression[i];
      if(isOperator(op)== true)// if b
      {
         if(!operators.isEmpty())
         {
         processOperator();
         }
         else
         {
         char tempChar = expression[i];
         operators.push(tempChar);
         cout << "operators stack: " << operators.peek() << endl;
         }
      }//end if b
      else 
      {
         int tempOp = getOperand(i);
         operands.push(tempOp);
         cout << "operands stack: " << operands.peek() << endl;
      }//end else
      isOperator(op);
   }//end for
}//end calculate() 
Last edited on
Thank you.

These are much easier to troubleshoot if we have "all" the code because there are many functions and variables being referenced in calculate that were defined outside the function.

I would like to see the header file class as that is where the Operators and Operands stacks are defined as well as your getters and setters.
Here is the Calculator.h file. I cannot change this file in any way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <string>
#include "ArrayStack.h"
using namespace std;

class Calculator
{
private:
   /**
    * stores the operands (the numbers) in the arithmetic expression while the 
    * expression is being evaluated
    */
   ArrayStack<int> operands; 

   /**
    * stores the operators in the arithmetic expression while the expression is
    * being evaluated
    * 
    */
   ArrayStack<char> operators; 

   /**
    * original arithmetic expression
    */
   string expression;

   /**
    * Determines if the character argument is one of the 4 valid operators: +, -.
    * *, or /.
    * @param ch - character to examine to determine if it is a valid operator
    * @return true if the argument is a valid operator, false otherwise
    */
   bool isOperator (char ch)
   {
      return (ch == '+' || ch == '*' || ch == '-' || ch == '/');
   }


   /**
    * Beginning at location index in the expression, collects all the digits in
    * the operand, stopping when a non-digit character is encountered. Converts
    * the digits in the operand to an integer.
    * @param index - location in expression of first character in the operand
    * @return operand's integer value
    */
   int getOperand (int &index)
   {
      int operand = 0;
      while (index < expression.length() && isdigit(expression[index]))
      {
         operand = (operand * 10) + (expression[index] - '0');
         index++;
      }
      return operand;
   }


   /**
    * Processes the top operator on the operators stack by removing 2 operands
    * from the operands stack and one operator from the operators stack. Performs
    * the designated calculation and pushes the result back onto the operands 
    * stack. Checks to be certain the stacks are not empty before attempting to
    * remove items from them.
    */
   void processOperator ();

   /**
    * Determines if the argument has a higher precedence than the operator 
    * currently on top of the operators stack.
    * @param op - operator being compared to the one on top of the operators stack
    * @return - true if op has a higher precedence than the one on top of the 
    *           operators stack; false otherwise
    */
   bool higherPrecedence(char op);
public:
   /**
    * Default constructor. Initializes expression to an empty string.
    */
   Calculator () 
   {
      expression = "";
   }


   /**
    * Overloaded constructor that initializes arithmetic expression.
    * @param - newExpression - value to use to initialize arithmetic expression
    */
   Calculator (string newExpression) 
   {
      expression = newExpression;
   }
   
   /**
    * Evaluates the arithmetic expression and returns the result, following all
    * the precedence rules for the 4 allowed operators: =, -, *, and /
    * @return result of calculation for arithmetic expression
    */
   int calculate (); 
};

Last edited on
So because the getOperand() method has index++ I need to use a while statement instead of the for loop, but when I try to implement the while loop I just get an infinite loop. Please help!!
Sorry I'm at work and it just got a little busy. I still don't have access to the ArrayStack class or your main file. However, I went ahead an implemented a predefined stack operation which has slightly different methods but I believe it works how you're describing it.

The problem with the while loop you created (or at least with the code i'm assuming you created) is most likely that you did not add an i++ under the "if" condition. It will increment when it hits the else statement because getOperand is called but it is not called in the if. Additionally, your check statement will need to be i < expression not i <= expression.

Other than that, everything looks alright. When implementing a stack I was able to make the following function work correctly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void Calculator::calculate ()
{
   cout << "Please enter an expression: " << endl;
   cin>> expression;
   cout << "Your expression is: " << expression << endl;
   cout << "The length of your expression " << expression.length() << endl;
   int i=0;
   while (i < expression.length()) //< instead of <=
   {
      char op = expression[i];
	
      if(isOperator(op)== true)// if b
      {
         if(!operators.empty())
         {
         processOperator();
         }
         else
         {
         char tempChar = expression[i];
         operators.push(tempChar);
         cout << "operators stack: " << operators.top() << endl;
	    
         }
	    i++; //MUST ADD THIS or loop will be infinite
      }//end if b
      else 
      {
         int tempOp = getOperand(i); //this acts as an i++ as well
         operands.push(tempOp);
         cout << "operands stack: " << operands.top() << endl;
      }//end else
       isOperator(op);
   }//end for
}//end calculate() 


You'll have to change some of the methods to that which is in the ArrayStack header file that I do not have access to. (For example, .empty() will be IsEmpty() and .top will be .peek and ect).
Last edited on
Topic archived. No new replies allowed.