Infix expression evaluation [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I would like to evaluate(not convert) infix expression in C++. If you posses algorithm or even implementation of such algorithm(may be not C++, any language... I will try to rewrite it to C++) share please.
Evaluation means give the value of expression. (2+2)*3 is 12
I am sorry, I forgot that I am talking about stack solution, cause I know the tree solution and It is not suitable this time : (.

How do you got the expression? If you got it like (3 + 4) - (1 * 2) + 1 =
+
/ \
- 1
/ \
+ *
/ \ / \
3 4 1 2
http://cboard.cprogramming.com/cplusplus-programming/32682-inserting-infix-into-binary-tree.html
do a tree transversal of the tree like Left Root Right so it will be sth like this: 3 + 4 the result - the result of 1 * 2 the result + 1.
If you got the expression like 34+12*-1+ you can simulate assembly like do a stack and if you get to an operator pop the last 2 elements in the stack and apply the operator: put 3 in stack, put 4 in stack, get op. + so pop the last 2 elements and use the operator. Now you got only 7 in stack. Now read until get an operator so in the stack you will have 7 1 2 after op. * in stack you got 7 2 after op. - you get only 5 in stack add 1 in stack: Stack 5 1, use the last operator + and get the final result 6.
Ok, here is the code:
#include <STACK>
int GetResult( char * rpn )
{
std::stack<int> myStack;
int nr1, nr2; int length = strlen(rpn);
for (int i = 0; i < length; i++)
{
if (isdigit(rpn[i]))
{
myStack.push(rpn[i] - '0');
}
else
{
switch(rpn[i])
{
case '+':
nr1 = myStack.top();
myStack.pop();
nr2 = myStack.top();
myStack.pop();
myStack.push(nr2 + nr1);
break;
case '-':
nr1 = myStack.top();
myStack.pop();
nr2 = myStack.top();
myStack.pop();
myStack.push(nr2 - nr1);
break;
case '*':
nr1 = myStack.top();
myStack.pop();
nr2 = myStack.top();
myStack.pop();
myStack.push(nr2 * nr1);
break;
case '/':
nr1 = myStack.top();
myStack.pop();
nr2 = myStack.top();
myStack.pop();
myStack.push(nr2 / nr1);
break;
default:
break;
}
}
}
return myStack.top();
}
int main(int argc, char* argv[])
{
char *rpn = "34+12*-1+";
int rez = GetResult(rpn);
printf("%i", rez);
return 0;
}

By far the easiest way is to convert the infix expression to postfix notation using Dijkstra's Shunting-yard algorithm, and evaulate the result, which is, like, trivial. There are code samples of this all over the internet (take a look at Rosetta code or LiteratePrograms).
Alternatively, if you'd like to learn, and you'd like to enter the magical world of parsing and a bit of compiler theory, write a recursive descent parser. It's great fun.
Oh and, if you'd like something more robust, you could take a look at Pratt parsing, which is awesome. Here's a great article about it.

Related

Keeping the order of operations while doing a sequential calculation

I am spending my evening doing some programming problems from Kattis. There is one part of the problem 4 thought that I am stuck on.
Given a number, the program is supposed to return the operations (+, -, * or /) required between 4 fours to achieve that number.
For example, the input
9
would result in the output
4 + 4 + 4 / 4 = 9
My solution (not efficient, but simple) is to evaluate all possible ways to combine the operators above and see if any of the combinations achieve the wanted result.
To do this I have written the function seen below. It takes in an array of chars which are the operators to be evaluated (uo[3], could look like {+, /, *}), and the wanted result as an integer (expRes).
bool check(char uo[3], int expRes) {
int res = 4;
for(int oPos = 2; oPos >= 0; oPos--) {
switch (uo[oPos]) {
case '+' : res += 4; break;
case '-' : res -= 4; break;
case '*' : res *= 4; break;
case '/' : res /= 4; break;
}
}
return res == expRes;
}
I realized that this "sequential" approach comes with a problem: it doesn't follow the order of operations. If I was to call the function with
uo = {+, -, /}
and
expRes = 7 it would return false since 4 + 4 = 8, 8 - 4 = 4, 4 / 4 = 1.
The real answer is obviously true, since 4 + 4 - 4 / 4 = 7.
Can any of you think of a way to rewrite the function so that the evaluation follows the order of operations?
Thanks in advance!
Its an easy problem if you look at it.
You are restricted with four 4's and three operators in between, that is you already know your search space. So one solution is to generate the complete search space which is O(n^3) = 4^3 = 64 total equations, where n is the number of operators. Keep the answer to these solutions as a <key, value> pair so that look up to the input of test case is O(1).
Step wise you'd do.
Generate Complete Sequence and store them as key, value pairs
Take Input from test cases
Check if key exists, if yes print the sequence, else print that the sequence doesn't exist
Solution would take 64*1000 operations, which can easily be computed with in a second and would avoid Time Limit Exceeded Error that usually these competitions have
in Code form (most of it is incomplete):
// C++ Syntax
map<int, string> mp;
void generateAll() {
// generate all equations
}
void main () {
generateAll();
int n, t; scanf("%d", &t);
while (t--) {
scanf("%d", &n);
if ( mp.find(n) != mp.end() )
// equation exists to the input
else
// equation doesn't exist for the input
}
}

Converting string into char

I've got a problem with converting types in C++. I've got an expression: string wholeExpression = "44*2"; and I want to separate numbers from operators.
If it is a operator, I use this part of code:
string subExpression;
char skladnik;
subExpression = wholeExpression.substr(poczatek, lenght);
skladnik = subExpression[0];
if it is a number:
subExpression = wholeExpression.substr(poczatek, lenght);
skladnik = atoi(subExpression.c_str());
#EDIT
switch (skladnik)
{
case '+':
case '-':
{
while (topOfStack > 0 && stack[topOfStack - 1] != '(')
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
stack += skladnik;
topOfStack++;
break;
}
case '/':
case '*':
{
while (topOfStack > 0 && (stack[topOfStack - 1] == '*' || stack[topOfStack - 1] == '/'))
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
stack += skladnik;
topOfStack++;
break;
}
case '(':
{
stack += skladnik;
topOfStack++;
break;
}
case ')':
{
while (stack[topOfStack - 1] != '(')
{
outPut += stack[topOfStack - 1] + przecinek;
stack.resize(topOfStack - 1);
topOfStack--;
}
if (stack[topOfStack - 1] == '(')
{
stack.resize(topOfStack - 1);
topOfStack--;
}
break;
}
default:
{
outPut += to_string(skladnik) + przecinek;
break;
}
}
}
But suddenly I've got problem with a numbers from 40 to 43 and 45 and 47 -> which are operators (in ASCII code). They are probably interpret by the switch not as numbers but as oparators. Another numbers work perfectly. How can i solve this problem?
You've answered your own question. The char for the number 40 doesn't exist. It's two char variables: 4 and 0. Because you are putting an int into a char with atoi, it is going to use the ASCII code. Without knowing the value of lenght, it's hard to say that this is indeed your problem, but here are two possible solutions:
Don't use atoi upfront. Instead interpret each number char into an actual integer after your switch statement (4 and 0 would be
atoi('4') * 10 + atoi('0'))
use an int orlong or double variable to hold your numbers.
You are using your variable skladnik in two different ways. In one code path it refers to a decoded integer, in the second code path it refers to a character. Once you've conflated the meaning like this, there's no way to tell once you're at the switch which meaning it has.
You should use two different variables, one for decoded numbers and one for operator characters. Then there will be no confusion.

