enter code here,
#include <stdio.h>
#include <ctype.h>
#define SIZE 50
char s[SIZE];
int top=-1;
void push(char elem)
{
s[++top]=elem;
}
char pop()
{
return(s[top--]);
}
int pr(char elem)
{
switch(elem)
{
case '#': return 0;
case '(': return 1;
case '+':
case '-': return 2;
case '*':
case '/': return 3;
}
}
void main()
{
char infx[50],pofx[50],ch,elem;
int i=0,k=0,j;
for(j=0;j<=3;j++)
{
printf("\n\nRead the Infix Expression ? ");
scanf("%s",infx);
push('#');
while( (ch=infx[i++]) != '\0')
{
if( ch == '(')
push(ch);
else
if(isalnum(ch))
pofx[k++]=ch;
else
if( ch == ')')
{
while( s[top] != '(')
pofx[k++]=pop();
elem=pop();
}
else
{
while( pr(s[top]) >= pr(ch) )
pofx[k++]=pop();
push(ch);
}
}
while( s[top] != '#')
pofx[k++]=pop();
pofx[k]='\0';
printf("\n\nGiven Infix Expn: %s Postfix Expn: %s\n",infx,pofx);
}
}
When looping through infix to post fix expression,it's not looping beyond 1st loop.
It is producing output of 1st loop and showing segmentation fault for rest of loops
Please can somebody guide me?
Consider an example
given input,
Given Infix Expn: a+b Postfix Expn: ab+
Read the Infix Expression ? a-b
Segmentation fault (core dumped)
you need to reset the index for pofx and infx for every new input. i.e to reset i and k in the for-loop. Fix as below,
void main()
{
char infx[50],pofx[50],ch,elem;
int i=0,k=0,j;
for(j=0;j<=3;j++)
{
i=0;j=0;//here is the update
//rest of your code follows,
}
}
Related
The question is:
WAP to convert a given Prefix expression into its equivalent Postfix
expression and evaluate it using stack.
I have written this code, it takes the input but doesn't display the output.
//header files
#include<stdio.h>
#include<string.h>
//global variables
char stack[50];
int top = -1;
void push(char s)
{
stack[++top]=s;
}
//function to pop an element
char pop()
{
return stack[top--];
}
// funtion to check if the character is operator or not
int is_operator(char x)
{
switch (x)
{
case '+':
case '-':
case '/':
case '*':
return 1;
}
return 0;
}
//function to Convert prefix to Postfix
void convert()
{
int i,l;
char op1,op2,tmp;
char exp[50];
printf("Enter the prefix expression: ");
gets(exp);
//length of expression
l = strlen(exp);
//scanning from right to left
for(i = l - 1; i >= 0; i--)
{
//checking if the symbol is an operator
if (is_operator(exp[i]))
{
//popping two operands from stack
op1 = stack[top];
pop();
op2 = stack[top];
pop();
//concating the operands and operator
tmp = op1 + op2 + exp[i];
//Pushing the temporary string to stack
push(tmp);
}
//if it is an operand
else
{
//push the operand to the stack
push((exp[i]));
}
}
//printf("The postfix expression is: %s",stack[top].c_str());
printf("%s ",stack[top]);
}
//main function
int main()
{
convert();
return 0;
}
when i run the code it takes the prefix expression but immediately after that it crashes and returns to the terminal?
Can anyone please help me with the code i am having difficulty in understanding what mistake i have made.
Also if possible give a little explanation what mistake i did in the code.
In this algorithm, a stack of strings is required. But you are using an array of char.
The exp[i] returns a char. So just can not expect tmp = op1 + op2 + exp[i] to concat them into a string in c.
In c strcpy() can be used to copy a string and strcat() can be used to concat strings.
There are several ways to convert a char to a string of one char tailing NULL. In this code (char[2]){(char)exp[i], '\0'} is used to get a string containing exp[i] and NULL char.
In the solution code there is a memory limitation. The input expression should be in 50 chars (including '\0') .
Solution code :
#include<stdio.h>
#include<string.h>
char stack[50][50];
int top = -1;
void clear_stack() {
top = -1 ;
}
void push(char *s)
{
strcpy(stack[++top], s) ;
}
char* pop()
{
return stack[top--];
}
int is_operator(char x)
{
if(x == '+' ||x == '-'||x == '*'||x == '/'){
return 1;
}
else{
return 0;
}
}
//function to Convert prefix to Postfix
void convert(char *exp)
{
clear_stack() ;
int i,l;
char op1[50],op2[50];
l = strlen(exp);
//scanning from right to left
for(i = l - 1; i >= 0; i--)
{
//checking if the symbol is an operator
if (is_operator(exp[i]))
{
//popping two operands from stack
strcpy(op1, pop()) ;
strcpy(op2, pop()) ;;
//concating the operands and operator
strcat(op1 , strcat(op2 , (char[2]) {(char)exp[i], '\0'})) ;
//Pushing the temporary string to stack
push(op1);
}
//if it is an operand
else
{
//push the operand to the stack
push((char[2]){(char)exp[i], '\0'});
}
}
//printf("The postfix expression is: %s",stack[top].c_str());
printf("%s\n",stack[top]);
}
//main function
int main()
{
convert("*-A/BC-/AKL");
convert("+ab");
convert("*+abc");
convert("*a+bc");
convert("+/ab/cd");
convert("*+ab+cd");
convert("-*+abcd");
return 0;
}
Output :
ABC/-AK/L-*
ab+
ab+c*
abc+*
ab/cd/+
ab+cd+*
ab+c*d-
What I'm trying to obtain is a calculator that will take infix notation, ignore insignificant whitespace characters like " " or '#', then convert that infix notaion into postfix notation and do simple calculations like addition, subtraction etc. So far the code is taking input in infix notation trimming it in a way that ignores insignificant whitespace characters and outputs the postfix notation.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>;
#include <ctype.h>;
#define MAX_LENGTH 100
//Functions
void push(char x);
char pop();
void trimString(char string[], char newString[]);
void inputToRPN(char trimmedExp[], char rpnExp[]);
int calculateRPN(char rpnExp[]);
char stack[MAX_LENGTH];
char resStack[MAX_LENGTH];
int top = -1;
int resTop = -1;
int index = 0;
int main() {
int res;
char exp[MAX_LENGTH] = "10 +2";
char trimmedExpression[MAX_LENGTH];
char rpnExpression[MAX_LENGTH];
// Input commented out as per suggestion in comments
//printf("Enter expression : ");
//fgets(exp, 100, stdin);
printf("Infix expression: %s \n", exp);
trimString(exp, trimmedExpression);
printf("\n");
inputToRPN(trimmedExpression, rpnExpression);
res = calculateRPN(rpnExpression);
//printf("Result of calculation: %d", res);
return 0;
}
void push(char x) {
stack[++top] = x;
}
char pop() {
if (top == -1)
return -1;
else
return stack[top--];
}
int priority(char x) {
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
return 0;
}
void trimString(char string[], char newString[]) {
int i = 0, j = 0;
while (string[i] != '\0' && string[i] != 10) {
// Range of significant characters
if (string[i] >= '(' && string[i] <= '9') {
newString[j] = string[i];
i++, j++;
}
else {
i++;
}
}
newString[j] = 0;
}
void inputToRPN(char trimmedExp[], char rpnExp[]) {
char* e, x;
e = trimmedExp;
while (*e != '\0') {
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
// Add to stack if is an open brace
else if (*e == '(')
push(*e);
// Add all operators to the expression until finding open braces
else if (*e == ')') {
while ((x = pop()) != '(') {
rpnExp[index] = x;
index++;
}
}
// If none of the above, that is an operator - check it's priority.
// If it's priority is less that that of the one on top of the stack add the operator from the top of the stack to the expression; untill it's priority is higher.
// At the end add current operator to the stack.
else {
while (priority(stack[top]) >= priority(*e)) {
rpnExp[index] = pop();
index++;
}
push(*e);
}
e++;
}
while (top != -1) {
rpnExp[index] = pop();
index++;
}
// Terminating character at the end of the string
rpnExp[index] = 0;
}
void pushRes(char x) {
printf("pushing: %c \n", x);
resStack[++resTop] = x;
}
char popRes() {
printf("poping \n");
if (resTop == -1)
return -1;
else
return resStack[resTop--];
}
int isValidOperator(char c) {
if (c == '/' || c == '*' || c == '+' || c == '-')
return 1;
else
return 0;
}
int calculateRPN(char rpnExp[]) {
// Doesnt do anything yet, just prints out the compiled reverse polish notation
char* c;
int result = 0;
c = rpnExp;
printf("Postfix expression: %s", rpnExp);
return result;
}
The problem I've stumbled upon is when the infix input has multiple digits say 10+2 the code will treat each digit individually. Therefore the whole expression will be invalid when calculating result. I'm almost certain the issue lies in this line of code:
// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
Despite that I've got no idea how should i treat multiple digits while adding them to the expression, since the input is in form of character and there can be N amount of digits that have coresponding ascii values which range from 0-9. Looking forward to your answears.
Edit: made it so the code compiles and the input is hard coded.
Okay, so thanks to Bodos suggestions I've fixed the issue. Adding one while loop in this section:
if (isalnum(*e)) {
rpnExp[index] = *e;
index++;
}
enabled me to add one character after every number (including the N digit ones).
Thanks to which I was later able to perform calculations in calculateRPN function that would eventually lead to correct answear.
The issue has been resolved.
I am trying to implement an infix-to-postfix conversion program. On executing the code I get to see only alpha-numeric characters. Arithmetic operators are not printing. Upon debugging, I found the operators are not inserting in the stack. I couldn't find out the reason behind this.
Any help is appreciated.
#include<stdio.h>
#include <ctype.h>
#define MAX 50
char st[MAX];
int top = -1;
void push(char);
char pop();
int priority(char);
int main()
{
int i=0;
char x,s[50];
printf("Enter infix expression: ");
gets(s);
while(s[i]!='\0')
{
if(isalnum(s[i]))
printf("%c",s[i]);
else if(s[i] == '(')
push(s[i]);
else if(s[i] == ')')
{
while((x=pop())!='(')
printf("%c",x);
}
else
{
while(priority(st[top])>=priority(s[i]))
printf("%c",pop());
push(st[i]);
}
i++;
}
while(top!=-1)
printf("%c",pop());
}
void push(char x)
{
st[++top] = x;
}
char pop()
{
if(top == -1)
return -1;
else
return (st[top--]);
}
int priority(char x)
{
if(x == '(')
return 0;
if(x == '+' || x == '-')
return 1;
if(x == '*' || x == '/' || x == '%')
return 2;
}
As you correctly detected on your debugging session, you don't see operators in your postfix expression because you never push() them to your stack.
In fact
in the first if you check for alphanumeric characters
in the following else if you check for opening parenthesis
in the second else if you check for closing parenthesis
in the final else you manage pops from stack... but you didn't push anything! (1)
What you need to fix is the last else, where you have at least two distinct problems:
You access st[top] without checking top value. You need to manage the case in which top = -1, that would lead to out of bounds access of the stack array and to undefined behavior. I think that in that scenario you just need to push the operator
You push in the stack st[i]. Probably you meant s[i]
In this way the while analysing the expression becomes
while(s[i]!='\0')
{
if(isalnum(s[i]))
printf("%c ",s[i]);
else if(s[i] == '(' )
push(s[i]);
else if(s[i] == ')')
{
while((x=pop())!='(')
printf("%c ",x);
}
else
{
if( top != -1 )
{
while(priority(st[top])>=priority(s[i]))
printf("%c ",pop());
}
push(s[i]);
}
i++;
}
Input:
4*6+3
Output:
4 6 * 3 +
(I added a further space after each %c in printfs in order to improve output readability).
Note: You still have to fix some problems in operators priority management.
I have written my code to evaluate from postfix to result. However, I am stuck at how to do it when the postfix is going to be in decimals & floating point numbers in scientific e notation - e.g. {1.23e4}. Any specific suggestion would be highly appreciated. Thanks.
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#define SIZE 50 /* Size of Stack */
double s[SIZE];
int top=-1; /* Global declarations */
int flag=0;
double pop()
{ /* Function for POP operation */
return(s[top--]);
}
double push(double elem)
{ /* Function for PUSH operation */
if(flag==1){
int num;
num=pop();
s[++top]=elem+10*num;
}
else if(flag==0){
s[++top]=elem;
flag=1;
}
}
void main()
{ /* Main Program */
char pofx[50],ch;
int i=0;
double op1,op2;
printf("Enter the Postfix Expression:");
fgets(pofx,100,stdin);
while( (ch=pofx[i++]) != '\n')
{
if(isdigit(ch)) push(ch-'0'); /* Push the operand */
else if(ch==' ')
flag=0;
else
{ /* Operator,pop two operands */
flag=0;
op2=pop();
op1=pop();
switch(ch)
{
case '+':push(op1+op2);break;
case '-':push(op1-op2);break;
case '*':push(op1*op2);break;
case '/':push(op1/op2);break;
case '^':push(pow(op1,op2));break;
default:
printf("Input invalid ... give proper input\n");
return 0;
}
}
}
printf("Result: %lf\n",s[top]);
}
How do I evaluate decimals & floating point numbers in scientific e notation ... (?)
To convert a string into FP value use strtod() #M Oehm
Yet code has other problems in that the operator symbols '-' and '+' may also begin valid value tokens like -123.45.
// insufficient test to determine if the next part of the string is a number or operator.
if(isdigit(ch))
push(ch-'0');
Use strtod() to convert text to double and determine if the next part of the string is a double.
Alternative code:
const char *st = pofx;
while (*st) {
char *end; //location to store end of FP parsing
double value = strtod(st, &end);
if (end > st) {
push(value);
st = end;
} else if (isspace((unsigned char) *st)) {
st++;
} else {
switch (*st) {
case '+':push(pop() + pop());break; // pop order irrelevant
case '-':{ double t = pop(); push(pop() - t);break; } // pop order relevant
case '*':push(pop() * pop());break;
...
default: {
printf("Input invalid operator: character code %d\n", *st);
return 0;
}
} // end switch
st++;
}
}
Re-write push()
void push(double elem) {
if (top + 1 >= SIZE) {
printf("Stack overflow\n");
return;
}
s[++top] = elem;
}
Wrong argument to fgets()
char pofx[50];
// fgets(pofx,100,stdin); // 100??
fgets(pofx, sizeof pofx, stdin); // better
The function strtod from <stdlib.h> will parse a double for you. It takes the string to parse and a pointer to a string, that will begin with the first unparsed character. (There's a similar function for long integers, strtol.)
Here's an example of how this might work in your case. (The code just prints out the tokens and doesn't do any calculations.)
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int is_number(const char *p)
{
if (*p == '-' || *p == '+') p++;
if (*p == '.') p++;
return isdigit((unsigned char) *p);
}
int main(void)
{
const char *line = " .1 20.1* 1.0e-3+2e+7 * -1.0*";
const char *p = line;
while (isspace((unsigned char) *p)) p++;
while (*p) {
if (is_number(p, after_op)) {
char *end;
double x = strtod(p, &end);
if (p == end) {
puts("Illegal number");
p++;
} else {
printf("Number %g\n", x);
p = end;
}
} else {
int c = *p++;
switch (c) {
case '+': puts("Operator add"); break;
case '-': puts("Operator sub"); break;
case '*': puts("Operator mult"); break;
case '/': puts("Operator div"); break;
case '^': puts("Operator pow"); break;
default: printf("Illegal char '%c'\n", c);
}
}
while (isspace((unsigned char) *p)) p++;
}
return 0;
}
This is still very crude, mind you. Strings like 20x21 will be parsed as number 20, unknown character x and number 21. While this code is bad at detecting and reporting errors (which really should be done, but it's left as an exercise, yadda, yadda), it works for valid input.
[Edit: I've incorporated chux's suggestions and also made the code compatible to read numbers with explicit signs, but that means that the binary operators - and + cannot immediately be followed by a digit. Pick your poison. I've also allowed the abridged version that leaves out a leading zero, e.g. .12, a format that I'm not very fond of.]
My code runs well to my surprise!!
The only problem is that whenever I use a bracketed infix input it comes out a 'J' at the end of postfix expression !! Any suggestions??
Here the algorithm is the basic one all expressions are getting converted and all is right but the tailing 'J' is i just cann't understand !! Suggestions??
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX 50
char stack[MAX];
int top = -1;
void push(char element)
{
stack[++top] = element;
}
char pop()
{
return(stack[top--]);
}
char tope()
{
return(stack[top]);
}
int prec(char c)
{
switch(c){
case '+':
case '-' : return 1;
break;
case '*' :
case '/' : return 2;
break;
default:
return 0;
break;
}
}
int main()
{
char post[MAX],in[MAX],ch,element;
printf("Infix expression : ");
scanf("%s",in);
int i=0,k=0;
in[strlen(in)] = ')';
push('(');
while((ch = in[i++]) != '\0')
{
if(isalnum(ch))
post[k++] = ch;
if(ch == '(')
push(ch);
if(ch == ')')
{
while(tope() != '(')
{
post[k++] = pop();
}
pop();
}
if(ch == '+' || ch =='-' || ch == '*' || ch == '/')
{
while(prec(ch) <= prec(tope()))
{
post[k++] = pop();
}
push(ch);
}
}
post[k] = '\0';
printf("%s",post);
return 0;
}
in[strlen(in)] = ')';
overwrites the nul-terminating character, which explains strange chars when printing (printing stops only when meeting another nul char by luck: undefined behaviour which may even lead to a crash if no nul char is found in the in 50-byte buffer)
You have to shift it, for instance like this:
int l = strlen(in);
in[l] = ')';
in[l+1] = '\0';
Note: you have to store the length of your string in l instead of calling strlen(in) twice not only because of the performance loss but, because putting the parenthesis means that strlen doesn't work properly until you null-terminate.
(also you probably want to protect your scanf like this: scanf("%48s",in); so you're sure to have enough room for the extra parenthesis for your 50-size buffer, even compatible with your macro definition, see scanf: template with macro (#define constant) inside)