Wrong answer from a program (infix notation->postfix notation) in C - c

I made a program which changes infix notation to postfix notation with using stack in C.
I made a function which prints the result of the postfix notation(from infix notaton).
But, the result of a notation is wrong. This should be '195' but its result is '-61'.
The results of the other notations are right but only the notation(op2) has this problem.
What should I do to fix this problem?
This is my code:
typedef char element;
typedef struct {
element stack[MAX_STACK_SIZE];
int top;
} StackType;
void init(StackType *s) {
s->top = -1;
}
int is_empty(StackType *s) {
return (s->top == -1);
}
int is_full(StackType *s) {
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType *s, element item) {
if (is_full(s)) {
fprintf(stderr, "FULL STACK ERROR\n");
return;
}
else s->stack[++(s->top)] = item;
}
element pop(StackType *s) {
if (is_empty(s)) {
fprintf(stderr, "EMPTY STACK ERROR\n");
exit(1);
}
else return s->stack[(s->top)--];
}
int eval(char exp[]) {
int op1, op2, value, i = 0;
int len = strlen(exp);
char ch;
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
if (ch != '+' && ch != '-' && ch != '*' && ch != '/') {
value = ch - '0';
push(&s, value);
}
else {
op2 = pop(&s);
op1 = pop(&s);
switch (ch) {
case '+': push(&s, op1 + op2); break;
case '-': push(&s, op1 - op2); break;
case '*': push(&s, op1 * op2); break;
case '/': push(&s, op1 / op2); break;
}
}
}
return pop(&s);
}
char* infix_to_postfix(char exp[]) {
int i = 0, j = 0;
char ch, top_op;
int len = strlen(exp);
char *ex = (char *)malloc(sizeof(char)*(len + 1));
StackType s;
init(&s);
for (i = 0; i < len; i++) {
ch = exp[i];
switch (ch) {
case '+': case '-': case '*': case '/':
while (!is_empty(&s) && (prec(ch) <= prec(peek(&s)))) {
ex[j++] = pop(&s);
}
push(&s, ch);
break;
case '(':
push(&s, ch);
break;
case ')':
top_op = pop(&s);
while (top_op != '(') {
ex[j++] = top_op;
top_op = pop(&s);
}
break;
default:
ex[j++] = ch;
break;
}
}
while (!is_empty(&s)) {
ex[j++] = pop(&s);
}
ex[j] = NULL;
return ex;
}
void main() {
char *op1 = "(9-(3+2))*3+4*((4+2)/3)-1";
char *op2 = "(4*5-3)/3+((2+5*7)-8+9)*5";
char *op3 = "7*3-7-4+1/3+6-8*2";
char *pos1, *pos2, *pos3;
pos1 = infix_to_postfix(op1);
pos2 = infix_to_postfix(op2);
pos3 = infix_to_postfix(op3);
printf(" Result : %d\n", eval(pos1));
printf(" Result : %d\n", eval(pos2));
printf(" Result : %d\n", eval(pos3));
}
[RESULT]
Result : 19
Result : -61 // This should be '195'.
Result : 0

The clue is 61+195 = 256. Which means that somewhere, your computations are being saved to chars. Looks like it is element.
typedef element int;

Related

I am doing a mini project on stack applications, and get errors

