Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // main.c
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "hash.h"
- int main(void) {
- char *words[] = { "aaa", "baa", "aab", "aba", "bba", "bab", "abb", "bbb", "aaa", "baa", "aab", "aba", "baa", "aab",
- "bbb", "aaa", "baa", "aab", "aba" };
- table *table = table_new();
- for (size_t i = 0; i < sizeof(words) / sizeof(char *); ++i) {
- table_add(table, words[i]);
- }
- puts("hashtable");
- table_print_to(table, stdout);
- node **array = table_entries(table);
- size_t items = table_items(table);
- puts("entries");
- node_array_print_to(array, items, stdout);
- node_array_sort_by_key(array, items);
- puts("sort by key");
- node_array_print_to(array, items, stdout);
- node_array_sort_by_value(array, items);
- puts("sort by value");
- node_array_print_to(array, items, stdout);
- table_delete(table);
- free(array);
- }
- // hash.h
- #ifndef HASH_H_
- #define HASH_H_
- #include <stddef.h>
- #include <stdio.h>
- #define HASH_SIZE 997
- #define HASH_RADIX 97
- typedef struct node node;
- typedef struct table table;
- table *table_new(void);
- void table_delete(table *);
- node *table_has_key(table *, char *);
- int table_add(table *, char *);
- int table_items(table *);
- char **table_keys(table *);
- node **table_entries(table *);
- void table_print_to(table *, FILE *);
- void node_array_print_to(node **, size_t, FILE *);
- void node_array_sort_by_key(node **, size_t);
- void node_array_sort_by_value(node **, size_t);
- int node_key_compare(const void *, const void *);
- int node_value_compare(const void *, const void *);
- #endif /* HASH_H_ */
- // hash.c
- #include "hash.h"
- #include <assert.h>
- #include <stdlib.h>
- #include <string.h>
- struct node {
- char *key;
- int value;
- int id;
- node *next;
- };
- struct table {
- node **head;
- int items;
- int rooms;
- };
- static unsigned int hash(char *);
- static int table_index(table *, char *);
- static node *node_new(char *);
- static unsigned int hash(char *str) {
- unsigned int v = 0;
- for (; *str; v = v * HASH_RADIX + *str++)
- ;
- return v;
- }
- static int table_index(table *table, char *key) {
- return hash(key) % table->rooms;
- }
- static node *node_new(char *key) {
- node *new = malloc(sizeof(node));
- new->key = strdup(key);
- new->value = 1;
- new->id = 0;
- new->next = NULL;
- return new;
- }
- table *table_new(void) {
- table *t = malloc(sizeof(table));
- t->items = 0;
- t->rooms = HASH_SIZE;
- t->head = malloc(sizeof(node *) * t->rooms);
- for (size_t i = 0; i < t->rooms; i++) {
- t->head[i] = NULL;
- }
- return t;
- }
- void table_delete(table *table) {
- if (!table) {
- return;
- }
- for (size_t i = 0; i < table->rooms; i++) {
- for (node *p = table->head[i], *q; p; q = p, p = p->next, free(q))
- ;
- }
- free(table->head);
- free(table);
- }
- int table_items(table *table) {
- assert(table);
- return table->items;
- }
- node *table_has_key(table *table, char *key) {
- assert(table && key);
- for (node *n = table->head[table_index(table, key)]; n; n = n->next) {
- if (!strcmp(key, n->key)) {
- return n;
- }
- }
- return NULL;
- }
- int table_add(table *table, char *key) {
- assert(table && key);
- node *found = table_has_key(table, key);
- if (found) {
- found->value++;
- return found->id;
- }
- node *new = node_new(key);
- new->id = table->items++;
- int index = table_index(table, key);
- new->next = table->head[index];
- table->head[index] = new;
- return new->id;
- }
- char **table_keys(table * table) {
- assert(table);
- char **keys = malloc(sizeof(char *) * table->items);
- for (int i = 0; i < table->rooms; ++i) {
- for (node *n = table->head[i]; n; keys[n->id] = n->key, n = n->next)
- ;
- }
- return keys;
- }
- node **table_entries(table *table) {
- assert(table);
- node **array = malloc(sizeof(node *) * table->items);
- for (int i = 0; i < table->rooms; ++i) {
- for (node * n = table->head[i]; n; array[n->id] = n, n = n->next)
- ;
- }
- return array;
- }
- void table_print_to(table *table, FILE *out) {
- assert(table);
- for (int i = 0; i < table->rooms; ++i) {
- for (node *n = table->head[i]; n; fprintf(out, "%s => %d\n", n->key, n->value), n = n->next)
- ;
- }
- }
- void node_array_print_to(node **array, size_t size, FILE *out) {
- for (size_t i = 0; i < size; ++i) {
- fprintf(out, "%s => %d\n", array[i]->key, array[i]->value);
- }
- }
- void node_array_sort_by_key(node **entries, size_t size) {
- qsort(entries, size, sizeof(node *), node_key_compare);
- }
- void node_array_sort_by_value(node **entries, size_t size) {
- qsort(entries, size, sizeof(node *), node_value_compare);
- }
- int node_key_compare(const void *p, const void *q) {
- node *u = *(node **) p;
- node *v = *(node **) q;
- return strcmp(u->key, v->key);
- }
- int node_value_compare(const void *p, const void *q) {
- node *u = *(node **) p;
- node *v = *(node **) q;
- if (u->value < v->value)
- return 1;
- if (u->value > v->value)
- return -1;
- return strcmp(u->key, v->key);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement