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 $.
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));
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
This code somehow always adds to the conclusion 12142.
For example insert 12; the output is 1212142, insert 1 + 2; get 312142
#include "stdafx.h"
#include <iostream>
using namespace std;
class Token
{
public:
char kind;
double value;
};
class Token_stream
{
public:
Token get();
void putback(Token t);
private:
bool full{ false };
Token buffer;
};
void Token_stream::putback(Token t)
{
buffer = t;
full = true;
}
Token Token_stream::get()
{
if (full)
{
full = false;
return buffer;
}
char ch;
cin >> ch;
switch (ch)
{
case ';':
case 'q':
case '(': case ')': case '+':
case '-': case '*': case '/':
return Token{ ch };
case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
cin.putback(ch);
double val;
cin >> val;
return Token{ '8',val };
}
default:
throw runtime_error("dont true token");
break;
}
}
Token_stream ts;
double expres();
double prim()
{
Token t = ts.get();
switch (t.kind)
{
case '(':
{
double d = expres();
t = ts.get();
if (t.kind != ')')
{
throw runtime_error("))))");
}
return d;
}
case '8':
return t.value;
default:
throw runtime_error("perm");
}
}
double term()
{
double left = prim();
Token t = ts.get();
while (true)
{
switch (t.kind)
{
case '*':
left *= prim();
t = ts.get();
break;
case '/':
{
double d = prim();
if (d == 0)
{
throw runtime_error("/0");
}
left /= d;
t = ts.get();
break;
}
default:
ts.putback(t);
return left;
}
}
}
double expres()
{
{
double left = term();
Token t = ts.get();
while (true)
{
switch (t.kind)
{
case '+':
left += term();
t = ts.get();
break;
case '-':
left -= term();
t = ts.get();
break;
default:
ts.putback(t);
return left;
}
}
}
}
int main()
{
double val = 0;
while (cin)
{
Token t = ts.get();
if (t.kind == 'q') break;
if (t.kind == ';')
cout << "=" << val << '/n';
else
ts.putback(t);
val = expres();
}
return 0;
}
This code is taken from the book Programming - Principles and Practice Using C ++
Look here:
if (t.kind == ';')
cout << "=" << val << '/n';
'/n' is the character / followed by the character n, squeezed into what's known as a "multi-character literal". These are actually ints with implementation-defined values; on your system, apparently that's the number 12142.
You meant the single character '\n'.
In future, locate and solve problems like this by constructing a minimal testcase. In doing so, you would eventually have ended up with a test program that simply said cout << '/n' and output 12142; at that point, if you still didn't spot the typo, you'd have a very simple thing to look up and/or ask about.
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.
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'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();
}
}