The program:
evaluates postfix and prefix expressions
reverse a string
parenthesis balancing
decimal to binary conversion
infix to postfix conversion
There a some extra characters (emojis) appended in the output. I would like to fix that.
Also I have used two pop functions with int and char return type how can I reduce it to one single function.
extra characters in the output of decimal to binary conversion, also that one extra left parenthesis when printing "balanced parenthesis"
This a first year college project.
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int stack[MAX], opp1, opp2, top = -1;
struct stack
{
char stck[20];
int top;
}
s;
void push(int x)
{
top++;
stack[top] = x;
}
int pop()
{
char c;
c = stack[top];
top = top - 1;
printf("%c", c);
}
char pop1()
{
if (top == -1)
return -1;
else
return stack[top--];
}
void postfixeval()
{
char postfix[20];
int res, i;
gets(postfix);
for (i = 0; postfix[i] != '\0'; i++)
{
if (isdigit(postfix[i]))
{
push(postfix[i] - 48);
}
else
{
opp2 = pop();
opp1 = pop();
switch (postfix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
break;
}
}
}
printf("result is %d \n", pop());
}
void prefixeval()
{
int len;
char prefix[20];
int res, i;
gets(prefix);
len = strlen(prefix);
for (i = len - 1; i >= 0; i--)
{
if (isdigit(prefix[i]))
{
push(prefix[i] - 48);
}
else
{
opp1 = pop();
opp2 = pop();
switch (prefix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
push(res);
break;
}
}
}
printf("result is %d \n", pop());
}
int match(char a, char b)
{
if (a == '[' && b == ']')
return 1;
if (a == '{' && b == '}')
return 1;
if (a == '(' && b == ')')
return 1;
}
int check(char exp[])
{
int i;
char temp;
for (i = 0; i < strlen(exp); i++)
{
if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
push(exp[i]);
if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
if (top == -1)
{
return 0;
}
else
{
temp = pop();
if (!match(temp, exp[i]))
{
printf("Mismatched parentheses are : ");
printf("%c and %c\n", temp, exp[i]);
return 0;
}
}
}
if (top == -1)
{
printf("Balanced Parentheses\n");
return 1;
}
else
{
return 0;
}
}
void dectobin(int n)
{
while (n != 0)
{
push(n % 2);
n = n / 2;
}
while (top != -1)
{
printf("%d", pop());
}
}
int priority(char x)
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
void intopost()
{
char exp[100];
char *e, x;
printf("Enter the expression : \n");
scanf("%s", exp);
printf("\n");
e = exp;
while (*e != '\0')
{
if (isalnum(*e))
printf("%c ", *e);
else if (*e == '(')
push(*e);
else if (*e == ')')
{
while ((x = pop1()) != '(')
printf("%c ", x);
}
else
{
while (priority(stack[top]) >= priority(*e))
printf("%c ", pop1());
push(*e);
}
e++;
}
while (top != -1)
{
printf("%c ", pop1());
}
}
int main()
{
int ch, i, len;
char postfix[20], prefix[20], str[30];
do {
printf("\n----STACK APPLICATIONS----\n");
printf("1.postfix expression evaluation\n2.prefix expression evaluation\n3.reverse a string\n4.paranthesis balancing\n5.decimal to binary\n6.infix to postfix\n7.exit\n");
printf("enter choice");
scanf("%d", &ch);
switch (ch)
{
case 1:
{
printf("enter postfix expression\n");
scanf("%c", &postfix);
postfixeval();
break;
}
case 2:
{
printf("enter prefix expression\n");
scanf("%c", prefix);
prefixeval();
break;
}
case 3:
{
printf("enter string\n");
scanf("%s", str);
len = strlen(str);
for (i = 0; i < len; i++)
{
push(str[i]);
}
printf("reversed string is:");
for (i = 0; i < len; i++)
{
pop();
}
break;
}
case 4:
{
char exp[20];
int valid;
printf("Enter an algebraic expression : \n");
scanf("%s", exp);
valid = check(exp);
if (valid == 1)
{
printf("Valid expression\n");
}
else
{
printf("Invalid expression\n");
}
break;
}
case 5:
{
int dec;
printf("enter decimal number\n");
scanf("%d", &dec);
dectobin(dec);
break;
}
case 6:
{
intopost();
break;
}
case 7:
{
exit(0);
}
default:
printf("invalid choice\n");
}
} while (ch != 7);
}
Here are the additional characters appended with the output
Here is one 'improvement' that you should learn about 'C'.
printf(
"1.postfix expression evaluation\n"
"2.prefix expression evaluation\n"
"3.reverse a string\n"
"4.paranthesis balancing\n"
"5.decimal to binary\n"
"6.infix to postfix\n"
"7.exit\n"
);
The compiler will 'join-up' those 'segments' (because there is no comma between a close quote and the next open quote.)
Once you have that, you can go back to basics and get this much displaying and functioning:
printf(
// "1.postfix expression evaluation\n"
// "2.prefix expression evaluation\n"
// "3.reverse a string\n"
// "4.paranthesis balancing\n"
// "5.decimal to binary\n"
// "6.infix to postfix\n"
"7.exit\n"
);
Don't try to run before you can walk...
To demonstrate 'incremental development' and 'learning/exploring':
// test.c - string segments in source code
#include <stdio.h>
int main() {
printf(
"Hello "
"World!\n"
);
return 0;
}

C program data structure stack calculator [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I'm studying about data structure coding.
I built a calculator using a stack.
infix to postfix and result
However, I want to get the result after all completing the input.
And I want to "out" the input with an end.
the last line is example when it debug.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100
enum {
lparen = -9,
rparen,
plus,
minus,
times,
divide,
mod,
eos,
operand
};
int stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE], postexpr[MAX_EXPR_SIZE];
int pos = 0;
static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 };
static int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 };
void add_stack(int *top, int item) {
if (*top >= MAX_STACK_SIZE - 1)
printf("Error: Stack is full\n");
stack[++*top] = item;
}
int delete_stack(int *top) {
if (*top == -1)
printf("Error: Stack is empty\n");
return stack[(*top)--];
}
int get_token(char *symbol, int *n) {
*symbol = expr[(*n)++];
switch (*symbol) {
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '-': return minus;
case '*': return times;
case '/': return divide;
case '%': return mod;
case 0:
case '\n': return eos;
default: return operand;
}
}
void print_token(int p) {
switch (p) {
case plus:
printf("+");
postexpr[pos++] = '+';
break;
case minus:
printf("-");
postexpr[pos++] = '-';
break;
case times:
printf("*");
postexpr[pos++] = '*';
break;
case divide:
printf("/");
postexpr[pos++] = '/';
break;
case mod:
printf("%");
postexpr[pos++] = '%';
break;
case eos:
printf(" ");
break;
}
}
void postfix(void) {
char symbol;
int token;
int n = 0;
int top = 0;
stack[0] = eos;
token = get_token(&symbol, &n);
for(; token != eos; token = get_token(&symbol, &n)) {
if (token == operand) {
printf("%c", symbol);
postexpr[pos++] = symbol;
}
else if (token == rparen) {
while (stack[top] != lparen)
print_token(delete_stack(&top));
delete_stack(&top);
} else {
while (isp[stack[top] + 9] >= icp[token + 9])
print_token(delete_stack(&top));
add_stack(&top, token);
}
}
while ((token = delete_stack(&top)) != eos)
print_token(token);
printf("\n");
}
int eval(void) {
int token;
char symbol;
int op1, op2;
int n = 0;
int top = 0;
stack[0] = eos;
token = get_token(&symbol, &n);
for(; token != eos; token = get_token(&symbol, &n)) {
if (token == operand)
add_stack(&top, symbol - '0');
else {
op2 = delete_stack(&top);
op1 = delete_stack(&top);
switch (token) {
case plus: add_stack(&top, op1 + op2); break;
case minus: add_stack(&top, op1 - op2); break;
case times: add_stack(&top, op1 * op2); break;
case divide: add_stack(&top, op1 / op2); break;
case mod: add_stack(&top, op1 % op2); break;
}
}
}
return delete_stack(&top);
}
int main(void) {
printf("Input expression : ");
scanf("%s", expr);
printf("Postfix expression: ");
postfix();
strcpy(expr, postexpr);
printf("Evaluation of the expression : %d", eval());
}
this is example when it done
input //
(8*6)+2/4
(8*6)+4/2
out //
print//
postfix (8*6)+2/4
result (8*6)+2/4
postfix (8*6)+4/2
result (8*6)+4/2
//
Here are some problems and possible improvements to your code:
printf("%") has undefined behavior. You should write printf("%%") or simply putchar('%')
you should parse numbers with multiple digits
you should skip spaces and TABs
you should detect invalid characters
you should detect invalid expressions
you should not use global variables
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100
enum {
error = -10,
lparen = -9,
rparen,
plus,
minus,
times,
divide,
mod,
eos,
operand, /* 0 and above are operand values */
};
static int const isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 };
void add_stack(int *stack, int *top, int item) {
if (*top >= MAX_STACK_SIZE - 1) {
printf("Error: Stack is full\n");
return;
}
stack[++*top] = item;
}
int delete_stack(int *stack, int *top) {
if (*top < 0) {
printf("Error: Stack is empty\n");
return eos;
}
return stack[(*top)--];
}
int get_token(const char *expr, int *pos) {
for (;;) {
int c = expr[*pos];
if (c == '\0' || c == '\n')
return eos;
*pos += 1;
if (c == ' ' || c == '\t')
continue;
if (c >= '0' && c <= '9') {
int value = c - '0';
while ((c = expr[*pos]) >= '0' && c <= '9') {
*pos += 1;
value = value * 10 + (c - '0');
}
return value;
}
switch (c) {
case '(': return lparen;
case ')': return rparen;
case '+': return plus;
case '-': return minus;
case '*': return times;
case '/': return divide;
case '%': return mod;
default: *pos -= 1; return error;
}
}
}
void print_token(char *postexpr, int *ppos, int token) {
int pos = *ppos;
switch (token) {
case error: postexpr[pos++] = '?'; break;
case lparen: postexpr[pos++] = '('; break;
case rparen: postexpr[pos++] = ')'; break;
case plus: postexpr[pos++] = '+'; break;
case minus: postexpr[pos++] = '-'; break;
case times: postexpr[pos++] = '*'; break;
case divide: postexpr[pos++] = '/'; break;
case mod: postexpr[pos++] = '%'; break;
case eos: break;
default:
/* insert a space between numbers */
if (pos > 0 && postexpr[pos - 1] >= '0' && postexpr[pos - 1] <= '9')
postexpr[pos++] = ' ';
pos += sprintf(postexpr + pos, "%d", token);
break;
}
*ppos = pos;
postexpr[pos] = '\0';
}
int put_error(const char *message, const char *expr, int col) {
if (col < 0) {
printf("%s\n", message);
} else {
printf("%s at column %d\n", message, col + 1);
printf("%s\n%*s\n", expr, col + 1, "^");
}
return -1;
}
int postfix(const char *expr, char *postexpr) {
int stack[MAX_STACK_SIZE];
int token, n = 0, top = 0, pos = 0, last = eos;
stack[0] = eos;
while ((token = get_token(expr, &n)) != eos) {
if (token == error) {
return put_error("syntax error", expr, n);
}
if (token >= operand) {
if (last >= operand) {
return put_error("missing operator", expr, n - 1);
}
print_token(postexpr, &pos, token);
} else
if (token == rparen) {
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n - 1);
}
while (stack[top] != lparen) {
if (stack[top] == eos) {
return put_error("invalid parenthesis", expr, n - 1);
}
print_token(postexpr, &pos, delete_stack(stack, &top));
}
delete_stack(stack, &top);
} else {
if (token == lparen) {
if (last >= operand || last == rparen) {
return put_error("missing operator", expr, n - 1);
}
} else {
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n - 1);
}
while (isp[stack[top] - lparen] >= isp[token - lparen]) {
print_token(postexpr, &pos, delete_stack(stack, &top));
}
}
add_stack(stack, &top, token);
}
last = token;
}
if (last < operand && last != rparen) {
return put_error("missing operand", expr, n);
}
while ((token = delete_stack(stack, &top)) != eos) {
if (token == lparen) {
return put_error("unmatched parenthesis", expr, -1);
}
print_token(postexpr, &pos, token);
}
return 0;
}
int eval(const char *expr) {
int stack[MAX_STACK_SIZE];
int token, n = 0, top = 0;
stack[0] = eos;
while ((token = get_token(expr, &n)) != eos) {
if (token >= operand) {
add_stack(stack, &top, token);
} else {
int op2 = delete_stack(stack, &top);
int op1 = delete_stack(stack, &top);
switch (token) {
case plus: add_stack(stack, &top, op1 + op2); break;
case minus: add_stack(stack, &top, op1 - op2); break;
case times: add_stack(stack, &top, op1 * op2); break;
case divide: add_stack(stack, &top, op1 / op2); break;
case mod: add_stack(stack, &top, op1 % op2); break;
}
}
}
return delete_stack(stack, &top);
}
int main() {
char expr[100], postexpr[200];
for (;;) {
printf("Input expression: ");
if (scanf("%99s", expr) != 1)
break;
if (!postfix(expr, postexpr)) {
printf("Postfix expression: %s\n", postexpr);
printf("Evaluation of the expression: %d\n", eval(postexpr));
}
}
printf("Done.\n");
return 0;
}
Sample run:
Input expression: 1
Postfix expression: 1
Evaluation of the expression: 1
Input expression: 1+
missing operand at column 3
1+
^
Input expression: 1+1
Postfix expression: 1 1+
Evaluation of the expression: 2
Input expression: (1+2*3)
Postfix expression: 1 2 3*+
Evaluation of the expression: 7
Input expression: (1+2*3)*(3+4*5/6)
Postfix expression: 1 2 3*+3 4 5*6/+*
Evaluation of the expression: 42
Input expression: Done.

