#include #include #include #include #include "string_util.h" #include "ismap.h" #include "usdot.h" int int_hash_identity(int n); int int_hash_knuth(int n); void free_value(int key, char *value, void *); void print_entry(int key, char *value, void *); void count_od(int key, char *value, void *); struct count_info { int count; char *match; }; #define CODE_LENGTH 3 int main(int argc, char **argv) { ismap *routes = ismap_create(int_hash_knuth); int id, seq, tot; char origin[CODE_LENGTH + 1]; char destination[CODE_LENGTH + 1]; while (read_segment(stdin, &id, &seq, &tot, origin, destination)) { if (!ismap_contains_key(routes, id)) { // key is not present; add it with empty route of // approriate size (3 chars for each airport in the route); char *route = malloc(sizeof(char) * CODE_LENGTH * (tot + 1) + 1); for (int i = 0; i < CODE_LENGTH * (tot + 1); i++) { route[i] = ' '; } route[CODE_LENGTH * (tot + 1)] = '\0'; ismap_put(routes, id, route); } // key should be present now; get value and update it char *route = ismap_get(routes, id); if (route != NULL) { // make sure sequence numbers work out if (strlen(route) >= (tot + 1) * CODE_LENGTH) { // copy origin and destination airports into appropriate // location in route strncpy(route + (seq - 1) * CODE_LENGTH, origin, CODE_LENGTH); strncpy(route + seq * CODE_LENGTH, destination, CODE_LENGTH); } } } ismap_for_each(routes, print_entry, NULL); if (argc > 1) { // need to pass two things into count_od: count and airport to match // so pack into a struct and pass a pointer to that struct ti // ismap_for_each so it can pass it along to count_od struct count_info info; info.count = 0; info.match = argv[1]; ismap_for_each(routes, count_od, &info); printf("%s: %d\n", argv[1], info.count); } // free allocated memory ismap_for_each(routes, free_value, NULL); ismap_destroy(routes); } void count_od(int key, char *value, void *arg) { struct count_info *info = arg; if (strncmp(value, info->match, CODE_LENGTH) == 0) { info->count++; } if (strncmp(value + strlen(value) - CODE_LENGTH, info->match, CODE_LENGTH) == 0) { info->count++; } } /** * Prints the given map entry to standard output. */ void print_entry(int key, char *value, void *arg) { printf("%d=%s\n", key, value); } /** * Frees the value in the given map entry. */ void free_value(int key, char *value, void *arg) { free(value); } /** * A very, very bad hash function for integers. */ int int_hash_identity(int n) { return n; } int int_hash_knuth(int n) { return n * 2654435761; }