removing redundant braces from Spoj - c

I new at solving problems using C , I am trying to solve a SPOJ problem on
complicated Expression
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void removeBrackets(char *string , int position1 , int position2);
int main()
{
char exp[]="(a+b)-(c-d)-(e/f)";
char ops[]={'/','*','+','-','(',')','\0'};
char found[50][5];
int stack[3];
int i,j , k =0;
int l = (int)strlen(exp);
int lExp = l ;
char *p = exp ;
// //remove external brackets
// while (*(p+0)=='(' && *(p+strlen(p)-1)==')')
// removeBrackets(exp, 0, ((int)strlen(p)-1));
printf("expression : %s\n",exp);
printf("operators : %s\n",ops);
//find the operators and their location
l = 0 ;
for(i=0;i<lExp;i++)
{
for(j=0;j<strlen(ops);j++)
{
if(exp[i]==ops[j])
{
found[l][2]='N';
found[l][0]=i;
found[l][1]=ops[j];
if (exp[i-2]=='(' && exp[i+2]==')')
{
found[l][2]='Y';
found[l][3]=exp[i-3];
found[l][4]=exp[i+3];
}
if (found[l][1]=='(')
{
stack[k] = found[l][0];
k++;
}
else if(found[l][1]==')')
{
stack[k] = found[l][0];
if (stack[0] == 0 && stack[1] == lExp-1)
{
removeBrackets(exp, 0, (int)strlen(exp)-1);
break ;
}
removeBrackets(exp, stack[k-1], stack[k]);
//stack[k] = -1 ;
//stack[k-1] = -1 ;
k--;
}
printf("found '%c' at '%d' and within brackets: %c\n",found[l][1],found[l][0],found[l][2]);
l++;
}
}
}
//find where brackets are the corresponding sign in the brackets
for (i=0; i<l-1; i++)
{
if(found[i][2]=='Y')
{
//find higher precedence operators present nearby , and if their precedence is lower , then remove the brackets ,else keep the brackets
//1-find the operator inside the brackets
switch (found[i][1])
{
case '/':
printf("\nfound '/' within brackets");
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
//remove the brackets
break;
case '*':
printf("\nfound '*' within brackets");
if (found[i][3] == '/' || found[i][4] == '/')
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
case '+':
printf("\nfound '+' within brackets");
if (found[i][3] == '/' || found[i][4] == '/' || found[i][3] == '*' || found[i][4] == '*' )
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
case '-':
printf("\nfound '-' within brackets");
if (found[i][3] == '/' || found[i][4] == '/' || found[i][3] == '*' || found[i][4] == '*' || found[i][4] == '+' || found[i][3] == '+')
break ;
else
removeBrackets(exp, found[i][0]-2, found[i][0]+2);
break;
default:
break;
}
}
}
printf("\nstring modified : %s",exp);
}
void removeBrackets(char *string, int position1 , int position2)
{
char *p = string;
char *newString = (char *)malloc(strlen(string -1));
int i = 0 , j =0 ;
for (i = 0 ; i <strlen(string); i++)
{
if (i == position1 || i == position2)
continue ;
else
{
newString[j] = *(p+i);
j++ ;
}
}
newString[j]='\0';
strcpy(string, newString);
printf("\n-----after removing brackets :- %s\n",newString);
free(newString);
}
What i am doing is , scanning all the words , then storing the found operators and brackets in an array 'Found' , stack is an array to check the sequence of '(' and ')' and 'ops' is an array to store all possible operators and brackets ,
then , if an operator is found within the brackets , then depending on the precendence of operators at left and right , brackets are removed .
But , after trying a lot , i am not able to come up with solution to remove brackets , for all test cases .
I searched on internet , they have used tree to solve this problem .
Can anybody please suggest some changes in my code to solve out the problem ..??
or is it that , the problem cannot be solved without trees ??

Related

Program in c regarding balance of parenthesis using stack not working