RPN with C language

I have problem with this code, It works fine with small values but with big values it crash.
for Example.
input:
1+2+3
output:
Expression:
1+2+3
Reverse Polish Notation:
12+3+
Result:
6
but with this example it crash
input:
100+2*100/50
output:
runtime-error
This code is converting infix to postfix and this calculate the RPN.
// C program to convert infix expression to postfix
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct Stack
{
int top;
unsigned capacity;
int* array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack = (struct Stack*)
malloc(sizeof(struct Stack));
if (!stack)
return NULL;
stack->top = -1;
stack->capacity = capacity;
stack->array = (int*)malloc(stack->capacity *
sizeof(int));
return stack;
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1;
}
char peek(struct Stack* stack)
{
return stack->array[stack->top];
}
char pop(struct Stack* stack)
{
if (!isEmpty(stack))
return stack->array[stack->top--];
return '$';
}
void push(struct Stack* stack, char op)
{
stack->array[++stack->top] = op;
}
int isOperand(char ch)
{
return (ch >= '0' && ch <= '9');
}
int Prec(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
int infixToPostfix(char* exp)
{
int i, k;
struct Stack* stack = createStack(strlen(exp));
if (!stack)
return -1;
for (i = 0, k = -1; exp[i]; ++i)
{
if (isOperand(exp[i]))
exp[++k] = exp[i];
else if (exp[i] == '(')
push(stack, exp[i]);
else if (exp[i] == ')')
{
while (!isEmpty(stack) && peek(stack) != '(')
exp[++k] = pop(stack);
if (!isEmpty(stack) && peek(stack) != '(')
return -1;
else
pop(stack);
}
else
{
while (!isEmpty(stack) &&
Prec(exp[i]) <= Prec(peek(stack)))
exp[++k] = pop(stack);
push(stack, exp[i]);
}
}
while (!isEmpty(stack))
exp[++k] = pop(stack);
exp[++k] = '\0';
printf("Reverse Polish Notation:\n");
char str[10];
strcpy(str, exp);
for (int i = 0; str[i]; i++)
{
printf("%c ", str[i]);
}
printf("\n");
}
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if (isdigit(exp[i]))
push(stack, exp[i] - '0');
else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2 / val1); break;
}
}
}
return pop(stack);
}
int main()
{
//char exp[] = "1+2+3";
char exp[10];
scanf("%14s", exp);
printf("Expression:\n%s\n", exp);
infixToPostfix(exp);
printf("Result:\n%d", evaluatePostfix(exp));
return 0;
}