Postfix Evaluation how to detect operator vs operand

I have this Code in which I am using character array to store each expression but it doesnt work with numbers >9 my current code is:
int main(){
int i,n,c,k,l;
char buf[200];
cin>>n;
IntStack s(n);
i=0;
while(i<n)
{
cin>>buf[i];
if(buf[i]=='*')
{
k=s.pop();
l=s.pop();
k=k*l;
s.push(k);
}
else if(buf[i]=='+')
{
k=s.pop();
l=s.pop();
k=k+l;
s.push(k);
}
else if(buf[i]=='-')
{
k=s.pop();
l=s.pop();
k=l-k;
s.push(k);
}
else if(buf[i]=='/')
{
k=s.pop();
l=s.pop();
k=l/k;
s.push(k);
}
else
{
c=(buf[i]-48);
s.push(c);
}
i++;
}
k=s.pop();
if(s.isempty())
{
cout<<k;
}
else
{
cout<<"INVALID";
}
return 0;
}
Input:
11
1 2 + 3 * 6 + 2 3 + / <-Working
11
3 5 * 2 / 11 3 / 7 * + <-not Working because of 11 in input
Kindley help solving this problem or give an better logic to differentiate between numbers and operators.
Complete Code can be viewed here.
To read the input, and split it into what compiler theory calls "tokens", you need a simple lexical analyzer, or scanner, but slightly more advanced than the just-read-a-character version you have.
A technique used in the simple scanner given in (the previous edition of) the "dragon book" (Aho, Sethi, Ullman: Compilers - Principles, Techniques, and Tools, 1986) is to read a character, and if it is a digit put it back in the input (with ungetc in C), and then read an integer normally. If it is not a digit, handle it as an operator.
Before applying any operand, you are just popping one digit. There should be a loop to pop all digits until another operator is found, and concatenate the digits to make a number. For example:
1+23+3
After first '+' operator, there should be a loop to pop both 2 and 3 ( generally until next operator is found). Then convert it to number 23 and apply the operator to 1 and 23.

