📄 dictionary.c
字号:
/* Copyright (C) 2001-2002 Mikael Ylikoski * See the accompanying file "README" for the full copyright notice *//** * @file * Functions to handle a dictionary of string -> integer mappings * (and optionally also the reverse integer -> string mappings). * * @author Mikael Ylikoski * @date 2001-2002 */#include <glib.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "dictionary.h"#include "iarray.h"#include "utility.h"#include "varray.h"/** * Dictionary. */struct dict_ { GHashTable *ht; /**< Hashtable */ int size; /**< Number of words in dictionary */ varray *num; /**< Reverse hashtable mapping */ iarray *reuse; /**< Stack of numbers to reuse */};/** * Create a new dictionary. * * @return The new dictionary. */dict *dict_new (void) { dict *dt; dt = my_malloc (sizeof(dict)); dt->ht = g_hash_table_new (g_str_hash, g_str_equal); if (!dt->ht) { free (dt); return NULL; } dt->num = NULL; dt->reuse = NULL; dt->size = 0; return dt;}/** * Setup reverse mappings to dictionary. */intdict_set_reverse (dict *dt) { if (!dt->num) dt->num = varray_new (10); if (!dt->reuse) dt->reuse = iarray_new (10); return 0;}/** * Free memory of dictionary. * * @param dt dictionary to free */voiddict_free (dict *dt) { g_hash_table_destroy (dt->ht); if (dt->num) varray_free (dt->num); if (dt->reuse) iarray_free (dt->reuse); free (dt);}/** * Load a dictionary. * * @param f file to load from * @return The loaded dictionary, or NULL if there was an error. */dict *dict_load (FILE *f) { char ch; char *ws; int i, j, k, l; int *w; dict *dt; dt = my_malloc (sizeof(dict)); i = fscanf (f, "%d;", &dt->size); if (i != 1) return NULL; dt->ht = g_hash_table_new (g_str_hash, g_str_equal); if (!dt->ht) { free (dt); return NULL; } for (i = 0; i < dt->size; i++) { j = fscanf (f, "%d=%d:", &k, &l); if (j != 2) return NULL; // FIXME memory leak w = my_malloc (sizeof(int)); ws = my_malloc (l + 1); j = fread (ws, sizeof(char), l, f); if (j != l) return NULL; // FIXME memory leak ws[l] = '\0'; *w = k; ch = fgetc (f); if (ch != ';') return NULL; // FIXME memory leak g_hash_table_insert (dt->ht, ws, w); } return dt;}static voiddict_write_word (gpointer key, gpointer value, gpointer fp) { int i; i = strlen ((char *)key); fprintf (fp, "%d=%d:%s;", *(int *)value, i, (char *)key);}/** * Save a dictionary. * * @param f file to save to * @param dt dictionary to save */intdict_save (FILE *f, dict *dt) { fprintf (f, "%d;", dt->size); g_hash_table_foreach (dt->ht, dict_write_word, f); return 0;}/** * Inserts a word into the dictionary hash table (unless it's already there). * * @param dt dictionary to use * @param w word to insert * @return The number of the word in the table, or -1 if there was an error. */intdict_insert_word (dict *dt, const char *w) { int *x; char *s; x = g_hash_table_lookup (dt->ht, w); if (!x) { x = my_malloc (sizeof(int)); s = my_strdup (w); if (dt->reuse) { if (array_get_size (dt->reuse) > 0) *x = iarray_pop_value (dt->reuse); else *x = dt->size++; } else *x = dt->size++; g_hash_table_insert (dt->ht, s, x); if (dt->num) varray_put_value (dt->num, *x, (void *)s); } return *x;}/** * Insert a word into the dictionary hash table with a specified number. * * @param dt dictionary to use * @param w word to insert * @param num the number of the word * @return The number of the word in the table, or -1 if there was an error. */intdict_insert_word_x (dict *dt, const char *w, int num) { int *x; char *s; x = g_hash_table_lookup (dt->ht, w); if (!x) { x = my_malloc (sizeof(int)); s = my_strdup (w); *x = num; dt->size++; g_hash_table_insert (dt->ht, s, x); if (dt->num) varray_put_value (dt->num, *x, (void *)s); } return *x;}/** * Find a word in a dictionary. * * @param dt dictionary to use * @param w word to look for * @return The number of the word in the table, or -1 if not present. */intdict_find_word (dict *dt, const char *w) { int *x; x = g_hash_table_lookup (dt->ht, w); if (!x) return -1; return *x;}/** * Remove a word from a dictionary. * * @param dt dictionary to use * @param w word to remove * @return Zero if word was removed, or nonzero if word was not present. */intdict_remove_word_num (dict *dt, int n) { char *w; int *x; if (dt->num) { w = (char *)array_get_value (dt->num, n); array_set_value (dt->num, n, NULL); // Not really necessary x = g_hash_table_lookup (dt->ht, w); g_hash_table_remove (dt->ht, w); if (x) { iarray_append (dt->reuse, *x); free (x); } free (w); } return -1;}/** * Get size of dictionary. * * @param dt dictionary to use * @return The size. */intdict_get_size (dict *dt) { return dt->size; // - array_get_size (dt->reuse);}/** * Print a dictinary word on stdout. * * @param w word to print */static voiddict_print_word (gpointer key, gpointer value, gpointer user_data) { printf ("%s -> %d\n", (char *)key, *(int *)value);}/** * Print a dictionary on stdout. * * @param dt dictionary to print */voiddict_print (dict *dt) { g_hash_table_foreach (dt->ht, dict_print_word, NULL);}/** * Apply a function on each word in a dictionary. * * @param dt dictionary to use * @param wf function to apply */voiddict_for_each (dict *dt, GHFunc wf) { g_hash_table_foreach (dt->ht, wf, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -