/* Name: Lab Section: TA: */ #include #include #include #define HASHSIZE 5 #define MAXSIZE 100 /* basic mapping from text to replace */ typedef struct text_mapping { /* replacement table entry */ char *text; /* text to look for */ char *replace; /* text to replace above with */ struct text_mapping *next; /* points to next mapping in same hash bucket */ } text_mapping; /* function prototypes */ text_mapping *install(char *text, char *replace); text_mapping *lookup(char *s); unsigned int hash(char *s); int undef(char *s); void print_rules(); void process_input(); char *strdupe(char *s); /* master hash table */ static text_mapping *hashtab[HASHSIZE]; /* used to undefine rules * * Input: s is name of the rule to delete * Return values: * -1 if error is encountered; use if you feel you need this * 0 on success * 1 if name is not found in table */ int undef(char *s) { /* FILL THIS IN AND TEST IN MAIN */ printf("I will no longer replace \"%s\" (if rule exists).\n", s); return 0; } int main() { int i; /* initialize hash table */ for (i = 0; i < HASHSIZE; i++) { hashtab[HASHSIZE] = NULL; } /* "install" replacement rules */ install("hate", "love"); install("apples", "kiwis"); install("blue", "green"); install("sky", "grass"); install("procrastinated", "work diligently"); install("proj1", "every day"); /* print out all replacement rules */ print_rules(); /* take input and apply replacement rules */ /* example inputs: The sky is blue * I hate apples! * I procrastinated on CS61C proj1 */ printf("\nRunning replacer with initial rules (hit enter twice to stop)...\n"); process_input(); /* FILL IN HERE ANY TEST DELETION CODE YOU WANT */ /* "undef" replacement rules */ undef("sky"); /* print out all replacement rules after deletions */ print_rules(); /* process input again */ printf("\nRunning replacer again after deletion of rules (hit enter twice to stop)...\n"); process_input(); return 0; } /* used to find in hash table */ text_mapping *lookup(char *s) { text_mapping *current; for (current = hashtab[hash(s)]; current; current = current->next) { if (!strcmp(s, current->text)) { return current; /* the string s was found */ } } return NULL; /* the string s was not found */ } /* used to add replacement rules */ text_mapping *install(char *text, char *replace) { text_mapping *found; unsigned hashval; if ((found = lookup(text)) == NULL) { /* not found */ found = (text_mapping *) malloc(sizeof(text_mapping)); if (found == NULL || !(found->text = strdupe(text))) { return NULL; } hashval = hash(text); found->next = hashtab[hashval]; hashtab[hashval] = found; } else { free(found->replace); } if (!(found->replace = strdupe(replace))) { return NULL; } return found; } /* hash function to determine which hash "bucket" */ unsigned int hash(char *s) { unsigned hashval; for (hashval = 0; *s; s++) { hashval = *s + 31 * hashval; } return hashval % HASHSIZE; } void print_rules() { int i; text_mapping *current; for (i = 0; i < HASHSIZE; i++) { if ((current = hashtab[i])) { do { printf("I will replace \"%s\" (hash: %u) with \"%s\"\n", current->text, hash(current->text), current->replace); current = current->next; } while (current); } } } void process_input() { char lbuff[MAXSIZE], *pos; text_mapping *current; while (fgets(lbuff, MAXSIZE, stdin) && *lbuff != '\n') { pos = strtok(lbuff, " \t\n"); while (pos) { if ((current = lookup(pos))) { printf("%s ", current->replace); } else { printf("%s ", pos); } pos = strtok(NULL, " \t\n"); } printf("\n"); } fgets(lbuff, MAXSIZE, stdin); } char *strdupe(char *s) { char *buff; buff = (char *) malloc(strlen(s) * sizeof(char) + 1); if (buff) { strcpy(buff, s); } return buff; }