Hate coming back for help after getting help on the same program just a few days ago, but I am really struggling to finish this program. In short, I need to create a postfix notation calculator (RPN) with a linked list stack, that allows me to do expressions such as 5 5 5 + + (=15). I've managed to get the main calculation part down now, but I am struggling with handling two of the errors. One of which is "too many operators," and the other, "too many operands." Currently working on "too many operators" and I feel like I am close but can't quite get there.
If the user enters 5 5 + + on the first entry, it catches it and says "too many operands." However, if something is already in the stack from a previous calculation, and they then type the same expression 5 5 + +, it is not saying that the stack is empty, and is instead outputting an answer with the previous number being used. If anyone can see where I am going wrong here, and also point me in a direction for figuring out the other error "too many operators" (ex: 5 5 5 +) that'd be greatly appreciated. Thanks again in advance.
(After messing with it more, it seems the more calculations I do, the more operators actually need to be put in place to be considered empty. I'm guessing I need to popVal somewhere before each expression but not sure where to put it, as I've tried many places and it's not working)
#include<iomanip>
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
class SLLNode
{
double data;
SLLNode *top;
SLLNode *ptr;
public:
SLLNode()
{
top = NULL;
ptr = NULL;
}
bool isEmpty()
{
return top == 0;
}
void pushVal(double val)
{
SLLNode *next = new SLLNode;
next -> data = val;
next -> ptr = top;
top = next;
}
double popVal()
{
if (isEmpty())
{
cout << "Error: Too many operators" << endl;
}
else
{
SLLNode *next = top -> ptr;
double ret = top -> data;
delete top;
top = next;
return ret;
}
}
void print()
{
cout << top -> data << endl;
}
};
bool isOperator(const string& input)
{
string ops[] = {"+", "-", "*", "/"};
for(int i = 0; i < 4; i++)
{
if(input == ops[i])
{
return true;
}
}
return false;
}
void performOp(const string& input, SLLNode& stack)
{
double fVal, sVal;
int errorCheck = 0;
sVal = stack.popVal();
fVal = stack.popVal();
if(input == "+")
{
stack.pushVal(fVal + sVal);
}
else if(input == "-")
{
stack.pushVal(fVal - sVal);
}
else if(input == "*")
{
stack.pushVal(fVal * sVal);
}
else if(input == "/" && sVal != 0)
{
stack.pushVal(fVal / sVal);
}
if(input == "/" && sVal == 0)
{
cout << "Error: Division by zero" << endl;
errorCheck = 1;
}
if(errorCheck == 0)
{
stack.print();
}
}
int main()
{
cout << "::::::::::::::::RPN CALCULATOR:::::::::::::::::" << endl;
cout << "::TYPE IN A POSTFIX EXPRESSION OR 'q' TO QUIT::" << endl;
cout << ":::::::::::::::::::::::::::::::::::::::::::::::" << endl << endl;
string input;
SLLNode stack;
while(true)
{
cin >> input;
double num;
if(istringstream(input) >> num)
{
stack.pushVal(num);
}
else if (isOperator(input))
{
performOp(input, stack);
}
else if (input == "q")
{
return 0;
}
}
}
The basic idea is to:
Read one line (std::getline);
Process this line (std::stringstream);
Output the answer or any errors;
Clean the stack (or destroy it and create a new one on step 2);
Go to 1 and repeat.
What you are missing is the first step. If you get everything directly from stdin, you will treat the newline as a simple whitespace.
Related
#include<iostream>
#include<stdio.h>
#define MAX 20
using namespace std;
char stk[MAX];
int top=-1;
void push(char c)
{
if(top==MAX-1)
cout<<"Overflow";
else
{
stk[++top]=c;
}
}
char pop()
{
if(top==-1)
{
return '\0';
}
else
return stk[top--];
}
int priority(char ch)
{
if(ch=='(')
return 1;
if(ch=='+'||ch=='-')
return 2;
if(ch=='*'||ch=='/')
return 3;
if(ch=='^')
return 4;
}
int main()
{
char exp[35],*t,x;
cout<<"Enter expression: ";
fgets(exp,35,stdin);
t=exp;
while(*t)
{
if(isalnum(*t))
cout<<*t;
else if(*t=='(')
push(*t);
else if(*t==')')
{
while((x=pop())!='(')
cout<<x;
}
else
{
if(priority(stk[top])>=priority(*t))
cout<<pop();
push(*t);
}
t++;
}
while(top!=-1)
cout<<pop();
return 0;
}
The output for input:
a+b-(c+d/e)
is
ab+cde/+
-
I don't understand why - is on a newline.
I have just started learning c++ and I am trying to implement some programs I did in c using c++. The same code in c works fine. I think there are some holes in my basic c++ knowledge and I would like to fill them up.
std::fgets does not discard the newline in the input stream like getline would. That means exp contains "a+b-(c+d/e)\n" and not "a+b-(c+d/e)". You either need to remove the newline from exp, switch to cin.getline(), or stop your processing loop when it hits the newline.
Try to change fgets to std::cin. And use std::string instead of char*:
#include <iostream>
#include <string>
int main()
{
string exp;
cout << "Enter expression: ";
std::cin >> exp;
auto t = exp.data();
char x;
for(auto &ch: exp)
{
if(isalnum(ch))
cout << ch;
else if(ch == '(')
push(ch);
else if(ch == ')')
{
while((x = pop()) != '(')
cout << x;
}
else
{
if(priority(stk[top]) >= priority(ch))
cout << pop();
push(ch);
}
}
while(top != -1)
cout << pop();
return 0;
}
In addition to the processing of '\n' as mentioned by NathanOliver, your function priority() doesn't return a value when the user entered any other character not checked in the if statements, so the behavior might be undefined.
Hello I have written a postfix calculator using vectors (which is required) and have run into trouble. When I enter two operands in a row, it won't give the correct answer. For example, "5 4 + 3 10 * +" gives the answer "36" when it should give 39. I understand why it isn't working I just can't think of a way to do it where it handles that case. Can someone give me a hand?
Code:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
//splits the string into different parts seperated by space and stores in tokens
void SplitString(string s, char delim, vector<string> &tokens)
{
stringstream ss;
ss.str(s);
string item;
while(getline(ss, item, delim))
{
tokens.push_back(item);
}
}
//preforms the operation denoted by the operand
void operation(string operand, vector<int> &eqVec)
{
int temp1 = eqVec.at(0);
int temp2 = eqVec.at(1);
if(operand == "+")
{
eqVec.push_back(temp1 + temp2);
}
else if(operand == "-")
{
eqVec.push_back(temp1 - temp2);
}
else if(operand == "*")
{
eqVec.push_back(temp1 * temp2);
}
else if(operand == "/")
{
eqVec.push_back(temp1 / temp2);
}
}
int main()
{
const char DELIM = ' ';
int total;
string eq;
vector <int> eqVec;
vector<string> tokens;
cout<<"Welcome to the postfix calculator! " << endl;
cout<<"Please enter your equation: ";
//gets the input and splits into tokens
getline(cin, eq);
SplitString(eq, DELIM, tokens);
//cycles through tokens
for(int i = 0; i < tokens.size(); ++i)
{
//calls operation when an operand is encountered
if(tokens.at(i) == "+" || tokens.at(i) == "-" || tokens.at(i) == "*" || tokens.at(i) == "/")
{
operation(tokens.at(i), eqVec);
}
//otherwise, stores the number into next slot of eqVec
else
{
//turns tokens into an int to put in eqVec
int temp = stoi(tokens.at(i));
eqVec.push_back(temp);
}
}
//prints out only remaining variable in eqVec, the total
cout<<"The answer is: " << eqVec.at(0) << endl;
return 0;
}
After taking a break and coming back I found a way to solve it. Posting here in case anyone in the future has the same problem. The following block of code is now at the beginning of the operation function before the series of if statements.
int temp1, temp2;
int size = eqVec.size();
if(size > 2)
{
temp1 = eqVec.at(size - 1);
temp2 = eqVec.at(size - 2);
eqVec.pop_back();
eqVec.pop_back();
}
else
{
temp1 = eqVec.at(0);
temp2 = eqVec.at(1);
eqVec.pop_back();
eqVec.pop_back();
}
Sorry if this is REALLY trivial, I'm just sick at being stuck at step one and need to continue and I have no help anywhere else. I can not for the life of me get this function to cooperate with me. Here's the source:
#include <iostream>
using namespace std;
void ReadDials(){
};
void ToDigit(char *x){
if (*x = 'a'){*x = '54';}
else if (*x = 'A'){*x = 2;}
else if (*x = 'b'){*x = 3;}
else(*x = 4);
};
int main()
{
char one;
char two;
char three;
cin >> one;
ToDigit(&one);
cout << "one is: " << one << endl;
system("PAUSE");
}
What I've tried: alternating between the actual number 2 and the ascii pointer of 2 which I believe is '32' I've used == to try, I've done everything I can possibly think of and I know I'm over thinking it. The point is to have that function convert user input into numbers for a phone dialer.
Problems ranging from numbers not syncing with if statements, and seeing a ':D' face on the console. It's making me very annoyed.
If I need to make myself more clear, I'll be more than happy too.
Thanks in advance for any assistance.
In if (*x = 'a'), the = is an assignment. You want == for comparison. Also, '54' isn't a character value.
void ToDigit(char *x){
if (*x == 'a') { *x = '54'; } /* what is this supposed to do? */
else if (*x == 'A') {*x = 2; }
else if (*x == 'b') {*x = 3; }
else { *x = 4 };
};
It looks like you are trying to use x as an input and output. Let's step back a minute. Let's instead write a function that takes a single char and returns an integer. This would be the canonical way of taking a char and getting a number from it.
int ToDigit(char x){
if (x == 'a') { return 54; }
if (x == 'A') { return 2; }
if (x == 'b') { return 3; }
return 4 ;
};
To use this form of the function, you'd assign the return value to a variable of type int in this case.
char my_input;
int mapped_number;
std::cin >> my_input;
mapped_number = ToDigit(my_input);
std::cout << my_input << " maps to " << mapped_number << ".\n";
novice coder here and I've been asking around how I should go about creating a two stack algorithm for calculating simple expressions (Dijkstra's Two Stack Algorithm) in C++. A quick refresher for anybody that need it:
Two Stack Algorithm:
Value - Push onto value stack
Operator - Push onto operator stack
Left Parenthesis - Ignore
Right Parenthesis - Pop two values from value stack and one value from operator stack and push the result
It appears that using istringstream, which was recommended to me, should allow me to separate the user inputted expression into basic, doubles, and non-doubles. This should allow me to populate my vals and ops stack respectively, however upon debugging, I realized that my vals stack ended up empty at the end (causing a segmentation fault)
I've got no idea what I'm doing wrong, and any help would be appreciated! Keep in mind I am relatively new to coding and my syntax is probably horrible, therefore any type of criticism is welcome.
For reference an input of:
( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )
Should output:
101
Thus far my code looks like this:
stack<string> ops;
stack<double> vals;
string input;
getline(cin, input);
istringstream scanner(input);
while(true){
double num;
scanner >> num;
if(scanner.fail() && scanner.eof()) break;
else if(!scanner.fail()) vals.push(num);
else{
scanner.clear();
string token;
scanner >> token;
if(token == "(") ;
else if(token == "+") ops.push(token);
else if(token == "*") ops.push(token);
/*Add more operations here (Log, sin, cos...)*/
else if(token == ")"){
string op = ops.top();
ops.pop();
if(op == "+"){
double a, b;
a = vals.top();
vals.pop();
b = vals.top();
vals.pop();
vals.push(a+b);
}
else if(op == "*"){
double a, b;
a = vals.top();
vals.pop();
b = vals.top();
vals.pop();
vals.push(a*b);
}
/*Add more operations here*/
}
}
return vals.top();
}
Thank you for your help!
Turns out the problem was with this:
scanner >> num;
if (scanner.fail() && scanner.eof()) break;
else if (!scanner.fail()) vals.push(num);
Changing it to the following fixed the problem:
if (scanner >> num) vals.push(num);
if (scanner.fail() && scanner.eof()) break;
else {
// ...
}
And putting the return statement below the loop also helped.
Live example
Not a straightforward answer to what you asked, but I reworked your example with out the use of stringstreams, which might be confusing to you. You can use the following code as an alternative:
#include <iostream>
#include <string>
#include <stack>
#include <ctype.h>
double parseExpression(std::string const &expr)
{
std::stack<char> ops;
std::stack<double> vals;
std::string num;
for (auto c : expr) {
if (c == '+' || c == '*') {
if(!num.empty()) vals.push(std::stod(num));
num.clear();
ops.push(c);
} else if (c == ')') {
if (!num.empty()) vals.push(std::stod(num));
num.clear();
char op = ops.top();
ops.pop();
switch (op) {
case '+': {
double tmp = vals.top();
vals.pop();
tmp += vals.top();
vals.pop();
vals.push(tmp);
} break;
case '*': {
double tmp = vals.top();
vals.pop();
tmp *= vals.top();
vals.pop();
vals.push(tmp);
} break;
};
num.clear();
} else if(isdigit(c) || c == '.') {
num.push_back(c);
} else if (isspace(c)) {
if (!num.empty()) vals.push(std::stod(num));
num.clear();
} else if(c != '(') {
throw std::runtime_error("Unknown character in expression!");
}
}
return vals.top();
}
int main()
{
std::string expr("( 1.00 + ( ( 2.000000 + 3.00 ) * ( 4.00 * 5.00 ) ) )");
std::cout << expr << " = " << parseExpression(expr) << std::endl;
return 0;
}
HTH
I have written a code for infix to postfix conversion,This piece of code is not encountering any kind of compile time error but after taking the input infix expression it is giving some runtime errors which i am unable to understand these errors are something related to string as the message says.
#include<iostream>
#include<string>
#define N 50
using namespace std;
class stack
{
private:
char arr[N];
int tos;
public:
void push(char p)
{
if (tos != N)
arr[++tos] = p;
else
cout << "stack full";
}
char pop()
{
if (tos == -1)
cout << "stack Empty";
else
return (arr[tos--]);
}
bool isempty()
{
if (tos == -1)
return (true);
else
return (false);
}
char top()
{
return arr[tos];
}
stack()
{
tos = -1;
}
};
int pres(char sym)
{
if (sym == '^')
return 3;
else if (sym == '*' || '/')
return 2;
else if (sym == '+' || '-')
return 1;
else if (sym == '(')
return 0;
}
bool isoperator(char op)
{
if (op=='+' || op=='-' || op=='/' || op=='*' || op=='^')
return true;
else
return false;
}
int main()
{
string infix, postfix;
stack s;
int in=0;
int post=0;
cout << "Enter an infix expression: ";
cin >> infix;
s.push('(');
infix.append(")");
char temp;
while (!(s.isempty()))
{
if (isdigit(infix[in]))
postfix[post++] = infix[in];
else if (infix[in] == '(')
s.push(infix[in]);
else if (infix[in] == ')')
{
while (1)
{
temp = s.pop();
if (temp == '(')
break;
else
postfix[post] = infix[in];
}
}
else if (isoperator(infix[in]))
{
while (pres(s.top()) >= pres(infix[in]))
postfix[post++] = s.pop();
s.push(infix[in]);
}
in++;
}
cout << "Postfix expression is: " << postfix;
system("pause");
}
I m unable to get what's wrong with it. Can any one help??
I found the following logical errors in your code:
the result string postfix is empty at the beginning, but you're writing to single character positions using postfix[post++]=. This is not valid and is propably causing the "string related" errors. You should only use postfix.push_back() to add characters to the output string.
In the first inner while loop (while(1)) the last statement should read
postfix.push_back(temp);
since you want to append the operators from the stack to the output.
Your code falsely accept input with unbalanced additional closing parents like "1+4)". Personally, I would put the input position as outer loop condition and verify that the stack is empty after the loop (and check for empty stack in the pop() function) for detecting input errors.
The biggest error is in his pres() function, it should be:
else if (sym == '*' || sym == '/')
else if (sym == '+' || sym == '-')
I have noticed some of the errors mentioned by MartinStettner.