Help with my RPN calculator using c++ #include <stack>

Jan 2, 2012 at 10:57am
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
#include <iostream>
#include <stack>
 
 
void calculation(int, int, char);
using namespace std;
stack<int> a;
 
void main(void)
{
     
    bool expression = false;
    char ch;
    char done;
     
    int op1, op2;
 
    cout << "Reverse Polish Notation : " << endl;
    cout << "Enter expression: " << endl;
    while (!expression)
    {
        cin >> op1;
        cin >> op2;
        cin >> ch;
         
        calculation(op1, op2, ch);
        if (!cin)
            expression = false;
        else
        {
            expression = true;
            calculation(op1, op2, ch);
        }
    }
    cout << "Your expression is " <<  a.top() << endl;
    system ("pause");
}
 
void calculation(int oper1, int oper2, char chr)
{
    switch (chr)
    {
        case '+':
            a.push(oper1 + oper2);
            break;
        case '-':
            a.push(oper1 - oper2);
            break;
        case '*':
            a.push(oper1 * oper2);
            break;
        case '/':
            a.push(oper1 / oper2);
            break;
         
    }
}


latest code: I still cant figure out what should I do.I want to make it like the function would do the calculations for every numbers that was pushed. Still, i manage to solve it with only 2 operands and 1 operator. How to do it when I want to have more than 3 operands and the function to check all the calculation. No error checking required.

If i try to add more than 2 numbers(eg, 3 numbers with 2 operands), the function would only calculate the first 2 operands and the operator(No error in program). Not sure how to do on the subsequent operands and operators
Last edited on Jan 2, 2012 at 10:59am
Jan 2, 2012 at 11:06am
You always push the arguments then apply the operator when you pop. You're cheating.

For example:
2 3 4 + *

push 2
push 3
push 4
pop (4)
pop (3)
add (7)
pop (2)
multiply (14)
Jan 2, 2012 at 11:12am
Because i dun know how to do. Give me some tips
Jan 2, 2012 at 11:14am
I just gave you an example.
Jan 2, 2012 at 11:18am
closed account (o1vk4iN6)
You could read input by lines, loop through the string using find_first_of and find_first_not_of to find operators. You'd than need to use a stringstream to convert it into an int. This is only a suggestion.

What you'd want to do than is push any values you read onto the stack, than whenever you read an operator, pop the last two values off the stack, compute and push the resultant back onto the stack. At the end you should have only 1 value left in the stack if the input follows RPN.
Jan 2, 2012 at 11:30am
I want to make it like the functions would calculate all of the operands regardless of any number input. Since i need 2 vairables for calculation, i have to declare 2 variables. Right now, i already confused how to implement the algorithm such that the function would do the counting, the number or charcter to be input would be calculated by the function regardless the amount of operators and operands. Anyway, my program do not need to check error checking.
Jan 2, 2012 at 11:33am
if i try to code the calculation function into pop instead of using push, i cant add, substract the variables since the stack pop fucntion take no argument. So, i have to use push. Seriously, give me some tips. I already tried 4 hours but still cant do. Where is the specify code I had done wrong.
Last edited on Jan 2, 2012 at 11:34am
Jan 2, 2012 at 11:40am
closed account (o1vk4iN6)
You need to use top() first to view the variable, than pop() to remove it from the stack. It's a shame that pop() doesn't return the value but I guess it's for efficiency.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

int calc (int op1, int op2, char expr); // can prob use templating here instead incase you want to change the type after

stack<int> values;
int a, b;

b = values.top();
values.pop();

a = values.top();
values.pop();

values.push( calc( a, b, expr ) );
Jan 2, 2012 at 11:54am
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
#include <iostream>
#include <stack>


void calculation(int, int, char);
using namespace std;
stack<int> a;

void main(void)
{
	
	bool expression = false;
	char ch;
	char done;
	int op1, op2;

	

	
	cout << "Reverse Polish Notation : " << endl;
	cout << "Enter expression: " << endl;
	while (!expression)
	{
		cin >> op1;
		op1 = a.top();
		a.pop();
		cin >> op2;
		op2 = a.top();
		a.pop();
		cin >> ch;
		
		a.push( calculation( op1, op2, ch ) ); //error doing this
		if (!cin)
			expression = false;
		else
		{
			expression = true;
			//cin >> op1;
			//cin >> op2;
			//cin >> ch;
			//calculation(op1, op2, ch);
		}
	}
	cout << "Your expression is " <<  a.top() << endl;
	system ("pause");
}

void calculation(int oper1, int oper2, char chr)
{
	switch (chr)
	{
		case '+':
			a.push(oper1 + oper2);
			break;
		case '-':
			a.push(oper1 - oper2);
			break;
		case '*':
			a.push(oper1 * oper2);
			break;
		case '/':
			a.push(oper1 / oper2);
			break;
		
	}
}


I got error if trying to write for the function porotypes. Anyway anything wrong with my function body inside the function.
Jan 2, 2012 at 12:03pm
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
#include <iostream>
#include <stack>

template <class Type>
Type calculation(Type oper1, Type oper2, Type chr);
using namespace std;
stack<int> a;