Evaluating a postfix expression using expression tree in C

I can't seem to get this program to work, it is a doubly linked list representation of expression tree. After creating the tree I need to evaluate the result but I can't seem to figure out how.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])+'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return result;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
I'm having trouble converting and returning the characters as integers.
UPDATE 1: I was able to make it solve single digit number inputs to recieve a multi digit result. I'm still working on a new data structure to compute multi digit numbers. Here's the updated code below.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])-'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return root->item;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
In operandFunc(expression[count]); you are only processing one character. That means you cannot work with multi-character operands like 10 or 123. If these occur, you push each digit separately. So your language is limited to single digit numbers (OK; your decission).
In solve you say printf("Root Item = %c and %d\n",temp->item,temp->item);
. Here, the second argument must be converted to an int: temp->item-'0'. You have to do that whenever you use %d in the printf format.
The rest of your code looks fine. Maybe set a higher warning level when compiling to find more errors?
EDIT/ADDITION:
How to handle multi-digit numbers?
The following snippet handles multi-digit numbers. You must adapt your struct to make a difference between chars and ints and change operandFunc to handle these numbers:
while((c=getchar())!='\n')
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(c);
break;
default: // assume digit(s)
num= c-'0';
while ((c=getchar())!='\n' && isdigit(c)) num= num*10+c-'0';
operandFunc(num);
ungetc(c,stdin);
}
}
We can evaluate the postfix expression using the binary tree by keeping in mind the two conditions
if
eval(root) is an operator we use recursion, eval(root->llink) + eval(root->rlink)
else
we return root->info - '0'
Function for evaluation
float evaluate(NODE root)
{
float num;
switch(root->info)
{
case '+' : return eval(root->llink) + eval(root->rlink);
case '-' : return eval(root->llink) - eval(root->rlink);
case '/' : return eval(root->llink) / eval(root->rlink);
case '*' : return eval(root->llink) * eval(root->rlink);
case $ :
case ^ : return pow( eval(root->llink) ,eval(root->rlink));
default : if(isalpha(root->info))
{
printf("%c" = root->info);
scanf("%f",&num);
return num;
}
else
return root->info - '0';
}
}

