HASH - C


SUBMITTED BY: bitcoinsachen

DATE: Dec. 14, 2016, 9:44 p.m.

UPDATED: Dec. 14, 2016, 9:52 p.m.

FORMAT: C

SIZE: 12.4 kB

HITS: 411

  1. #ifndef HEADER_H_INCLUDED
  2. #define HEADER_H_INCLUDED
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. typedef struct hashentry__s
  7. {
  8. char songtitle[256], interpreter[256];
  9. } hashentry_t;
  10. typedef struct hasharray__s
  11. {
  12. hashentry_t *entries;
  13. long num_entries;
  14. } hasharray_t;
  15. typedef struct hashcontainer__s
  16. {
  17. hasharray_t *harrays;
  18. long hashsize;
  19. } hashcontainer_t;
  20. long hash_key(char songtitle[], char interpreter[], long hash_max);
  21. hashcontainer_t *create_hash(long hashsize);
  22. void delete_hash(hashcontainer_t *hashcontainer);
  23. void insert_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[]);
  24. hashentry_t *search_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[]);
  25. void delete_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[]);
  26. void print_hash(hashcontainer_t *hashcontainer);
  27. long count_entries(hashcontainer_t *hashcontainer);
  28. long count_entries_with_songtitle(hashcontainer_t *hashcontainer, char songtitle[]);
  29. void insert_entry_ext_exp(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[], long(*hashkey_gen)(hashentry_t *entry, long hash_max));
  30. void insert_entry_ext(hashcontainer_t *hashcontainer, hashentry_t *hashentry, long(*hashkey_gen)(hashentry_t *entry, long hash_max));
  31. long hashkey_gen1(hashentry_t *entry, long hash_max);
  32. long hashkey_gen2(hashentry_t *entry, long hash_max);
  33. void rehash1(hashcontainer_t *hashcontainer, long(*hashkey_gen)(hashentry_t *entry, long hash_max), long hash_max);
  34. void rehash2(hashcontainer_t *hashcontainer, long(*hashkey_gen)(hashentry_t *entry, long hash_max), long hash_max);
  35. #endif // HEADER_H_INCLUDED
  36. #include "header.h"
  37. long hash_key(char songtitle[], char interpreter[], long hash_max)
  38. {
  39. unsigned long i, index = 0;
  40. for (i = 0; i < strlen(songtitle); ++i)
  41. index = 64 * index + (long)(songtitle[i]);
  42. for (i = 0; i < strlen(interpreter); ++i)
  43. index = 64 * index + (long)(interpreter[i]);
  44. return index % hash_max;
  45. }
  46. long hashkey_gen1(hashentry_t *entry, long hash_max)
  47. {
  48. unsigned long i, index = 0;
  49. for (i = 0; i < strlen(entry->songtitle); ++i)
  50. index = 64 * index + (long)(entry->songtitle[i]);
  51. for (i = 0; i < strlen(entry->interpreter); ++i)
  52. index = 64 * index + (long)(entry->interpreter[i]);
  53. return index % hash_max;
  54. }
  55. hashcontainer_t *create_hash(long hashsize)
  56. {
  57. unsigned long i;
  58. hashcontainer_t *new = 0;
  59. if (!(new = malloc(sizeof(hashcontainer_t))))
  60. {
  61. fprintf(stderr, "Memory allocation error in create_hash()");
  62. exit(-1);
  63. }
  64. if (!(new->harrays = calloc(hashsize, sizeof(hasharray_t))))
  65. {
  66. fprintf(stderr, "Memory allocation error in create_hash()");
  67. exit(-1);
  68. }
  69. new->hashsize = hashsize;
  70. for (i = 0; i < hashsize; i++)
  71. {
  72. new->harrays[i];
  73. }
  74. return new;
  75. }
  76. void delete_hash(hashcontainer_t *hashcontainer)
  77. {
  78. unsigned long i;
  79. for (i = 0; i < hashcontainer->hashsize; i++)
  80. {
  81. if (hashcontainer->harrays[i].entries)
  82. {
  83. free(hashcontainer->harrays[i].entries);
  84. hashcontainer->harrays[i].entries = 0;
  85. hashcontainer->harrays[i].num_entries = 0;
  86. }
  87. }
  88. free(hashcontainer->harrays);
  89. hashcontainer->harrays = 0;
  90. hashcontainer->hashsize = 0;
  91. }
  92. void insert_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[])
  93. {
  94. unsigned long index = hash_key(songtitle, interpreter, hashcontainer->hashsize);
  95. hashcontainer->harrays[index].num_entries++;
  96. hashcontainer->harrays[index].entries = realloc(hashcontainer->harrays[index].entries, hashcontainer->harrays[index].num_entries * sizeof(hashentry_t));
  97. strcpy(hashcontainer->harrays[index].entries[hashcontainer->harrays[index].num_entries - 1].songtitle, songtitle);
  98. strcpy(hashcontainer->harrays[index].entries[hashcontainer->harrays[index].num_entries - 1].interpreter, interpreter);
  99. }
  100. hashentry_t *search_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[])
  101. {
  102. unsigned long index = hash_key(songtitle, interpreter, hashcontainer->hashsize);
  103. unsigned long len = hashcontainer->harrays[index].num_entries, i;
  104. for (i = 0; i < len; i++)
  105. {
  106. if ((strcmp(hashcontainer->harrays[index].entries[i].interpreter, interpreter) == 0) && (strcmp(hashcontainer->harrays[index].entries[i].songtitle, songtitle) == 0))
  107. return (hashcontainer->harrays[index].entries)+i;
  108. }
  109. return 0;
  110. }
  111. void delete_entry(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[])
  112. {
  113. unsigned long index = hash_key(songtitle, interpreter, hashcontainer->hashsize);
  114. unsigned long len = hashcontainer->harrays[index].num_entries, i;
  115. for (i = 0; i < len; i++)
  116. {
  117. if ((strcmp(hashcontainer->harrays[index].entries[i].interpreter, interpreter) == 0) && (strcmp(hashcontainer->harrays[index].entries[i].songtitle, songtitle) == 0))
  118. {
  119. if (i == 0 && len == 1)
  120. {
  121. free(hashcontainer->harrays[index].entries);
  122. hashcontainer->harrays[index].entries = 0;
  123. hashcontainer->harrays[index].num_entries = 0;
  124. }
  125. else
  126. {
  127. if (i != len - 1)
  128. memcpy(hashcontainer->harrays[index].entries + i, hashcontainer->harrays[index].entries + i + 1, (len - i - 1)* sizeof(hashentry_t));
  129. hashcontainer->harrays[index].entries = realloc(hashcontainer->harrays[index].entries, --hashcontainer->harrays[index].num_entries * sizeof(hashentry_t));
  130. }
  131. }
  132. }
  133. }
  134. void print_hash(hashcontainer_t *hashcontainer)
  135. {
  136. unsigned long i, j;
  137. for (i = 0; i < hashcontainer->hashsize; i++)
  138. {
  139. fprintf(stdout, "Hash index %ld\n", i);
  140. for (j = 0; j < hashcontainer->harrays[i].num_entries; j++)
  141. {
  142. fprintf(stdout, "%s\t%s\n", hashcontainer->harrays[i].entries[j].songtitle, hashcontainer->harrays[i].entries[j].interpreter);
  143. }
  144. fprintf(stdout, "\n");
  145. }
  146. }
  147. long count_entries(hashcontainer_t *hashcontainer)
  148. {
  149. unsigned long i, j, count = 0;
  150. for (i = 0; i < hashcontainer->hashsize; i++)
  151. {
  152. for (j = 0; j < hashcontainer->harrays[i].num_entries; j++)
  153. {
  154. count++;
  155. }
  156. }
  157. return count;
  158. }
  159. long count_entries_with_songtitle(hashcontainer_t *hashcontainer, char songtitle[])
  160. {
  161. unsigned long i, j, count = 0;
  162. for (i = 0; i < hashcontainer->hashsize; i++)
  163. {
  164. for (j = 0; j < hashcontainer->harrays[i].num_entries; j++)
  165. {
  166. if (strcmp(hashcontainer->harrays[i].entries[j].songtitle, songtitle) == 0)
  167. count++;
  168. }
  169. }
  170. return count;
  171. }
  172. void insert_entry_ext_exp(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[], long(*hashkey_gen)(hashentry_t *entry, long hash_max))
  173. {
  174. hashentry_t *new = malloc(sizeof(hashentry_t));
  175. strcpy(new->songtitle, songtitle);
  176. strcpy(new->interpreter, interpreter);
  177. unsigned long index = hashkey_gen(new, hashcontainer->hashsize);
  178. hashcontainer->harrays[index].num_entries++;
  179. hashcontainer->harrays[index].entries = realloc(hashcontainer->harrays[index].entries, hashcontainer->harrays[index].num_entries * sizeof(hashentry_t));
  180. memcpy(hashcontainer->harrays[index].entries + hashcontainer->harrays[index].num_entries - 1, new, sizeof(hashentry_t));
  181. }
  182. void insert_entry_ext(hashcontainer_t *hashcontainer, hashentry_t *new, long(*hashkey_gen)(hashentry_t *entry, long hash_max))
  183. {
  184. unsigned long index = hashkey_gen(new, hashcontainer->hashsize);
  185. hashcontainer->harrays[index].num_entries++;
  186. hashcontainer->harrays[index].entries = realloc(hashcontainer->harrays[index].entries, hashcontainer->harrays[index].num_entries * sizeof(hashentry_t));
  187. memcpy(hashcontainer->harrays[index].entries + hashcontainer->harrays[index].num_entries - 1, new, sizeof(hashentry_t));
  188. }
  189. hashentry_t *search_entry_ext(hashcontainer_t *hashcontainer, char songtitle[], char interpreter[], long(*hashkey_gen)(hashentry_t *entry, long hash_max))
  190. {
  191. hashentry_t *new = malloc(sizeof(hashentry_t));
  192. strcpy(new->songtitle, songtitle);
  193. strcpy(new->interpreter, interpreter);
  194. unsigned long index = hashkey_gen(new, hashcontainer->hashsize);
  195. unsigned long i;
  196. for (i = 0; i < hashcontainer->harrays[index].num_entries; i++)
  197. {
  198. if ((strcmp(hashcontainer->harrays[index].entries[i].interpreter, interpreter) == 0) && (strcmp(hashcontainer->harrays[index].entries[i].songtitle, songtitle) == 0))
  199. return (hashcontainer->harrays[index].entries)+i;
  200. }
  201. return 0;
  202. }
  203. void rehash1(hashcontainer_t *hashcontainer, long(*hashkey_gen)(hashentry_t *entry, long hash_max), long hash_max)
  204. {
  205. hashcontainer_t *new = create_hash(hash_max);
  206. unsigned long i, j;
  207. for (i = 0; i < hashcontainer->hashsize; i++)
  208. {
  209. for (j = 0; j < hashcontainer->harrays[i].num_entries; j++)
  210. {
  211. insert_entry_ext(new, hashcontainer->harrays[i].entries + j, hashkey_gen);
  212. }
  213. }
  214. delete_hash(hashcontainer);
  215. hashcontainer->harrays = new->harrays;
  216. hashcontainer->hashsize = new->hashsize;
  217. }
  218. void rehash2(hashcontainer_t *hashcontainer, long(*hashkey_gen)(hashentry_t *entry, long hash_max), long hash_max)
  219. {
  220. unsigned long i, j, count = 0, len = count_entries(hashcontainer);
  221. hashentry_t temp[len];
  222. for (i = 0; i < hashcontainer->hashsize; i++)
  223. {
  224. for (j = 0; j < hashcontainer->harrays[i].num_entries; j++)
  225. {
  226. strcpy(temp[count].songtitle, hashcontainer->harrays[i].entries[j].songtitle);
  227. strcpy(temp[count].interpreter, hashcontainer->harrays[i].entries[j].interpreter);
  228. count++;
  229. }
  230. }
  231. delete_hash(hashcontainer);
  232. hashcontainer_t *new = create_hash(hash_max);
  233. for (i = 0; i < len; i++)
  234. {
  235. insert_entry_ext(new, &temp[i], hashkey_gen);
  236. }
  237. hashcontainer->harrays = new->harrays;
  238. hashcontainer->hashsize = new->hashsize;
  239. free(new);
  240. }
  241. #include "source.c"
  242. int main()
  243. {
  244. hashcontainer_t *container = create_hash(3);
  245. insert_entry_ext_exp(container, "Title1", "Inter1", hashkey_gen1);
  246. insert_entry_ext_exp(container, "Title2", "Inter2", hashkey_gen1);
  247. insert_entry_ext_exp(container, "Title2", "Inter2", hashkey_gen1);
  248. insert_entry_ext_exp(container, "Title3", "Inter3", hashkey_gen1);
  249. insert_entry_ext_exp(container, "Title3", "Inter3", hashkey_gen1);
  250. insert_entry_ext_exp(container, "Title3", "Inter3", hashkey_gen1);
  251. insert_entry_ext_exp(container, "Title3", "Inter3", hashkey_gen1);
  252. insert_entry_ext_exp(container, "Title4", "Inter4", hashkey_gen1);
  253. insert_entry_ext_exp(container, "Title7", "Inter7", hashkey_gen1);
  254. insert_entry_ext_exp(container, "Title7", "Inter7", hashkey_gen1);
  255. delete_entry(container, "Title7", "Inter7");
  256. print_hash(container);
  257. fprintf(stdout, "\nRehashing...\n\n");
  258. rehash1(container, hashkey_gen1, 11);
  259. print_hash(container);
  260. hashentry_t *temp = search_entry_ext(container, "Title7", "Inter7", hashkey_gen1);
  261. if (temp)
  262. fprintf(stdout, "%s\t%s\n", temp->songtitle, temp->interpreter);
  263. else
  264. fprintf(stdout, "Not found.\n");
  265. fprintf(stdout, "%ld entries found.", count_entries(container));
  266. delete_hash(container);
  267. free(container);
  268. return 0;
  269. }

comments powered by Disqus