-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhtable.c
More file actions
123 lines (103 loc) · 3.13 KB
/
htable.c
File metadata and controls
123 lines (103 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mylib.h"
#include "htable.h"
struct htablerec {
int capacity;
int num_keys;
int *frequencies;
char **keys;
};
htable htable_new(int capacity) {
int i;
htable h = emalloc(sizeof * h);
h->capacity = capacity;
h->num_keys = 0;
h->frequencies = emalloc(h->capacity * sizeof h->frequencies[0]);
h->keys = emalloc(h->capacity * sizeof h->keys[0]);
for (i = 0; i < h->capacity; i++) {
h->frequencies[i] = 0;
h->keys[i] = NULL;
}
return h;
}
void htable_free(htable h) {
int i;
for (i = 0; i < h->capacity; i++) {
free(h->keys[i]);
}
free(h->keys);
free(h->frequencies);
free(h);
}
static unsigned int htable_word_to_int(char *word) {
unsigned int result = 0;
while (*word != '\0') {
result = (*word++ + 31 * result);
}
return result;
}
int htable_insert(htable h, char *str) {
unsigned int result = htable_word_to_int(str);
int index = (result % h->capacity);
int collisions;
/* posibility 1) no string at position */
if (h->keys[index] == NULL) {
h->keys[index] = emalloc((strlen(str) + 1) * sizeof h->keys[0][0]);
strcpy(h->keys[index], str);
h->frequencies[index]++;
h->num_keys++;
return 1;
}
/* Possibility 2) same string at that position */
else if (strcmp(h->keys[index], str) == 0) {
h->frequencies[index]++;
return h->frequencies[index];
}
/* possibility 3) wrong str at that position */
else if (h->keys[index] != NULL && (strcmp(h->keys[index], str) != 0)) {
/* if htable is full */
if (h->num_keys == h->capacity) {
return 0;
} else {
for (collisions = 1; collisions < h->capacity; collisions++) {
if (h->keys[(index + 1) % h->capacity] == NULL) {
h->keys[(index + 1) % h->capacity] = emalloc((strlen(str) + 1) * sizeof h->keys[0][0]);
strcpy(h->keys[(index + 1) % h->capacity], str);
h->frequencies[(index + 1) % h->capacity] = 1;
h->num_keys++;
return 1;
}
else if (strcmp(h->keys[(index + 1) % h->capacity], str) == 0) {
h->frequencies[(index + 1) % h->capacity]++;
return h->frequencies[(index + 1) % h->capacity];
}
}
return 0;
}
}
return 0;
}
void htable_print(htable h, FILE *stream) {
int i;
for (i = 0; i < h->capacity; i++) {
if (h->frequencies[i] > 0) {
fprintf(stream, "%d coppies of %s\n", h->frequencies[i], h->keys[i]);
}
}
}
int htable_search(htable h, char *str) {
int collisions = 0;
unsigned int result = htable_word_to_int(str);
int index = (result % h->capacity);
while (h->keys[index] != NULL && collisions < h->capacity) {
if (strcmp(h->keys[index], str) != 0) {
collisions++;
index++;
} else {
return h->frequencies[index];
}
}
return 0;
}