/***************************************************** * Author: xianyuxiaoqiang * Usage : For Polynomial Add or subtract * eg : * - input * 2x^2-2x^4+3x^2+2x^-1+x^-2 * - output * -2x^4+5x^2+2x^-1+x^-2 * * ***************************************************** */ #define MAXBUFFER 1024 #define MAX_NODE_NUM MAXBUFFER/4 #define INTERNAL_ERROR() {printf("Internal error accured in line %d !",__LINE__);} #define NULL 0 typedef struct _Node{ int exponent; int coefficient; int n_next_id;/* The logical next */ }PolyNode; typedef struct _List{ int num; PolyNode nodeArray[MAX_NODE_NUM]; int n_head_id;/* The logical head */ int n_tail_id;/* The phisical tail */ }PolyList; PolyList polyList; int my_atoi(char* str, int *num){ int sign = 0; int n = 0; char *ptr=str; if(*ptr == '-'){ sign = -1; ptr++; }else if(*ptr == '+'){ sign = 1; ptr++; } while(*ptr){ n = (*ptr-'0') + n*10; ptr++; } if(sign < 0){ n = ~n + 1; } *num = n; return n; } int getNumberAndMovePtr(char**pp_str, int* number){ char buffer[MAXBUFFER]=""; int index = 0; int num = 0; if(NULL==pp_str || NULL==number || NULL==*pp_str){ INTERNAL_ERROR() return -1; } if( strlen(*pp_str) == 0 )return 1; /* deal with the firt char */ if((*pp_str)[0] == '-'|| (*pp_str)[0] == '+'||((*pp_str)[0]<='9' && (*pp_str)[0]>='0')){ buffer[0] = (*pp_str)[0]; index++; }else if( (*pp_str)[0] == 'x' ){ /* Deal with +/-1 */ buffer[0] = '1'; } for(; index < strlen(*pp_str) && index < MAXBUFFER; index++){ if( (*pp_str)[index]<='9' && (*pp_str)[index]>='0' ){ buffer[index] = (*pp_str)[index]; } else { break; } } if( buffer[0] == '-' || buffer[0] == '+' ){ /* Deal with +/-1 */ if( buffer[1] == 0 ){ buffer[1] = '1'; } } if(strlen(buffer) == 0)return -1; *pp_str += index; my_atoi(buffer,&num); if(buffer[0] != '-' && num < 0){ return -1; } *number = num; return 0; } /* search and sort */ int searchNodeId(int exponent){ int id = 0; int lastid = 0; int nextid = 0; if(polyList.num == 0){ /* The first node born */ polyList.n_head_id = 0; polyList.n_tail_id = 0; polyList.num++; polyList.nodeArray[0].n_next_id = -1; polyList.nodeArray[0].exponent = exponent; polyList.nodeArray[0].coefficient = 0; return 0; } lastid = polyList.n_head_id; if( exponent > polyList.nodeArray[lastid].exponent ){ /* it is larger than head */ id = polyList.n_tail_id+1; if(id >= MAX_NODE_NUM ){ INTERNAL_ERROR() return -1; } /* The new head is born */ polyList.n_head_id = id; polyList.nodeArray[id].n_next_id = lastid; polyList.nodeArray[id].exponent = exponent; polyList.nodeArray[id].coefficient = 0; polyList.n_tail_id++; polyList.num++; return id; } nextid = polyList.nodeArray[lastid].n_next_id; while(nextid >= 0){ if( exponent > polyList.nodeArray[nextid].exponent ){ if( exponent == polyList.nodeArray[lastid].exponent ){ return lastid; }else{ /* new node between last and current is born */ id = polyList.n_tail_id+1; if(id >= MAX_NODE_NUM ){ INTERNAL_ERROR() return -1; } polyList.nodeArray[lastid].n_next_id = id; polyList.nodeArray[id].n_next_id = nextid; polyList.nodeArray[id].exponent = exponent; polyList.nodeArray[id].coefficient = 0; polyList.n_tail_id++; polyList.num++; return id; } } lastid = nextid; nextid = polyList.nodeArray[lastid].n_next_id; } if( exponent == polyList.nodeArray[lastid].exponent ){ /* The last node */ return lastid; }else{ /* The smallest node is born */ id = polyList.n_tail_id+1; if(id >= MAX_NODE_NUM ){ INTERNAL_ERROR() return -1; } polyList.nodeArray[lastid].n_next_id = id; polyList.nodeArray[id].n_next_id = -1; polyList.nodeArray[id].exponent = exponent; polyList.nodeArray[id].coefficient = 0; polyList.n_tail_id++; polyList.num++; return id; } } int Head(char** pp_str){ int cur_exponent; int cur_coefficient; char **cur_ptr=pp_str; int cur_node_id = -1; PolyNode tempNode; int ret=0; if(NULL == pp_str || NULL == *pp_str){ INTERNAL_ERROR() return -1; } /* get a number from the buffer ,this number is coefficient */ ret = getNumberAndMovePtr( cur_ptr, &cur_coefficient ); if( ret < 0 ){ return -1; }else if( ret > 0 ){ /* end of string */ return 1; } /* get the next number from the buffer ,this number is exponent */ if( 'x' == (*cur_ptr)[0] ){ if( '^' == (*cur_ptr)[1] ){ *cur_ptr += 2; ret = getNumberAndMovePtr( cur_ptr, &cur_exponent ); if( ret !=0 )return -1; }else{ /* the exponent is 1 */ cur_exponent = 1; (*cur_ptr)++; } }else{ /* simple number */ cur_exponent = 0; } /* get the id of the sub sentence in the list by it's exponent */ cur_node_id = searchNodeId(cur_exponent); if(cur_node_id < 0){ /* Error accured */ return -1; } /* add the coefficient to the node */ polyList.nodeArray[cur_node_id].coefficient += cur_coefficient; return 0; } int Tail(char **pp_str){ if(NULL == pp_str || NULL == *pp_str){ INTERNAL_ERROR() return -1; } if(0 == (*pp_str)[0])return 0; /* do with a sub sentence */ if( Head(pp_str) < 0 ){ return -1; }else if( Tail(pp_str) < 0 )return -1;/* contine */ return 0; } int DisplayResult(){ int cur_node_id = polyList.n_head_id; printf("/n/n-------------------- The result --------------------------/n/n"); if( polyList.nodeArray[cur_node_id].coefficient != 0 ){ if( polyList.nodeArray[cur_node_id].coefficient == -1 ){ if( polyList.nodeArray[cur_node_id].exponent != 0 ){ printf("-"); }else { printf("-1"); } }else if( polyList.nodeArray[cur_node_id].coefficient != 1 ){ printf("%d",polyList.nodeArray[cur_node_id].coefficient); }else if( polyList.nodeArray[cur_node_id].coefficient == 1 ){ if( polyList.nodeArray[cur_node_id].exponent == 0 ){ printf("1"); } } if( polyList.nodeArray[cur_node_id].exponent != 0 ){ if( polyList.nodeArray[cur_node_id].exponent != 1 ){ printf("x^%d",polyList.nodeArray[cur_node_id].exponent); }else{ printf("x"); } } } cur_node_id = polyList.nodeArray[cur_node_id].n_next_id; for( ; cur_node_id >= 0; cur_node_id = polyList.nodeArray[cur_node_id].n_next_id ){ if( cur_node_id >= MAX_NODE_NUM ){ INTERNAL_ERROR() return -1; } if( polyList.nodeArray[cur_node_id].coefficient != 0 ){ if( polyList.nodeArray[cur_node_id].coefficient > 0 ){ printf("+"); } if( polyList.nodeArray[cur_node_id].coefficient == -1 ){ if( polyList.nodeArray[cur_node_id].exponent != 0 ){ printf("-"); }else { printf("-1"); } }else if( polyList.nodeArray[cur_node_id].coefficient != 1 ){ printf("%d",polyList.nodeArray[cur_node_id].coefficient); }else if( polyList.nodeArray[cur_node_id].coefficient == 1 ){ if( polyList.nodeArray[cur_node_id].exponent == 0 ){ printf("1"); } } if( polyList.nodeArray[cur_node_id].exponent != 0 ){ if( polyList.nodeArray[cur_node_id].exponent != 1 ){ printf("x^%d",polyList.nodeArray[cur_node_id].exponent); }else{ printf("x"); } } } } printf("/n/n--------------------------------------------------------------/n"); return 0; } int Polynomial(char* str){ if( Tail(&str) < 0 )return -1; return 0; } int main(int arg, char** args){ char buffer[MAXBUFFER]=""; char format[100]; printf("Please input your Polynomial/n"); sprintf(format, "%%%ds", MAXBUFFER-1); scanf(format, buffer); printf("/n/nThe source is : %s/n", buffer); /* initialize the list */ polyList.num = 0; polyList.n_head_id = -1; polyList.n_tail_id = -1; if( Polynomial(buffer) != 0 ){ goto USAGE_ERROR; } DisplayResult(); return 0; USAGE_ERROR: printf("Usage : <head><tail>/n"); printf("<head> : <number>( <null> | 'x^'<number> )/n"); printf("<tail> : (<'-'|'+'><head><tail>)|<null>/n"); printf(" eg : 2x^2-2x^4+3x^2+2x^-1+x^-2/n"); return -1; }