I wrote this program in c to check whether the parenthesis is balanced or not using the concept of stack.
#include<stdio.h>
#include<string.h>
#define MAX 100
int top = -1;
int arr[MAX];
void push(int x)
{
if (top == (MAX - 1))
{
printf("error:stack overflow n");
return;
}
top++;
arr[top] = x;
}
void pop()
{
top--;
}
int empty()
{
if (top == -1)
{
printf("The stack is empty \n ");
return 1;
}
else{
return 0;
}
}
int main()
{
char str[30];int len;int i;int temp;
printf("Enter he expression \n ");
scanf("%d",str);
len=strlen(str);
for(i=0;i<len;i++)
{
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
{
push(str[i]);
}
if (str[i] == ')' || str[i] == '}' || str[i] == ']')
{
temp=empty();
if((empty())==1)
{
printf("Unbalanced\n ");
return;
}
else if(str[i]==arr[top])
{
pop();
}
}
}
if((empty())==1)
{
printf("Balanced\n");
}
else {
printf("unbalanced\n");
}
return 0;
}
however whatever the input i give the result i am getting is
Enter he expression
{{{]])
empty happend
Balanced
i have isolated the problem where my push and pop function are not being called,and the stack is empty regardless of the input.
any idea how to fix the code?
If one wanted (, [, { to be indistinguishable, one doesn't need O(length) space. An O(1) counter of how many parentheses/braces/brackets are currently at the position of the string would do. You can do more storing the arr queue; that is, find mismatches in the types of braces. I wrote my own quick parentheses checker, and discovered:
I would say there are 4 exception conditions to a passing valid input. In addition to a passing test, I would make sure to engineer a test for all four failing tests,
stack overflow: there are too many nesting levels for the fixed-size stack;
underflow: there are too many closing braces;
mismatch: one type of brace opened, but another closed; this is entirely missing from the original code;
unclosed: there are braces left in your stack but the input has ended.
One may want to automate this process, but the input has to be abstracted. Using #include <assert.h>.
assert(check("([{}({}[])]())") != 0);
assert(check("(") == 0);
assert(check("]") == 0);
...
printf("Enter he expression \n ");
if(!fgets(str, sizeof str, stdin)) return perror("input"), EXIT_FAILURE;
printf("%s\n", check(str) ? "Balanced" : "unbalanced");
I used the queue as what one expects; this is different for every character. Instead of a series of ifs, I used a switch statement. I changed the prototype for pop() to return the former top element and push() to return a boolean that it was successful (that is, not a stack overflow.) With this, for every byte, I wrote,
expect = 0;
switch(str[i]) {
case '\0':
if(!empty()) raise unclosed;
return;
case '(': expect = ')'; break;
case '[': expect = ']'; break;
case '{': expect = '}'; break;
case ')': case ']': case '}':
if(empty()) raise underflow;
if(pop() != str[i]) raise mismatch;
default: ; /* sic, everything else ignored */
}
if(expect && !push(expect)) raise overflow;
Where raise is dependent on the specificity one requires. Immediately report? With #include <stdbool.h>, raise -> return false; return -> return true. If one wanted be more specific, maybe return an exception value, enum { okay, unclosed, underflow, mismatch, overflow }. Or use goto to have more information about the context.
There are two problems.
First one is the scan should be %s not %d.
second one you pop if(str[i] == arr[Top]) which is always false, so the stack will remain full.
The code below should work fine.
#include <stdio.h>
#include <string.h>
#define MAX 100
int top = -1;
int arr[MAX];
void push(int x)
{
if (top == (MAX - 1))
{
printf("error:stack overflow n");
return;
}
top++;
arr[top] = x;
}
void pop()
{
top--;
}
int empty()
{
if (top == -1)
{
printf("The stack is empty \n ");
return 1;
}
return 0;
}
int main()
{
char str[30];
int len;
int i;
int temp;
printf("Enter he expression \n ");
scanf("%s", str);
len = strlen(str);
for (i = 0; i < len; i++)
{
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
{
push(str[i]);
continue;
}
if (str[i] == ')' || str[i] == '}' || str[i] == ']')
{
if (empty())
{
printf("Unbalanceddd\n ");
return;
}
pop();
}
}
if (empty())
{
printf("Balanced\n");
}
else
{
printf("unbalanced\n");
}
return 0;
}
Edit:
The code above is just fixing the error of stack.
The one below will check for each pair of the three.
#include <stdio.h>
#include <string.h>
#define STACK_MAX 100
int stack[STACK_MAX];
int top = -1;
void push(int x);
int pop();
int peek();
int isEmpty();
int main()
{
char str[STACK_MAX * 2];
printf("Enter he expression \n ");
scanf("%s", str);
int len = strlen(str);
for (int i = 0; i < len; i++)
{
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
{
push(str[i]);
continue;
}
if (str[i] == ')' || str[i] == '}' || str[i] == ']')
{
if (isEmpty())
{
printf("unbalanced\n");
return 0;
}
const char left = peek();
const char peek[3];
sprintf(peek, "%c%c", left, str[i]);
if (!(strcmp(peek, "()") == 0 || strcmp(peek, "[]") == 0 || strcmp(peek, "{}") == 0))
break;
pop();
}
}
if (isEmpty())
{
printf("Balanced\n");
}
else
{
printf("unbalanced\n");
}
return 0;
}
// --------------------------------------
// Stack Implementation
// --------------------------------------
void push(int x)
{
if (top + 1 == STACK_MAX)
{
printf("error:stack overflow \n");
return;
}
stack[++top] = x;
}
int pop()
{
if (top == -1)
{
printf("error: stack is empty \n");
return -1;
}
return stack[top--];
}
int peek()
{
if (top == -1)
{
printf("error: stack is empty\n");
return -1;
}
return stack[top];
}
int isEmpty()
{
return top == -1;
}
A fun project!
An alternative to function calls to push/pop values off a stack is to use 32 (or 64) bits of a variable to track the 3 different pairs of parentheses/brackets...
2 bits can represent 4 values. 0b00 is not useful as it cannot be distinguished from null (data), but 0b01, 0b10 & 0b11 can be harnessed to represent the each of the three pairs of interest.
In the code below, an unsigned int is the stack. Pushing two bits onto the stack involves a left shift and and OR. Popping is first testing the stack's two LSB's against what the character stream holds as a closing bracket, then right shifting the stack.
This is limited to 16 concurrent levels of nesting on my 32 bit compiler, but could go to 32 levels on a 64 bit compiler. Practically speaking, this should serve the majority of instances.
The code does detect/prevent stack over-/under-flow and bails out when detected.
#include <stdio.h>
#include <limits.h> // to determine 32 bit v. 64 bit
#if UINT_MAX = 0xffffffff // not sure this is right...???
typedef uint32_t stk_t;
#define FULL 0xC0000000 // b31 & b30 set
#else
typedef uint64_t stk_t;
#define FULL 0xC000000000000000 // b63 & b62 set
#endif
int balChk( char *str ) {
stk_t stk = 0;
char *sel = "(){}[]";
int ret = 0;
for( char *cp = str; !ret && *cp; cp++ ) {
for( char *bp = sel; *bp && *bp != *cp; bp++ ) {} // loop
if( !*bp ) continue; // not interesting character
if( (bp-sel)%2 == 0 ) { // 0,2,4 means push
if( stk & FULL ) {
printf( "Stack full - " );
ret = -1;
}
// pushes encoded matching close ')', '}' or ']'
stk = stk<<2 | ((bp-sel)+2)>>1; // use [2,4,6]/2 = 1,2,3
}
else // 1,3,5 means pop
{
// have stk item AND two LSBs match ([1,3,5]+1)/2 = 1,2,3
// compare encoded close with "top of stack" (ie: 2 LSBs )
if( !stk || (stk&3) != (bp-sel+1)>>1 ) {
printf( !stk ? "Stack empty - " : "Unmatched '%c' - ", *cp );
ret = -1;
}
stk >>= 2;
}
}
return ret + stk; // 0 means good
}
int main() { // test a few variations
char *strs[] = {
"()", "{}", "[]", "((()))", "(([()]))",
"(((([ (((([ (((([", // 15
"(((([ (((([ (((([ [", // 16
"(((([ (((([ (((([ [{", // 17 too many for my 32bit compiler
"(((([ (((([ (((([ []{", // 16-1+1
"{ ({()}) ((())) [] }",
"{ ({()}) ((())) [] missing!",
"{ ({()}) ((())) [] }",
"{ ({()}) ((())) [] too many }}",
};
for( int i = 0; i < sizeof strs/sizeof strs[0]; i++ )
printf( "'%s' - %s\n", strs[i], balChk( strs[i] ) ? "Bad" : "Good" );
return 0;
}
Output
'()' - Good
'{}' - Good
'[]' - Good
'((()))' - Good
'(([()]))' - Good
'(((([ (((([ (((([' - Bad // but 15 passed
'(((([ (((([ (((([ [' - Bad // but 16 passed
Stack full - '(((([ (((([ (((([ [{' - Bad // 17 popped the stack
'(((([ (((([ (((([ []{' - Bad // 16 - 1 + 1 passed
'{ ({()}) ((())) [] }' - Good
'{ ({()}) ((())) [] missing!' - Bad
'{ ({()}) ((())) [] }' - Good
Stack empty - '{ ({()}) ((())) [] too many }}' - Bad // Excessive popping
All-in-all, a fun project...

Stack infix to postfix

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)

Extracting chars from inside '(' and ')' from char array in C

I am stuck on this problem:
A user writes a math expression and the program need to extract from it all subexpressions that are inside ( ) ex. (x+2) or (x+(y-2)).
For example, if the user enters 2-(5+(x-6)-(y+9)), the program should return (x-6), (y+9), (5+(x-6)-(y+9))
This is what I've tried to do.
#include<stdio.h>
int main()
{
char a[100];
int i=0,t,j=0;
printf("enter math expression:\n");
while( (a[i++]=getchar()) != '\n' && i < 100);
a[i] = '\0';
for (i=0; a[i]!='\0'; i++)
{
if (a[i]=='(')
{ printf("found (\n");
j++;
while (a[i] !=')')
printf("%c",a[i++]);
printf("%c",a[i]);
Since you are dealing with nested expressions, you need to keep a stack around in order to match parentheses. Ideally inside the loop you should:
Whenever found a '(', push position within the string into the stack
When a ')' is found, then pop from the stack the position of the matching '('. You have start-end indexes for your expression.
Continue until string is finished
Example (x + (y+2)):
i == 0 -> '(' -> s.push(0);
i == 1 -> 'x'
i == 2 -> '+'
i == 3 -> '(' -> s.push(3);
i == 4 -> 'y'
i == 5 -> '+'
i == 6 -> '2'
i == 7 -> ')' -> s.pop() [3, 7] contains '(y + 2)'
i == 8 -> ')' -> s.pop() [0, 8] contains '(x + (y+2))'
Let, s be a cstring in this context.
Since in valid mathematical expression parenthesis are balanced, we can observe that,
s+1 is balanced if s[0] is not '('
if s[0] is '(' then we are at the start of a parenthesis'ed expression.
At the case of #1 we do not care about the first character. So, we can set s = s+1 and start over again.
At the case of #2 we have to find the matched end for the first character. So, we divide it in two part. The matched expression and the tail. Both are valid expression. So, we start with them over again.
int main()
{
char s[] = "2-(5+(x-6)-(y+9))";// s have to be modifiable.
extractAndPrint(s, 0); // we are at start and 0 indicates balanced
return 0;
}
Now,
void extractAndPrint(char *s, int found)
{
if(s[0] == 0) return;//no more honey
if(!found){ //so far balanced
if(s[0] == '(') extractAndPrint(s+1, 1);// case 2
else extractAndPrint(s+1, 0); //this is the case 1
} else {//start of a expression
char *t;
//separates the end of current expression
//and the remaining part.
mark_end(s, 0, &t);
printf("(%s)\n", s);
extractAndPrint(s, 0);//potentially contain more expression
extractAndPrint(t, 0);//check past the previous exp
}
}
I liked recursion here too. It takes less thinking for me. Can be implemented in more elegant way.
void mark_end(char *s, int c, char **t)
{
if(c == 0){
if(s[0] == ')'){
*t = s+1;
*s = '\0';
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
} else {
if(s[0] == ')'){
mark_end(s+1, c-1, t);
} else if(s[0] == '('){
mark_end(s+1, c+1, t);
} else {
mark_end(s+1, c, t);
}
}
}
OUTPUT:
(5+(x-6)-(y+9))
(x-6)
(y+9)
I recommend you to use state machine, in your case this state machine should be suitable :
so your main will be a kind of a switch case, take care of writing your pop and push fuctions and represent your heap with a good structure
You should use recursion to parse the string as a tree of parenthesis. Here is an example showing how to do it :
#include <stdio.h>
#include <string.h>
#define MAX_DATA 100
int mathexp(const char *exp, int start, int end)
{
int i = start;
while(i < (start + end) && exp[i] != ')') {
if(exp[i] == '(') {
i = mathexp(exp, i + 1, end) + 1;
} else {
i++;
}
}
char subexp[i - start];
memcpy(subexp, &exp[start], i - start);
subexp[i - start] = '\0';
printf("%s\n", subexp);
return i;
}
int main(int argc, char *argv[])
{
char input[MAX_DATA];
printf("Enter a math expression: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\r\n")] = '\0'; // remove trailing \r\n
mathexp(input, 0, strlen(input));
return 0;
}
and when you test it, you have :
Enter a math expression: 2-(5+(x-6)-(y+9))
x-6
y+9
5+(x-6)-(y+9)
2-(5+(x-6)-(y+9))

Brainfuck interpreter in c printing trouble

I'm trying to code a very simple brainfuck interpreter in C, and I run into problems while trying to outprint certain characters by what I understand.
This is all my code:
#include <stdio.h>
int bla(char tabukaz[30000], int ukaz, int num) {
int sum = 0;
int index = ukaz;
while (sum > -1) {
index -= num;
if (tabukaz[index] == ']')
sum += num;
else if (tabukaz[index] == '[')
sum -= num;
}
return index;
}
int main () {
int tab[30000];
int tabukaz[30000];
int c;
int i = 0; int ukaz = 0;
unsigned char ch;
for (int i = 0; i < 30000; i++) {
tab[i] = 0;
tabukaz[i] = 0;
}
while ((c=getchar()) != EOF) {
ch = (unsigned char)c;
if (ch == '>' || ch == '<' || ch == '+' || ch == '-' || ch == '.' || ch == '[' || ch == ']')
{
tabukaz[ukaz] = ch;
}
switch (ch) {
case '>': i++; break;
case '<': i--; break;
case '+': tab[i]++;break;
case '-': tab[i]--; break;
case '.': putchar(tab[i]); break;
case '[':
if (tab[i]==0) {
ukaz = bla(tabukaz, ukaz, -1);
}
break;
case ']':
if (tab[i]!=0) {
ukaz = bla(tabukaz, ukaz, 1);
}
break;
default:
break;
}
ukaz++;
}
return 0;
}
This is the input in question (I tried to avoid the other text in the actual input (keep in mind everything down here is part of the input, even the unnecessary text) We were provided with a make file which will write the output into a text file, and compare it to a predefined text, the problem is my text file comes out as a binary file and I cant figure out why. The problem may be hidden in how I handle [ and ] as I didn't have that problem in the earlier tests without them
+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
<<<< - decrement counter (cell #0)
]
> ++ . print 'H'
> + . print 'e'
+++++ ++ . print 'l'
. print 'l'
+++ . print 'o'
> ++ . print ' '
<< +++++ +++++ +++++ . print 'W'
> . print 'o'
+++ . print 'r'
----- - . print 'l'
----- --- . print 'd'
> + . print '!'
> . print '\n'
As a suggestion made by somebody I did this:
while ((c=getchar())!=EOF) {
ch = (unsigned char)c;
if (ch == '>' || ch == '<' || ch == '+' || ch == '-' || ch == '.' || ch == '[' || ch == ']')
{
tabukaz[ukaz]=ch;
stukaz++;
}
}
while (stukaz>0) {
switch (tabukaz[ukaz]) {
case '>': i++; break;
case '<': i--; break;
case '+': if(tab[i]==255) tab[i] = 0;
else tab[i]++;
break;
case '-': if (tab[i]==0) tab[i] = 255;
else tab[i]--;
break;
case '.': printf ("%c", tab[i]); break;
case '[':
if (tab[i]==0) {
ukaz = bla(tabukaz, ukaz, -1);
}
break;
case ']':
if (tab[i]!=0) {
ukaz = bla(tabukaz, ukaz, 1);
}
break;
default: break;
}
stukaz--;
ukaz++;
}
However the problem now extends to the tests before that, as it even outputs those as binary files, I'm thinking there's something wrong with the [ and ] code and thus it doesn't increment the fields properly printing unwanted characters, how this extended to tests without them only when putting another loop around it I have no idea.
EDIT: the problem with the above loop is not the while loop not going trough, the problem is that it will never get into the switch, any solution to that?
The test is wrong while scanning for a matching bracket.
while (sum > -1) {
index -= num;
if (tabukaz[index] == ']')
sum += num;
else if (tabukaz[index] == '[')
sum -= num;
}
You set num to 1 for a backwards scan, but to -1 for a forward scan.
case '[':
if (tab[i]==0) {
ukaz = bla(tabukaz, ukaz, -1);
}
break;
case ']':
if (tab[i]!=0) {
ukaz = bla(tabukaz, ukaz, 1);
}
break;
So the test should be (sum != 0) so it stops when the brackets are balanced from either direction. Of course, sum is initialized to 0, so I recommend a do { ... } while(); loop so the test is at the end.
Also, remember that you're incrementing the instruction pointer at the end of the loop.
ukaz++;
So you may want to set the pointer to bla(...) - 1, so the increment puts the pointer in the correct place.
You might also like to look at my own brainfuck interpreter, which is very similar to yours. One of my reviewers there gives an excellent explanation of optimizing the loop execution with a jump table.

Array not being assigned char after certain number of loops

I am in the process of writing an infix to postfix function. After it loops through a couple of times(8 or 9th loop), my postfix array won't accept any more characters(it's set for 100).
void convertToPost(char infix[], char postfix[])
{
StackNode *pMem=NULL;
int i=-1,j=0, priority=0,priorityStack=0,operandCounter=0;
push(&pMem,'(');
infix[strlen(infix)]=')';
printf("%s\n",infix);
for(j=0;j<strlen(infix);j++)
{
putchar('\n');
printf("infix[%d]: %s\n",j,infix);
printf("postfix[%d]: %s\n",j,postfix);
putchar('\n');
if(infix[j] <= 57 && infix[j] >= 48)
{
i++;
postfix[i]=infix[j]; // not assigning value 8 to postfix
i++;
postfix[i] = ' ';
}
else if(infix[j] == '(')
{
push(&pMem,infix[j]);
//pop(&pMem);
}
else if(infix[j] == ')')
{
while(pMem->pNext != NULL)
{
if(pMem->pString == '(')
{
pop(&pMem);
}
else
{
postfix[i]= ' ';
i++;
postfix[i] = pMem->pString;
i++;
pop(&pMem);
}// figure out how to take char from top of stack and put in postfix something pop()
//push(&pMem,'(');
}
push(&pMem,'(');
//pop(&pMem);
}
else if(infix[j] == '+' || infix[j] == '-' || infix[j] == '^' || infix[j] == '*' || infix[j] == '/' || infix[j] == '%')
{
//i--;
if(operandCounter==0)
{
push(&pMem,infix[j]);
operandCounter++;
}
else
{
priority=Precedence(infix[j]);
priorityStack=Precedence(pMem->pString);//pString is empty
if(priority >= priorityStack)
{
if(pMem->pString != '(')
{
i++;
postfix[i]=pMem->pString;
i++;
postfix[i]=' ';
pop(&pMem);
push(&pMem,infix[j]);
}
else
{
push(&pMem,infix[j]);
}
}
}
}
}
}
This is the sample equation that I am using: 9*(5-4)+2/6
Its output should be: (9 5 4 - * 2 6 / +)
I put a comment where the problem occurs first. It continues throughout after it reaches that point. For example when I run the code it returns: 9 5 4 - *
But gives no error codes or anything.
If you would like some of the other functions (i.e priority, push, pop) feel free to ask.
inside the for loop(), strlen(infix) value is undefined. Because you are replacing the terminating NULL character in the string.infix[strlen(infix)]=')'; Which causes strlen() to return undefined value.
so change
infix[strlen(infix)]=')';
to
int len = strlen(infix);
infix[len]=')';
infix[len+1] = '\0';
Also make sure you have sufficient memory allocated for the array so the len+1 index in the array will not be out of bounds access.

Resources