C++ iostream recruitcoders [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have found 4 tasks on recruitcoders.com and
I have completed all of them, but in the first one i have scored only 1/10:
Write a program that works as a simple calculator that supports five operations: addition, subtraction, multiplication, division and modulo.
Input:
There is an unknown number of tests. Each test consists of one-character symbol which corresponds to specific operation (+ addition, - subtraction, * multiplication, / division and % modulo) and two following integers. Each test will be separated by spaces and followed by a newline. Number of tests doesn't exceed 100 and the result is less than 2^31. You can assume that there is no situation in which you would have to divide by 0.
Output:
For each test you should print a single number being the result of each operation.
Example:
Input:
+ 7 9
- 0 4
* 5 6
/ 8 3
% 5 2
Output:
16
-4
30
2
1
MyCode:
#include <iostream>
using namespace std;
int fcount(char, int, int);
int main() {
char znak;
long a, b;
long* wynik=new long[100];
for(char i=0;i<100;i++){
cin>>znak>>a>>b;
wynik[i]=fcount(znak,a,b);
}
for(char i=0;i<100;i++)
cout<<wynik[i]<<endl;
return 0;
}
int fcount(char znak, int a, int b){
switch(znak){
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
case '%':
return a%b;
}
}
THIS CODE IS WORKING FINE, IT IS JUST UNDERRATED BY RECRUITCODERS (1/10)
I am not asking you for better code, I just wonder where am I loosing so many points in such an easy task? Any suggestions? I have completed all 4 tasks scoring 28/40 total (1/10, 10/10, 10/10, 7/10), so the task with score 1/10 is a pain in a** for me :/
The requirement says that there is an unknown number of tests, but you are assuming exactly 100 tests. Change it to:
while (cin >> znak >> a >> b)
cout << fcount(znak, a, b) << endl;

Evaluate a simple string mathematical expression [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I've just taken a test for a graduate C++ developer with the question below. It didn't go too well as I couldn't decide on a clear way of completing the task. Time limit didn't help either. I'm interested in how experienced developers would have tackled the follow problem - in pseudo or sample code:
Evaluate
Write a function in C or C++ that evaluates the result of a simple expression.
The function should ignore whitespace, but stop at the first non valid character.
Valid tokens are listed in the table below:
0-9 - Only integers are allowed in expressions
() - Nested expressions should be evaluated first.
+, -, *, / - Basic operators are addition, subtraction, multiplication and division.
The expression should be parsed from left to right. It is not necessary to consider operator precedence in your solution (e.g. 1 + 3 * 4 = 16). If there is an error in the expression, the function should return false.
Suggested prototype for function:
Example:
bool evaluate(const char *expression, int &result)
{
...
}
**Input**
1+3
(1 + (12 * 2)
**Result**
4
N/A
**Return code**
true
false (missing bracket)
In addition, this is the 2nd C++ that I've failed to complete successfully. Have had 1 year intership experiece and 1 year academic experiece using C++, but I'm not prepared for some of these tests. Are there any recommended resources where I can attept to solve problems such as this one in order to gain more 'testing' experience?
The problem here is mostly parsing, which would be covered in a compiler course probably in second or third year. Once you can parse expressions to build up a recursive data structure representing the input (called a syntax tree) it's pretty trivial to evaluate such expressions. A recursive decent parser can also evaluate the expression as it goes without actually building a syntax tree.
For a full treatment you'd want a book on compilers, such as the dragon book. Also IIRC the book Programming: Principals and Practice using C++ covers an example like this.
You could also wait for chapter ten of The Art of Computer Programming to be published, which will cover parsing. It's scheduled to be out around 2020.
Here is my shortest attempt. It took about 40 minutes to type up, you can play with it on ideone (link).
The code is very straightforward, assuming that you have at least a cursory familiarity with the basic recursive descent parsing technique.
#include <iostream>
#include <cctype>
using namespace std;
bool eval_expr(const char **pe, int &lhs, bool inside = false);
// gets the next char after skipping optional whitespace
char skip_ws(const char **pe) {
while (**pe == ' ') ++(*pe);
return **pe;
}
// evaluates a parenthesized expression or a number
bool eval_prim(const char **pe, int &res) {
char c = skip_ws(pe);
if (c == '(') {
++(*pe);
if (!eval_expr(pe, res, true)) return false;
++(*pe);
return true;
}
if (isdigit(c)) {
res = 0;
while (isdigit(c)) {
res = 10*res + c - '0';
c = *(++(*pe));
}
return true;
}
return false;
}
// evaluates a chain of + - * / operations
bool eval_expr(const char **pe, int &lhs, bool inside) {
if (!eval_prim(pe, lhs)) return false;
char op;
while ((op = skip_ws(pe)) && (op == '+' || op == '-' || op == '*' || op == '/')) {
++(*pe);
int rhs;
if (!eval_prim(pe, rhs)) return false;
switch (op) {
case '+': lhs += rhs; break;
case '-': lhs -= rhs; break;
case '*': lhs *= rhs; break;
case '/': lhs /= rhs; break;
}
}
return inside ? op == ')' : !op;
}
// wrapper API to hide an extra level of indirection
bool evaluate(const char *e, int &result) {
return eval_expr(&e, result);
}
Begin with a simple grammar:
expr: n-expr {o-expr} | p-expr {o-expr}
n-expr: [0-9]n-expr
p-expr: ( expr )
o-expr: op expr
op: + | - | * | /
This is probably the largest hurdle for the question. You want to be able to write a simple top down recursive descent parser, so your grammar needs to be written in a way to allow that to happen.
Then, the implementation from there is fairly straightforward:
bool expr (const char *&s, int &result, int eos = 0) {
while (isspace(*s)) ++s;
if (*s == eos) return false;
if (isdigit(*s)) {
if (!n_expr(s, result)) return false;
} else if (*s == '(') {
if (!p_expr(s, result)) return false;
} else return false;
while (isspace(*s)) ++s;
if (*s == eos) return true;
return o_expr(s, result, eos);
}
bool n_expr (const char *&s, int &result) {
int n = 0;
while (isdigit(*s)) n = 10 * n + (*s++ - '0');
result = n;
return true;
}
bool p_expr (const char *&s, int &result) {
if (expr(++s, result, ')')) {
++s;
return true;
}
return false;
}
bool o_expr (const char *&s, int &result, int eos) {
int oresult = 0;
const char *op = strchr("+-*/", *s);
if (op == 0) return false;
if (!expr(++s, oresult, eos)) return false;
switch (*op) {
case '+': result += oresult; break;
case '-': result -= oresult; break;
case '*': result *= oresult; break;
case '/': result /= oresult; break;
default: return false;
}
return true;
}
This is a simple scan push apply (the twist is the braces).
Look for a number:
If you see a number push onto stack
if you see a '(' push it onto stack and goto 1
Otherwise an error.
Look for an op:
If you see an op push it onto stack
Otherwise an error
Look for a number:
If you see a number push onto stack
If you see a '(' push onto stack and goto 1
Otherwise an error
pop last three items from the stack (should be number op number)
do the operation and push the result onto the stack.
Now the complex bit:
Peek to see if the next character is a ')' if it is goto "PopCode" below.
If no more input goto 7.
Otherewise goto 2
If only one item on the stack you have your result.
Otherwise an error.
PopCode
Pop last two values from the stack. Should be '( Number'
If it is not then an error
Throw away the '('
If the top of the stack is an op push value goto 4 (above)
Otherwise push the value onto the stack goto 5 (above)
When finished there should be one number on the stack.
Example:
1+3
Rule 1: push 1 stack = '1'
Rule 2: push + stack = '1 +'
Rule 3: push 3 stack = '1 + 3'
Rule 4: pop and do: stack = '4'
Rule 5: Nothing stack = '4'
Rule 6: goto 7 stack = '4'
Rule 7: stack = '4'
(1 + (12 * 2)
Rule 1: push ( goto 1 stack = '('
Rule 1: push 1 stack = '( 1'
Rule 2: push + stack = '( 1 +'
Rule 3: push ( goto 1 stack = '( 1 + ('
Rule 1: push 12 stack = '( 1 + ( 12'
Rule 2: push * stack = '( 1 + ( 12 *'
Rule 3: push 2 stack = '( 1 + ( 12 * 2'
Rule 4: Pop and do: stack = '( 1 + ( 24'
Rule 5: Do 'PopCode' stack = '( 1 + ( 24'
Pop 1: Pop 2 stack = '( 1 +'
Pop 2: Holding 24 stack = '( 1 +'
Pop 3: push 24 goto 4 stack = '( 1 + 24'
Rule 4: Pop and do stack = '( 25'
Rule 5: Nothing stack = '( 25'
Rule 6: goto 7 stacj = '( 25'
Rule 7: More than 1 item error
Re-Doing with correct formula
(1 + (12 * 2))
Rule 1: push ( goto 1 stack = '('
Rule 1: push 1 stack = '( 1'
Rule 2: push + stack = '( 1 +'
Rule 3: push ( goto 1 stack = '( 1 + ('
Rule 1: push 12 stack = '( 1 + ( 12'
Rule 2: push * stack = '( 1 + ( 12 *'
Rule 3: push 2 stack = '( 1 + ( 12 * 2'
Rule 4: Pop and do: stack = '( 1 + ( 24'
Rule 5: Do 'PopCode' stack = '( 1 + ( 24'
Pop 1: Pop 2 stack = '( 1 +'
Pop 2: Holding 24 stack = '( 1 +'
Pop 3: push 24 goto 4 stack = '( 1 + 24'
Rule 4: Pop and do stack = '( 25'
Rule 5: Do 'PopCode' stack = '( 25'
Pop 1: Pop 2 stack = ''
Pop 2: holding 25 stack = ''
Pop 3: Nothing. stack = ''
Pop 4: push 25 goto 5 stack = '25'
Rule 5: Nothing stack = '25'
Rule 6: goto 7 stack = '25'
Rule 7: Result = 25
The easiest way to solve a (not necessarily) simple mathematical expression is to use the Shunting Yard algorithm to convert it to Reverse Polish Notation, which is almost trivial to parse using a stack. Of course it might not be feasible to do so for an assignment or an interview (perhaps unless a SY algorithm reference is available).