|
|||
Department of Engineering | |
University of Cambridge > Engineering Department > computing help |
char * get_string(char str[]) { printf("Input a string\n"); return gets(str); }Sample answers are on page unless otherwise stated.
int ccase = (skew >= 0 ? copy_right : ((bptr += chunk_bytes), copy_left)) + function;
... int degrees; char scale; int return_value; ... return_value = sscanf(str,"%d%c",°rees, &scale); ...
Each entry in the look-up table needs to have a record of the original string and the result of the processing. A structure of type Entry
typedef struct { char str[64]; int value; } Entry;will do for now. For our purposes it doesn't matter much what the processing routine is. Let's use the following, multiplying all the characters' values together.
int process(char *str){ int val = 1; while (*str){ val = val * (*str); str++; } return val; }
To get strings into the program you can use the get_string function. Now write a program that reads strings from the keyboard. If the string is new, then it's processed, otherwise its value is looked up in a table. The program should stop when `end' is typed. Here's a skeleton program to get you started.
/* hash1.c */ /* TODO include standard include files */ /* The following 2 lines use the preprocessor to create aliases. Note that these lines DON'T end with a `;' */ #define TABLE_SIZE 50 #define MAX_STR_LEN 64 typedef struct { char str[MAX_STR_LEN]; int value; } Entry; char str[MAX_STR_LEN]; /* TODO Create an array of TABLE_SIZE elements of type Entry */ int process(char *str){ int val = 1; while (*str){ val = val * (*str); str++; } return val; } char * get_string(char str[]) { printf("Input a string\n"); return gets(str); } main(){ int num_of_entries = 0; /* TODO Use get_string repeatedly. For each string:- If the string says `end', then exit. If the str is already in the table, print the associated value else calculate the value, add a new entry to the table, then print the value. */ }
A technique called hashing copes with the speed problem. First we need a hash function which given a string produces a number in the range 0..TABLE_SIZE. The following function just adds up the value of the characters in the string and gets the remainder after dividing by TABLE_SIZE.
int hashfn(char *str){ int total = 0; int i; while (i = *str++) total += i; return total % TABLE_SIZE; }
Now, whenever a string is to be processed, its hash value is calculated and that is used as an index into the table, which is much quicker than searching. If that entry is empty then the string is new and has to be processed. If the entry is occupied, then the associated value can be accessed. This method is flawed, but we'll deal with that problem later.
/* hash2.c */ /* TODO include standard include files */ #define TABLE_SIZE 50 #define MAX_STR_LEN 64 #define EMPTY -1 typedef struct { char str[MAX_STR_LEN]; int value; } Entry; char str[MAX_STR_LEN]; /* TODO Create an array of TABLE_SIZE elements of type Entry */ int process(char *str){ /* Same as hash1.c */ int val = 1; while (*str){ val = val * (*str); str++; } return val; } char * get_string(char str[]) /* Same as hash1.c */ { printf("Input a string\n"); return gets(str); } int hashfn(char *str){ int total = 0; int i; while (i = *str++) total += i; return total % TABLE_SIZE; } void set_table_values(void){ /* TODO set all the value entries in the table to EMPTY (We'll assume that the process() routine doesn't produce -1) */ } int find_entry(char *str, int bucket){ /* TODO if the entry in postion 'bucket' is EMPTY then fill the entry's fields in and return the string's processed value, else return the value of the entry. */ } main(){ int bucket; int val; set_table_values(); /* TODO Use get_a_string repeatedly. For each string:- use the hash function to find the string's entry in the table, then do the following */ bucket = hashfn(str) val = find_entry(str,bucket); printf("Value of <%s> is %d\n",str, val); }
You'll have to add just a few lines to the find_entry routine of the previous exercise. Remember to cycle round when the bottom of the table is reached.
A more robust method (and the answer to the exercise here) is in the next set of exercises (see section 17).