Using a stack to do an infix to postfix

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "stack.h"
#define MAX_EQU_LEN 100
static int prec(char operator)
{
switch (operator)
{
case '*':
return 5;
case '/':
return 4;
case '%':
return 3;
case '+':
return 2;
case '-':
return 1;
default:
break;
}
return 0;
}
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
char* infix_to_postfix(char* infix)
{
char* postfix = malloc(MAX_EQU_LEN);
stack* s = create_stack();
s->size = strlen(infix);
node* tempPtr = s->stack;
unsigned int i;
char symbol,next;
char temp[2] = {0};
for(i = 0; i < s->size ; i++)
{
symbol = *((infix + i));
temp[0] = symbol;
tempPtr = s->stack;
if(isNumeric(temp) != 1)
{
strcat(postfix, temp);
}
else if(symbol == '(')
{
push(s, symbol);
}
else if(symbol == ')')
{
while(s->size != 0 && top(s) != '(')
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix, temp);
tempPtr = s->stack;
if(tempPtr->data == '(')
{
pop(s);
}
}
}
else
{
while(s->size != 0 && prec(top(s)) > prec(symbol))
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix,temp);
push(s,next);
}
}
while(s->size != 0)
{
next = tempPtr->data;
temp[0] = next;
pop(s);
strcat(postfix, temp);
}
}
return postfix;
}
int evaluate_postfix(char* postfix) {
//For each token in the string
int i,result;
int right, left;
char ch;
stack* s = create_stack();
node* tempPtr = s->stack;
for(i=0; i < strlen(postfix); i++){
//if the token is numeric
ch = postfix[i];
if(isNumeric(&ch)){
//convert it to an integer and push it onto the stack
atoi(&ch);
push(s, ch);
}
else
{
pop(&s[0]);
pop(&s[1]);
//apply the operation:
//result = left op right
switch(ch)
{
case '+': push(&s[i],right + left);
break;
case '-': push(&s[i],right - left);
break;
case '*': push(&s[i],right * left);
break;
case '/': push(&s[i],right / left);
break;
}
}
}
tempPtr = s->stack;
//return the result from the stack
return(tempPtr->data);
}
This code is part of a bigger program that is designed to convert simple math from infix to postfix and then evaluate it. This will be aided by a stack to hold the numbers and symbols. However when I run the program it seg faults and all the debugger says is that it is in the infix_to_postfix function and I cannot figure out what part of the code makes it seg fault.

Resources