Last active
July 2, 2016 13:51
-
-
Save chaws/1f3063360b96fba8c676afe7e955b1a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This was based on problem 1077: infix to postfix form | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define PRI(c) (c == '*' ? 1 : (c == '(' ? -1 : 0)) | |
#define push iStack++, opStack[iStack].c = infix[i], opStack[iStack].pri = PRI(infix[i]) | |
// Encapsulate an element | |
typedef struct | |
{ | |
char el[300]; | |
int sel; | |
} elem; | |
typedef struct | |
{ | |
char c; | |
char pri; | |
} op; | |
void print(char * e, int s) | |
{ | |
int i = 0; | |
for(; i < s; i++) printf("%c", e[i]); | |
printf("\n"); | |
} | |
// Add two sets | |
int sum(char * out, elem * elstack) | |
{ | |
char *el1, *el2; | |
int sel1, sel2; | |
el2 = elstack->el; | |
sel2 = elstack->sel; | |
//printf("sum) working with el2: "); print(el2, sel2); // DEBUG1 | |
elstack--; | |
el1 = elstack->el; | |
sel1 = elstack->sel; | |
//printf("sum) working with el1: "); print(el1, sel1); // DEBUG1 | |
// If el1 is zero, just copy el2 | |
if(sel1 == 0) | |
{ | |
strncpy(out, el2, sel2); | |
return sel2; | |
} | |
// Otherwise, if el2 is zero, just copy el1 | |
else if(sel2 == 0) | |
{ | |
strncpy(out, el1, sel1); | |
return sel1; | |
} | |
int written = 0; | |
if(sel1 > sel2) | |
{ | |
// el1 is guiding | |
while(sel1--) | |
{ | |
// Put the smallest char first | |
if(*el1 < *el2) | |
*out = *el1, el1++; | |
else if(*el1 > *el2) | |
*out = *el2, el2++, sel2--, sel1++; | |
else | |
*out = *el1, el1++, el2++, sel2--; | |
//printf("sum1) writting '%c'\n", *out); // DEBUG1 | |
written++; | |
out++; | |
// If el2 is done, just copy the rest of el1 | |
if(!sel2) | |
{ | |
strncpy(out, el1, sel1); | |
//printf("sum1) finish writting :"); print(out, sel1); // DEBUG1 | |
return written + sel1; | |
} | |
} | |
// If el2's still kicking, just copy the rest of el2 | |
if(sel2) | |
{ | |
strncpy(out, el2, sel2); | |
//printf("sum1) finish writting 2 :"); print(out, sel2); // DEBUG1 | |
return written + sel2; | |
} | |
} | |
else | |
{ | |
// el2 is guiding | |
while(sel2--) | |
{ | |
// Put the smallest char first | |
if(*el2 < *el1) | |
*out = *el2, el2++; | |
else if(*el2 > *el1) | |
*out = *el1, el1++, sel1--, sel2++; | |
else | |
*out = *el2, el2++, el1++, sel1--; | |
//printf("sum2) writting '%c'\n", *out); // DEBUG1 | |
written++; | |
out++; | |
// If el1 is done, just copy the rest of el2 | |
if(!sel1) | |
{ | |
strncpy(out, el2, sel2); | |
//printf("sum2) finish writting :"); print(out, sel2); // DEBUG1 | |
return written + sel2; | |
} | |
} | |
// If el2's still kicking, just copy the rest of el2 | |
if(sel1) | |
{ | |
strncpy(out, el1, sel1); | |
//printf("sum1) finish writting 2 :"); print(out, sel1); // DEBUG1 | |
return written + sel1; | |
} | |
} | |
return written; | |
} | |
// Remove all el2 that is present in el1 | |
int sub(char * out, elem * elstack) | |
{ | |
char *el1, *el2; | |
int sel1, sel2; | |
el2 = elstack->el; | |
sel2 = elstack->sel; | |
//printf("sub) working with el2: "); print(el2, sel2); // DEBUG1 | |
elstack--; | |
el1 = elstack->el; | |
sel1 = elstack->sel; | |
//printf("sub) working with el1: "); print(el1, sel1); // DEBUG1 | |
// If el1 is zero, return empty set | |
if(sel1 == 0) | |
{ | |
*out = 0; | |
return 0; | |
} | |
// Otherwise, if el2 is zero, just copy el1 | |
else if(sel2 == 0) | |
{ | |
strncpy(out, el1, sel1); | |
return sel1; | |
} | |
int written = 0, iel1, iel2; | |
for(iel2 = 0; iel2 < sel2; iel2++) | |
{ | |
//printf("sub = %c\n", *el2); // DEBUG1 | |
while(sel1 && *el1 < *el2) | |
{ | |
*out = *el1; | |
//printf("sub2) writting '%c'\n", *out); // DEBUG1 | |
out++; | |
written++; | |
el1++; | |
sel1--; | |
} | |
el2++; | |
el1++; | |
sel1--; | |
} | |
// Finish copying el1 | |
if(sel1 > 0) | |
{ | |
strncpy(out, el1, sel1); | |
//printf("sub) finish writting :"); print(out, sel1); // DEBUG1 | |
return written + sel1; | |
} | |
return written; | |
} | |
// Intersection between el1 and el2 | |
int mul(char * out, elem * elstack) | |
{ | |
char *el1, *el2; | |
int sel1, sel2; | |
el2 = elstack->el; | |
sel2 = elstack->sel; | |
//printf("mul) working with el2: "); print(el2, sel2); // DEBUG1 | |
elstack--; | |
el1 = elstack->el; | |
sel1 = elstack->sel; | |
//printf("mul) working with el1: "); print(el1, sel1); // DEBUG1 | |
// if either el1 or el2 are empty, intersection should also be empty | |
if(sel1 == 0 || sel2 == 0) | |
{ | |
*out = 0; | |
return 0; | |
} | |
int written = 0, iel1, iel2; | |
for(iel2 = 0; sel1 && iel2 < sel2; iel2++, el2++) | |
{ | |
//printf("mul = %c\n", *el2); // DEBUG1 | |
while(sel1 && *el1 < *el2) el1++, sel1--; | |
if(*el1 == *el2) | |
{ | |
*out = *el2; | |
//printf("mul1) writting '%c'\n", *out); // DEBUG1 | |
out++; | |
written++; | |
el1++, sel1--; | |
} | |
} | |
return written; | |
} | |
void process(char * postfix) | |
{ | |
char *el; | |
int sel; | |
elem *pelstask, elstack[300]; | |
pelstask = elstack; | |
// Process postfix string | |
while(*postfix != '\0') | |
{ | |
char result[300] = {0}; | |
// Add el to elstack | |
if(*postfix == '{') | |
{ | |
// Grow stack | |
pelstask++; | |
// Get el | |
postfix++, el = postfix; // { + 1 | |
sel = 0; | |
while(*postfix != '}') sel++, postfix++; | |
strncpy(pelstask->el, el, sel); | |
pelstask->sel = sel; | |
//printf("p) pushing to stack: sel = %d, el = ", sel); print(pelstask->el, pelstask->sel); // DEBUG1 | |
} | |
// It's an operator, evaluate it | |
else | |
{ | |
//printf("Processing operator '%c'\n", *postfix); // DEBUG1 | |
switch(*postfix) | |
{ | |
case '+': sel = sum(result, pelstask); break; | |
case '-': sel = sub(result, pelstask); break; | |
case '*': sel = mul(result, pelstask); break; | |
} | |
//printf("result = '%s'\n", result); // DEBUG1 | |
// Pop the stack and rewrite the stack - 1th position | |
pelstask--; | |
strncpy(pelstask->el, result, sel); | |
pelstask->sel = sel; | |
//printf("Saving the result to the stack "); print(result, sel); // DEBUG1 | |
} | |
postfix++; | |
} | |
pelstask->el[pelstask->sel] = '\0'; | |
printf("{%s}\n", pelstask->el); | |
} | |
int chrcmp(const void * c1, const void * c2) | |
{ | |
return *(char *)c1 - *(char *)c2; | |
} | |
int main(void) | |
{ | |
int iPost, iStack, cread, i, pri, start_sort, end_sort; | |
char infix[301] = {0}; | |
while(scanf("%s%n", infix, &cread) != EOF) | |
{ | |
char postfix[301] = {0}; | |
op opStack[301]; | |
iPost = iStack = 0; | |
//printf("Read = %s: ", infix); // DEBUG1 | |
cread--; | |
for(i = 0; i < cread; i++) | |
{ | |
if(infix[i] == '{') | |
{ | |
// Save {...} | |
start_sort = iPost + 1; | |
while(infix[i] != '}') | |
postfix[iPost++] = infix[i], i++; | |
end_sort = iPost - 1; | |
postfix[iPost++] = infix[i]; // } | |
// make sure the letters are sorted | |
//printf("end_sort= %d, start_sort = %d\n", end_sort, start_sort); | |
if(end_sort - start_sort > 0) | |
{ | |
//printf("sorting '%c' to '%c'\n", *(postfix + start_sort), *(postfix + end_sort + 1)); | |
qsort(postfix + start_sort, end_sort - start_sort + 1, sizeof(char), chrcmp); | |
} | |
// printf("Found1 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack); | |
} | |
else if(infix[i] == '(') | |
{ | |
push; | |
// printf("Found2 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack); | |
} | |
else if(infix[i] == '+' || infix[i] == '-' || infix[i] == '*') | |
{ | |
LOOP: | |
if(iStack == 0) // empty? | |
{ | |
push; | |
// printf("Found3 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack); | |
} | |
else | |
{ | |
// Check stack's top pri | |
pri = PRI(infix[i]) - opStack[iStack].pri; | |
if(pri > 0) | |
{ | |
// Just push | |
push; | |
// printf("Found4 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack); | |
} | |
else | |
{ | |
// Print top of stack | |
postfix[iPost++] = opStack[iStack--].c; | |
// printf("Found5 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack+1); | |
// Next pos in stack | |
goto LOOP; | |
} | |
} | |
} | |
else // Can only be ')' | |
{ | |
// Go through stack until '(' | |
while(iStack > 0 && opStack[iStack].c != '(') | |
{ | |
postfix[iPost++] = opStack[iStack--].c; | |
// printf("Found6 %c, postfix = %s\n", infix[i], postfix); printStack(opStack, iStack+1); | |
} | |
iStack--; // Remove '(' | |
} | |
} | |
// Clean the stack | |
while(iStack > 0) | |
{ | |
postfix[iPost++] = opStack[iStack--].c; | |
// printf("Found6 postfix = %s\n", postfix); printStack(opStack, iStack+1); | |
} | |
postfix[iPost] = '\0'; | |
//printf("before %s\n", postfix); // DEBUG1 | |
process(postfix); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment