I am able to convert infix to postfix and calculates with one digit but i can't convert to postfix and calculate with N digits. PLz anyone help me! Thanks!!
here is my code with single digit
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
class infix2postfix
{
public:
void push(int symbol);
int pop();
void infix_to_postfix();
int priority(char symbol);
int isEmpty();
int white_space(char);
int eval_post();
};
char infix[100], postfix[100];
int stack[100];
int top;
int main()
{
infix2postfix ip;
top=-1;
cout<<"Enter infix : ";
gets(infix);
ip.infix_to_postfix();
cout<<"Postfix : "<<postfix<<endl;
cout<<"Result is : "<<ip.eval_post()<<endl;
return 1;
}
void infix2postfix :: infix_to_postfix()
{
int i,p=0;
char next;
char symbol;
for(i=0; i<strlen(infix); i++)
{
symbol=infix[i];
if(!white_space(symbol))
{
switch(symbol)
{
case '(':
push(symbol);
break;
case ')':
while((next=pop())!='(')
postfix[p++] = next;
break;
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
while( !isEmpty( ) && priority(stack[top])>= priority(symbol) )
postfix[p++]=pop();
push(symbol);
break;
default: /*if an operand comes*/
postfix[p++]=symbol;
}
}
}
while(!isEmpty( ))
postfix[p++]=pop();
postfix[p]='\0'; /*End postfix with'\0' to make it a string*/
}
/*This function returns the priority of the operator*/
int infix2postfix :: priority(char symbol)
{
switch(symbol)
{
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '^':
return 3;
default :
return 0;
}
}
void infix2postfix :: push(int symbol)
{
if(top>100)
{
cout<<"Stack overflow\n";
exit(1);
}
stack[++top]=symbol;
}
int infix2postfix :: pop()
{
if( isEmpty() )
{
cout<<"Stack underflow\n";
exit(1);
}
return (stack[top--]);
}
int infix2postfix :: isEmpty()
{
if(top==-1)
return 1;
else
return 0;
}
int infix2postfix :: white_space(char symbol)
{
if( symbol == ' ' || symbol == '\t' )
return 1;
else
return 0;
}
int infix2postfix :: eval_post()
{
int a,b,i,temp,result;
for(i=0; i<strlen(postfix); i++)
{
if(postfix[i]<='9' && postfix[i]>='0')
push(postfix[i]-'0');
else
{
a=pop();
b=pop();
switch(postfix[i])
{
case '+':
temp=b+a;
break;
case '-':
temp=b-a;
break;
case '*':
temp=b*a;
break;
case '/':
temp=b/a;
break;
case '%':
temp=b%a;
break;
case '^':
temp=pow(b,a);
}
push(temp);
}
}
result=pop();
return result;
}
My Question is: how to get the result for more than 1 digit operand?
I have tried for Single digit, but how could i get for multi-digit numbers?
You are currently pushing the digits on the stack individually, so a numeric value of 10 will be pushed on the stack two symbols: 1 and 0.
In your operator logic, you are popping one symbol from the stack per operand. Multi-digits operands will thus not work and produce completely wrong results.
There are many ways to solve this. For example, you could fuse multiple digits together into the same stack symbol while reading them in (i.e. combine the digit currently processed with the top of the stack if both are digits).
The place to do this would be inside push. Here's how to do this:
void infix2postfix :: push(int symbol)
{
if(top>100)
{
cout<<"Stack overflow\n";
exit(1);
}
if (! isEmpty() && stack[top] >= 0 && stack[top] <= 9) {
stack[top] *= 10;
stack[top] += symbol;
}
else {
stack[++top]=symbol;
}
}
This will work as long as a numeric operand fits inside the range of an int. Bigger numbers will simply overflow.
There will also be problems because numbers cannot be told apart from other stack symbols. With multi-digit numbers, you can now have symbols which have the same int value as an operator. A way to fix this is to assign negative int values to the operator symbols, and non-negative values for the numbers. This will work for your case as your grammar does not seem to have a unary minus.
This approach is also in line with what you do in eval_post, where you push the calculation result on the stack as a single integer value, regardless of how many digits might be contained.
The most powerful but complicated alternative would write a grammar and use a parser generator. I recommend GNU bison. This will completely take over generating the code for the parser, so all you have to do is to write the grammar for your expressions plus the actual infix-to-postfix transformation (which will be trivial with bison). It will also help you detect invalid input easily and provide appropriate error messages.
However, getting started with bison can be hard if you never used it before.
Related
I don't what is wrong with this code it should answer -4
but the answer i'm getting is 2492
#include <bits/stdc++.h>
using namespace std;
int main() {
stack <int> st;
char s[]="231*+9-" ;
for(int i=0;i<7;i++){
if (isdigit(s[i])){
st.push((int)s[i]);
}
else{
float val1,val2;
val1=st.top();
st.pop();
val2=st.top();
st.pop();
switch (s[i])
{
case '+': st.push( val2 + val1); break;
case '-': st.push(val2 - val1); break;
case '*': st.push( val2 * val1); break;
case '/': st.push( val2/val1); break;
}
}
}int m=st.top();
cout<<m;
return 0;
}
You cannot cast a numeric char directly to int if you want its digit value, because that would just give its ASCII code. Instead, do st.push((int)(s[i]-'0')). This removes the offset of the 0-9 character group.
One easy way is to replace char s[]="231*+9- by a string string s ="231*+9-"
and then create an alias of size_t, so you can push the char as a substr like this:
std::string::size_type sz;
...
st.push(stoi(s.substr(i,1), &sz));
I use stack to evaluate an expression.
The most important function is below:
double Expression_Eval()
{
SeqStack<char,100> OPTR;
SeqStack<double,100> OPND;
OPTR.Push('#');
char ch;
ch=getchar();
while (ch!='#' || OPTR.GetTop()!='#')
{
if (!InOPTR(ch))
{
int n=ch-'0';
double num=(double)n;
OPND.Push(num);
ch=getchar();
}
else
{
char pre_op=OPTR.GetTop();
switch (Precede(pre_op, ch))
{
case '<': OPTR.Push(ch);
ch=getchar();
break;
case '=': OPTR.Pop();
ch=getchar();
break;
case '>': double b=OPND.Pop();
double a=OPND.Pop();
pre_op=OPTR.Pop();
OPND.Push(Operate(a, pre_op, b));
ch=getchar();
break;
}
}
}
return OPND.GetTop();
}
Then, when I input 8/(5-3)#, it will not print the result.
I think the loop termination condition ch!='#' || OPTR.GetTop()!='#' is wrong.
When I press Enter, getchar() get the last char is CR but not #.
But, I don't know how to revise it to make my program work.
The other part of my program is below:
#include<iostream>
using namespace std;
template<typename DataType,int StackSize>
class SeqStack
{
private:
DataType data[StackSize];
int top;
public:
SeqStack()
{ top=-1; }
~SeqStack() {}
void Push(DataType x)
{
if(top == StackSize-1)
throw "error";
data[++top]=x;
}
DataType Pop()
{
if(top == -1)
throw "error";
DataType x=data[top--];
return x;
}
DataType GetTop()
{
if(top != -1)
return data[top];
else
cout<<"error";
}
};
bool InOPTR(char ch)
{
if( (ch>='(' && ch<='+') || ch=='-' || ch=='/' )
{
return true;
}else{
return false;
}
}
char Precede(char op1, char op2)
{
char pri[7][7]={ {'>','>','<','<','<','>','>'}
, {'>','>','<','<','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'>','>','>','>','<','>','>'}
, {'<','<','<','<','<','=','#'}
, {'>','>','>','>','#','>','>'}
, {'<','<','<','<','<','#','='} };
int m,n;
switch(op1)
{
case '+': m=0;break;
case '-': m=1;break;
case '*': m=2;break;
case '/': m=3;break;
case '(': m=4;break;
case ')': m=5;break;
case '#': m=6;break;
}
switch(op2)
{
case '+': n=0;break;
case '-': n=1;break;
case '*': n=2;break;
case '/': n=3;break;
case '(': n=4;break;
case ')': n=5;break;
case '#': n=6;break;
}
return pri[m][n];
}
double Operate(double a, char op, double b)
{
double result;
switch(op)
{
case '+': result=a+b; break;
case '-': result=a-b; break;
case '*': result=a*b; break;
case '/': result=a/b; break;
}
return result;
}
int main()
{
double r=Expression_Eval();
cout<<r<<endl;
return 0;
}
Problem seem to be that '#' is considered a number, but it should be considered an operation:
Use:
bool InOPTR(char ch) {
if ((ch >= '(' && ch <= '+') || ch == '-' || ch == '/' || ch=='#'){
return true;
}
else {
return false;
}
}
Note that '#' is ASCII 64 which is not covered in the ranage '(' to '+' [40-43]
Hope this helps.
You need to consume carriage return or newline character after getchar(); which comes into play when you press enter button.
One trick is as below.
ch=getchar();
getchar(); //this getchar to consume CR.
since you have used ch = getchar() many times you have to use above solution at many places.
Better solution to this problem will be to enter string instead of entering single character using getchar()...
Hope you got what I am trying to say...
I wrote a very simple calculator program in C++ and it works fine! But can someone explain how I can modify this code such that it will be able to add more than 2 numbers at once?
So instead of doing 2 + 2 for example, I want users to be able to do 2 + 2 + 2. But every time I try, it just adds the first two "2"s and gives 4, no matter how many + 2 you type after it.
Here is the code:
#include <iostream>
using namespace std;
// input function
void Input (float &x, float &y);
float a=1.0, b=1.0, result;
char operation;
int main ()
{
cout << "A simple calculator \n\n";
cin >> a >> operation >> b;
Input (a,b);
cout << result << endl;
system ("pause");
return 0;
}
void Input (float &x, float &y)
{
a = x;
b = y;
switch (operation)
{
case '+':
result = x + y;
break;
case '-':
result = x - y;
break;
case '*':
result = x * y;
break;
case '/':
result = x / y;
break;
default:
cout << "Improper operation. Please input a correct calculation operation: \n";
cin >> a >> operation >> b;
Input (a, b);
}
}
Thanks guys!
Your code is thought so you are asking the input for three elements: 2 numbers and their operator (represented as a character).
Let's say you are taking just one shot. If you want to use more operators and numbers you have to develop a simple parser which should continue acquiring input until a end token is found, probably end of line in your case.
To do this I would change your approach concerning data acquisition and calculation. You have to simple options:
Perform your calculations online: That is, to keep a partial result and update it after each input.
Gather all your input in a data structure representing it and then perform all the calculations.
For example, if you decide to implement the first option, this incomplete code may help you:
float Input (float &x, float &y, char operation)
{
float result;
switch (operation)
{
case '+':
result = x + y;
break;
case '-':
result = x - y;
break;
case '*':
result = x * y;
break;
case '/':
result = x / y;
break;
default:
cout << "Improper operation. Please input a correct calculation operation: \n";
}
return result;
}
...
...
string input;
if(!getline( cin, input ) ) return; //Try to read one line.
istringstream lin( input );
float partial = 0.0;
float a;
char op;
while(lin >> op >> a) partial = Input(partial, a, op);
//At this point, partial should contain your final result
Note: I have not tested cases. Like division by zero. etc
float operate(float a, char operand, float b)
{
float result=0.0;
switch(operand)
{
case '+':
result = (a+b);
break;
case '*':
result = (a*b);
break;
case '/':
result = (a/b);
break;
default:
cout<<"Unknown operand"<<endl;
break;
}
return result;
}
int main()
{
float result=0.0;
char operand;
float a,b;
cout<<"enter a number followed by an operation, followed by a number"<<endl;
while(cin>>a>>operand>>b)
result+=operate(a,operand,b);
cout<<result;
return 0;
}
i wrote a little parser a few weeks ago, you can study my code and maybe (hopefully) you find something usefull.
its not c++, but c, so your compiler should be able to compile it.
the parser parses any statements that could be built by following rules:
<expression> ::= <term>
| <term> "+" <term>
| <term> "-" <term>
<term> ::= <factor>
| <factor> "*" <factor>
| <factor> "/" <factor>
<factor> ::= <number>
| "(" <expression> ")"
<number> ::= ["-"] ["0" .. "9"]*
here is the code, it is pretty much self explaining because it follows the rules defined above:
#include <stdio.h>
#include <stdlib.h>
char next;
void getNext(){
next=getchar();
}
int getNum(){ //get a number
int num=0;
if((next<'0')||(next>'9')){
printf("error: expected number; found %c",next);
exit(-1);
}
while((next>='0')&&(next<='9')){
num*=10;
num+=(next-'0');
getNext();
}
return num;
}
int add(int x){
return x+term();
}
int sub(int x){
return x-term();
}
int multiply(int x){
return x*factor();
}
int divide(int x){
return x/factor();
}
int factor(){
int f=0;
if(next=='('){
getNext();
f=expression();
if(next=')')
getNext();
else{
printf("error \")\" expected; found %c",next);
exit(-1);
}
}else{
f=getNum();
}
return f;
}
int term(){
int val;
val=factor();
while((next=='*')||(next=='/')){
char c=next;
getNext();
switch(c){
case '*': val=multiply(val); break;
case '/': val=divide(val); break;
default: printf("error: (*, /) expected; found %c",next);
exit(-1);
}
}
return val;
}
int expression(){
int sign=1;
int val;
if(next=='-'){
sign=-1;
getNext();
}
val=term()*sign;
while((next=='+')||(next=='-')){
char c=next;
getNext();
switch(c){
case '+': val=add(val); break;
case '-': val=sub(val); break;
default: printf("error: (+, -) expected; found %c",next);
exit(-1);
}
}
return val;
}
int main(void) {
getNext();
printf("%d\n", expression());
return 0;
}
example:
$ gcc main.c -o calc
$ ./calc
1+2+3
6
$ ./calc
(1+2+3)/2
3
$ ./calc
3*(1+2)
9
$ ./calc
-10+20
10
$
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.
what does return 4 return 2 return 6 in this code really returning is not making sense to me may someone explain to me what they return,i saw this code on stack flow someone wanted an explanation on infix and prefix convertion
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define MAX 20
char stack[MAX];
int top = -1;
char pop();
void push(char item);
int prcd(char symbol)
{
switch(symbol)
{
case '+':
case '-':
return 2;
case '*':
case '/':
return 4;
case '^':
case '$':
return 6;
case '(':
case ')':
case '#':
return 1;
}
}
int isoperator(char symbol)
{
switch(symbol)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '$':
case '(':
case ')':
return 1;
default:
return 0;
}
}
void convertip(char infix[],char prefix[])
{
int i,symbol,j=0;
char test[MAX];
infix=strrev(infix);
stack[++top]='#';
for(i=0;i<strlen(infix);i++)
{
symbol=infix[i];
if(isoperator(symbol)==0)
{
prefix[j]=symbol;
j++;
}
else
{
if(symbol==')')
{
push(symbol);
}
else if(symbol=='(')
{
while(stack[top]!=')')
{
prefix[j]=pop();
j++;
}
pop();//pop out (.
}
else
{
if(prcd(symbol)>prcd(stack[top]))
{
push(symbol);
}
else
{
while(prcd(symbol)<=prcd(stack[top]))
{
prefix[j]=pop();
j++;
}
push(symbol);
}//end of else.
}//end of else.
}//end of else.
}//end of for.
while(stack[top]!='#')
{
prefix[j]=pop();
j++;
}
prefix[j]='\0';//null terminate string.
prefix=strrev(prefix);
}
int main()
{
char infix[20],prefix[20];
//clrscr();
printf("Enter the valid infix string:\n");
gets(infix);
convertip(infix,prefix);
printf("The corresponding prefix string is:\n");
puts(prefix);
getch();
return 0;
}
void push(char item)
{
top++;
stack[top]=item;
}
char pop()
{
char a;
a=stack[top];
top--;
return a;
}
This code might interpret numerical terms, like. 17 + 3 * 8. To calculate this properly, the code must determine to first take the * and then the +. The order of evaluation is set by the precedence rules: * and / come before + and -.
The return statements look like some precedence code.
(, ), #: return 1
+, -: return 2
*, /: return 4
^, $: return 6
(, ) and # have lowest precedence. After that + and - have next lowest precedence. Then follows * and /. Highest precedence is for ^ and $.
I'm supposed to write this c++ that take in 01 and on. for example: 01010101 but not 0,1,10,011,110. Can someone help me figure out what I need to do to fix the problem. Sorry guys the code isn't working right.I pushed ctrl+k and posted the code but everything wasn't in place.
What I was trying to do is that when some enter 1 than it prints invalid. if they enter 0 it prints invalid, if the enter 10 it prints invalid, if they enter 01 it prints valid, if the enter 0101 it prints valid. So 0 always have to come first and always follow by 1. another example: 0101010101 prints valid
Thanks Seth :). I removed the links
[From seth.arnold: I removed commented-out code and indented the code to follow some kind of logical pattern. Feel free to replace this with your code if you wish, indent each line by four spaces to properly format it.]
#include <iostream>
#include<stdlib.h> // for the exit(1) function
using namespace std;
char text[300];
char ToBeChecked;
char lexical(); //identify the characters
void SProd();
void BProd();
int main(){
cout<<"Enter some strings only 1 and 0 (max. 300 characters"<<endl;
cin>>text;
ToBeChecked = lexical(); //identify the character; find the first letter and give it to ToBeChecked
SProd();
if(ToBeChecked == '\0')
cout<<"Valid"<<endl;
else
cout<<"Invalid"<<endl;
cin.get();
return 0;
}
char lexical(){
static int index = -1; //a memory box named index with a value of -1; is static so it won't change.
//is -1 because -1 to 1 is 0; everything move on to next one
index++; //update index
return text[index]; //return the value of index
}
void SProd(){
if(ToBeChecked != '0' ) {
cout<<"Invalid"<<endl;
exit(1);
}
else{
BProd();
ToBeChecked = lexical();
}
}
void BProd(){
if(ToBeChecked != '1')
{
cout<<"Invalid"<<endl;
exit(1);
}
else
SProd();
ToBeChecked = lexical();
}
Have a look in Bjorn Stroustroup's book Programming Principles and Practice using c++ chapter 6-7.
You will have to write the grammar, you need to know how to:
Distinguish a rule from a token
Put one rule after another (sequencing)
Express alternative patterns (alternation)
Express a repeating pattern
(repetition)
Recognize the grammar rule to start
with
For example - you will have to have a token class:
class Token {
public:
char kind; // what kind of token
double value; // for numbers: a value
Token(char ch) // make a Token from a char
:kind(ch), value(0) { }
Token(char ch, double val) // make a Token from a char and a double
:kind(ch), value(val) { }
};
Then Token stream class:
class Token_stream {
public:
Token_stream(); // make a Token_stream that reads from cin
Token get(); // get a Token (get() is defined elsewhere)
void putback(Token t); // put a Token back
private:
bool full; // is there a Token in the buffer?
Token buffer; // here is where we keep a Token put back using putback()
};
Identify default constructor for Token stream:
Token_stream::Token_stream()
:full(false), buffer(0) // no Token in buffer
{
}
Then create a putback() function, you will need that to put back the character you read from the iostream if it is of interest to you, and function who specializes in extraction of that particular character will be called:
void Token_stream::putback(Token t)
{
if (full) throw std::runtime_error("putback() into a full buffer");
buffer = t; // copy t to buffer
full = true; // buffer is now full
}
Then in Token::get() you will have to make the rules what is important to you and what you want to include, omit or throw error:
Token Token_stream::get()
{
if (full) { // do we already have a Token ready?
// remove token from buffer
full=false;
return buffer;
}
char ch;
cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)
switch (ch) {
case '=': // for "print"
case 'x': // for "quit"
case '(': case ')': case '{': case '}': case '+': case '-': case '*': case '/': case '!':
return Token(ch); // let each character represent itself
break;
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '9':
{
cin.putback(ch); // put digit back into the input stream
double val;
cin >> val; // read a floating-point number
return Token('8',val); // let '8' represent "a number"
}
break;
default:
throw std::runtime_error("Bad token");
}
}
In this version of Token_stream::get() we are interested in numbers, mathematical operators and brackets. So you will have to change that case statement to get either '1' or '0', and ignore everything else, or throw, it is up to you, I don't know what is exactly you need to do.
Then create a grammar function, you will have to establish hierarchy of functions that call one another if you want or example 1 character to be processed in front of the other. But if you only need to read sequentially, you can have only 1 function. anyway, I include 3 functions that are using calculator example where you have +,-,*,/,(,),{,}. As you see this example need to identify what it is in order to call the right function before the other one, eg - multiplication before subscription.
primary() function deals with numbers and parentheses:
// deal with numbers and parentheses
double primary()
{
Token t = ts.get();
switch (t.kind) {
case '(': // handle '(' expression ')'
{
double d = expression();
t = ts.get();
if (t.kind != ')') throw std::runtime_error("')' expected");
return d;
break;
}
case '{':
{
double d = expression();
t=ts.get();
if (t.kind != '}') throw std::runtime_error("'}' expected");
return d;
break;
}
case '8': // we use '8' to represent a number
return t.value; // return the number's value
break;
default:
throw std::runtime_error("primary expected");
}
}
term() function deals with multiplication and division:
// deal with *, /, and %
double term()
{
double left = primary();
Token t = ts.get(); // get the next token from token stream
while(true) {
switch (t.kind) {
case '*':
left *= primary();
t = ts.get();
break;
case '/':
{
double d = primary();
if (d == 0) throw std::runtime_error("divide by zero");
left /= d;
t = ts.get();
break;
}
default:
ts.putback(t); // put t back into the token stream
return left;
}
}
}
expression() deals with addition and subtraction:
double expression()
{
double left = term(); // read and evaluate a Term
Token t = ts.get(); // get the next token from token stream
while(true) {
switch(t.kind) {
case '+':
left += term(); // evaluate Term and add
t = ts.get();
break;
case '-':
left -= term(); // evaluate Term and subtract
t = ts.get();
break;
default:
ts.putback(t); // put t back into the token stream
return left; // finally: no more + or -: return the answer
}
}
}
And finally our calling function:
int callDrill_01(void)
try
{
std::cout << "Welcome to simple calculator." << std::endl;
std::cout << "Please enter expressions using floating-point numbers." << std::endl;
std::cout << "The arithmetic operators available are: + - * / ( ) { } = e(x)it." << std::endl;
double val = 0;
while (cin) {
Token t = ts.get();
if (t.kind == 'x') break; // 'q' for quit
if (t.kind == '=') { // ';' for "print now"
cout << "=" << val << '\n';
}else{
ts.putback(t);
}
val = expression();
}
keep_window_open();
}
catch (exception& e) {
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n";
keep_window_open();
return 2;
}
This should give you an idea of how recursive parser are created. Your head is probably spinning. I suggest you to find that book that I mentioned and read those chapters. It will help you in the future.
#include <iostream>
//#include<stdlib.h> // for the exit(1) function
using namespace std;
char text[300];
char ToBeChecked;
char lexical(); //identify the characters
void SProd();
void BProd();
int main(){
cout<<"Enter some strings (max. 300 characters"<<endl;
cin>>text;
ToBeChecked = lexical(); //identify the character; find the first letter and give it to ToBeChecked
SProd();
if(ToBeChecked == '\0')
cout<<"Valid"<<endl;
else
cout<<"Invalid"<<endl;
cin.get();
return 0;
}
char lexical(){
static int index = -1; //a memory box named index with a value of -1; is static so it won't change.
//is -1 because -1 to 1 is 0; everything move on to next one
index++; //update index
return text[index]; //return the value of index
}
void SProd(){
if(ToBeChecked != 'a' ) {
BProd();
ToBeChecked = lexical();
}
}
void BProd(){
if(ToBeChecked == 'b'){
ToBeChecked = lexical();
SProd();
}
}