void main(void)
{
	
	bool expression = false;
	char ch;
	char done;
	int op1, op2;

	

	
	cout << "Reverse Polish Notation : " << endl;
	cout << "Enter expression: " << endl;
	while (!expression)
	{
		cin >> op1;
		op1 = a.top();
		a.pop();
		cin >> op2;
		op2 = a.top();
		a.pop();
		cin >> ch;
		
		a.push( calculation( op1, op2, ch ) ); //error doing this
		if (!cin)
			expression = false;
		else
		{
			expression = true;
			//cin >> op1;
			//cin >> op2;
			//cin >> ch;
			//calculation(op1, op2, ch);
		}
	}
	cout << "Your expression is " <<  a.top() << endl;
	system ("pause");
}
template <class Type>
void calculation(Type oper1, Type oper2, Type chr)
{
	switch (chr)
	{
		case '+':
			a.push(oper1 + oper2);
			break;
		case '-':
			a.push(oper1 - oper2);
			break;
		case '*':
			a.push(oper1 * oper2);
			break;
		case '/':
			a.push(oper1 / oper2);
			break;
		
	}
}


Latest code using templates. Error in line 32 and line 5
Last edited on Jan 2, 2012 at 12:03pm
Jan 2, 2012 at 12:04pm
closed account (o1vk4iN6)
The reason your program isn't working the way it is is because you aren't reading the input correctly.

Think about this, right now it's hard coded to read 2 ints and 1 operator so if you have this input:

1 1 1 + +

It'll read, 1 -> op1, 1 -> op2 and 1 -> ch.

You need to change the method in which you read input from.

Also you shouldn't be using a global variable like you have, you can easily use it as a local variable, which makes your calculation function look more like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int // change output type
calculation(int oper1, int oper2, char chr)
{
	switch (chr)
	{
		case '+':
			return oper1 + oper2;
		case '-':
			return oper1 - oper2;
		case '*':
			return oper1 * oper2;
		case '/':
			return oper1 / oper2;
		default: cerr << "undefined behavor\n";
                         break;
	}
}


If you don't understand and you've spend 4 hours without figuring something like this out, you should probably start with something a bit simpler and work your way up. Right now it seems your problem is you don't know how to get input the way you need it to. You can't assume that it'll be 2 ints followed by an expression unless you are telling the user to input only a single operation.
Last edited on Jan 2, 2012 at 12:05pm
Jan 2, 2012 at 12:20pm
So, should I use templates instead. Because my program do not required error checking in my assignment, so I assume all of the number, ooperator input by the user is correct.

I know this problem but not sure how should I changed it such that the input accept charcters and integers together. This is my biggest problem that stuck me for several hours.Not sure if templates work. Should i change my functions or data typs into templates. As for global variables, if i declare it in local variables, the a.push in the function body of the calculation would be undeclared. So, no choice, i had to let it become global variables.

And i cant just code what you wrote in the function. I need to pop the any 2 numbers to do the calculation and I cant just return the amount only.
Last edited on Jan 2, 2012 at 12:31pm
Jan 2, 2012 at 12:38pm
closed account (o1vk4iN6)
You can pass the stack by reference or pointer through to a function if that's what's required of you, so yes there is a choice.

If this is an assignment ask your prof or teacher for guidance, they are the most knowledgeable and reliable source of information. There's many methods you can choose to read input the way you need it, read the characters one by one, use a space as a delimiter.
Jan 2, 2012 at 12:40pm
How to like translate it into the code for reading the char one by one.

a.push( calculation( op1, op2, ch ) );
I cant do something like that for the function. I not sure of the error.
cannot convert parameter 1 from 'void' to 'const int &' - error
Last edited on Jan 2, 2012 at 12:43pm
Jan 2, 2012 at 12:57pm
I think you need some thing like this

1
2
3
cout<<"\n Enter the the values ";
get(cin , str_calc);
calculation(str_calc);


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
int calculation(string oper )
{
	stack<int> input_values ;
	stack<int> iterator::it ; 
	char operation; 
	int result = 0;
	do
	{
		if(	isdigit(oper[i]) ) 
			input_value.push(atoi(oper[i]);
		if(	isalphanumeric(oper[i]) ) 
	}		operation = oper[i]
	while (	oper[i] != '\0'	);
	switch (operation)
	{
		case '+':
			 for( it = input_value.begin() ; it!= input_value.end(); it++)
					result+= *it;
			break;
		case '-':
			for( it = input_value.begin() ; it!= input_value.end(); it++)
					result-= *it;
			break;
		case '*':
			for( it = input_value.begin() ; it!= input_value.end(); it++)
					result*= *it;
			break;
		case '/':
			for( it = input_value.begin() ; it!= input_value.end(); it++)
					result/= *it;
			break;
		default: cerr << "undefined behavor\n";
                         break;
	}
return result;
}
Last edited on Jan 2, 2012 at 12:57pm
Jan 2, 2012 at 1:03pm
Wa, this code definitely looks new and hard. I dun understand the code at all.

Just asking, anyone know if it is possible to declare something that the data type can store integers or charcters both without the int which store only integers and char to store only charcters. This is the part where I had big problem since I only can do the calculation for a b+ only.
Jan 2, 2012 at 2:53pm
help people
Jan 8, 2012 at 4:11pm
Any1 know what should I do if I want to check whether the user input is integer or characters. Currently, this is my biggest problem. Because integer is make of int data types while characters is make of char data types. how should I check if the user input enter is either integer of characters using c++ algorithms with perhaps example of source code.
Jan 8, 2012 at 5:39pm
Look at KBW's example: http://cplusplus.com/forum/general/58633/#msg316108

You need to ask for your input, one at a time. Then if it is a number, push it onto the stack. If it is an opertor, then pop the last two numbers off the stack, evaluate them according to the operator and push the result back onto the top of the stack.

Topic archived. No new replies allowed.