Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fc46c72

Browse files
Word ladder
Signed-off-by: begeekmyfriend <begeekmyfriend@gmail.com>
1 parent c923ab2 commit fc46c72

File tree

3 files changed

+218
-11
lines changed

3 files changed

+218
-11
lines changed

030_substring_with_concatenation_of_all_words/concatenation.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,27 @@ static inline int BKDRHash(char *s, size_t size)
2020

2121
static int find(char *word, struct word_hash *table, int size)
2222
{
23-
int i, first = 1, hash = BKDRHash(word, size);
24-
for (i = hash; first || i != hash; i = ++i % size) {
25-
first = 0;
23+
int hash = BKDRHash(word, size);
24+
int i = hash;
25+
do {
2626
if (table[i].freq > 0 && !strcmp(table[i].word, word)) {
2727
return i;
2828
}
29-
}
29+
i = ++i % size;
30+
} while (i != hash);
3031
return -1;
3132
}
3233

34+
static void add(char *word, struct word_hash *table, int size)
35+
{
36+
int i, hash = BKDRHash(word, size);
37+
for (i = hash; table[i].freq > 0 && strcmp(table[i].word, word); i = ++i % size) {}
38+
if (table[i].freq == 0) {
39+
table[i].word = word;
40+
}
41+
table[i].freq++;
42+
}
43+
3344
/**
3445
** Return an array of size *returnSize.
3546
** Note: The returned array must be malloced, assume caller calls free().
@@ -44,7 +55,7 @@ static int *findSubstring(char *s, char **words, int wordsSize, int *returnSize)
4455
int i, j, cap = 500, count = 0;
4556
char *start = s;
4657
struct word_node *wn;
47-
int hash_size = wordsSize;
58+
int hash_size = wordsSize * 2;
4859
int len = strlen(words[0]);
4960
char *word = malloc(len + 1);
5061
int *indexes = malloc(cap * sizeof(int));
@@ -53,12 +64,7 @@ static int *findSubstring(char *s, char **words, int wordsSize, int *returnSize)
5364

5465
memset(table, 0, hash_size * sizeof(*table));
5566
for (i = 0; i < wordsSize; i++) {
56-
int hash = BKDRHash(words[i], hash_size);
57-
for (j = hash; table[j].freq > 0 && strcmp(table[j].word, words[i]); j = ++j % hash_size) {}
58-
if (table[j].freq == 0) {
59-
table[j].word = words[i];
60-
}
61-
table[j].freq++;
67+
add(words[i], table, hash_size);
6268
}
6369

6470
word[len] = '\0';

127_word_ladder/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc -O2 -o test word_ladder.c

127_word_ladder/word_ladder.c

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
struct hlist_node;
6+
7+
struct hlist_head {
8+
struct hlist_node *first;
9+
};
10+
11+
struct hlist_node {
12+
struct hlist_node *next, **pprev;
13+
};
14+
15+
static inline void INIT_HLIST_HEAD(struct hlist_head *h) {
16+
h->first = NULL;
17+
}
18+
19+
static inline void INIT_HLIST_NODE(struct hlist_node *n) {
20+
n->next = NULL;
21+
n->pprev = NULL;
22+
}
23+
24+
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
25+
{
26+
if (h->first != NULL) {
27+
h->first->pprev = &n->next;
28+
}
29+
n->next = h->first;
30+
n->pprev = &h->first;
31+
h->first = n;
32+
}
33+
34+
struct list_head {
35+
struct list_head *next, *prev;
36+
};
37+
38+
static inline void
39+
INIT_LIST_HEAD(struct list_head *list)
40+
{
41+
list->next = list->prev = list;
42+
}
43+
44+
static inline int
45+
list_empty(const struct list_head *head)
46+
{
47+
return (head->next == head);
48+
}
49+
50+
static inline void
51+
__list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
52+
{
53+
next->prev = new;
54+
new->next = next;
55+
new->prev = prev;
56+
prev->next = new;
57+
}
58+
59+
static inline void
60+
list_add(struct list_head *_new, struct list_head *head)
61+
{
62+
__list_add(_new, head, head->next);
63+
}
64+
65+
static inline void
66+
list_add_tail(struct list_head *_new, struct list_head *head)
67+
{
68+
__list_add(_new, head->prev, head);
69+
}
70+
71+
static inline void
72+
__list_del(struct list_head *entry)
73+
{
74+
entry->next->prev = entry->prev;
75+
entry->prev->next = entry->next;
76+
}
77+
78+
static inline void
79+
list_del(struct list_head *entry)
80+
{
81+
__list_del(entry);
82+
entry->next = entry->prev = NULL;
83+
}
84+
85+
#define container_of(ptr, type, member) \
86+
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
87+
88+
#define list_entry(ptr, type, member) \
89+
container_of(ptr, type, member)
90+
91+
#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field)
92+
#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)
93+
94+
#define list_for_each(p, head) \
95+
for (p = (head)->next; p != (head); p = p->next)
96+
97+
#define list_for_each_safe(p, n, head) \
98+
for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
99+
100+
#define hlist_for_each(pos, head) \
101+
for (pos = (head)->first; pos; pos = pos->next)
102+
103+
#define hlist_for_each_safe(pos, n, head) \
104+
for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n)
105+
106+
struct word_node {
107+
int step;
108+
char *word;
109+
struct hlist_node node;
110+
struct list_head link;
111+
};
112+
113+
static int BKDRHash(char* str, int size)
114+
{
115+
int seed = 131; // 31 131 1313 13131 131313 etc..
116+
unsigned int hash = 0 ;
117+
while (*str != '\0') {
118+
hash = hash * seed + (*str++);
119+
}
120+
return hash % size;
121+
}
122+
123+
static struct word_node *find(char *word, struct hlist_head *hhead, int size)
124+
{
125+
struct hlist_node *p;
126+
int hash = BKDRHash(word, size);
127+
hlist_for_each(p, &hhead[hash]) {
128+
struct word_node *node = list_entry(p, struct word_node, node);
129+
if (node->step == 0 && !strcmp(node->word, word)) {
130+
return node;
131+
}
132+
}
133+
return NULL;
134+
}
135+
136+
static int ladderLength(char* beginWord, char* endWord, char** wordList, int wordListSize)
137+
{
138+
int i, len = strlen(beginWord);
139+
char *word = malloc(len + 1);
140+
struct list_head queue;
141+
struct word_node *node;
142+
143+
struct hlist_head *hhead = malloc(wordListSize * sizeof(*hhead));
144+
for (i = 0; i < wordListSize; i++) {
145+
INIT_HLIST_HEAD(hhead + i);
146+
}
147+
148+
/* Add into hash list */
149+
for (i = 0; i < wordListSize; i++) {
150+
node = malloc(sizeof(*node));
151+
node->word = wordList[i];
152+
node->step = 0;
153+
int hash = BKDRHash(wordList[i], wordListSize);
154+
hlist_add_head(&node->node, &hhead[hash]);
155+
}
156+
157+
INIT_LIST_HEAD(&queue);
158+
struct word_node *first = malloc(sizeof(*node));
159+
first->word = beginWord;
160+
first->step = 1;
161+
162+
while (strcmp(first->word, endWord)) {
163+
strcpy(word, first->word);
164+
for (i = 0; i < len; i++) {
165+
char c;
166+
char o = word[i];
167+
for (c = 'a'; c <= 'z'; c++) {
168+
if (c == o) continue;
169+
word[i] = c;
170+
node = find(word, hhead, wordListSize);
171+
if (node != NULL) {
172+
list_add_tail(&node->link, &queue);
173+
node->step = first->step + 1;
174+
}
175+
}
176+
word[i] = o;
177+
}
178+
179+
if (list_empty(&queue)) {
180+
return 0;
181+
} else {
182+
first = list_first_entry(&queue, struct word_node, link);
183+
list_del(&first->link);
184+
}
185+
}
186+
187+
return first->step;
188+
}
189+
190+
int main(int argc, char **argv)
191+
{
192+
if (argc < 3) {
193+
fprintf(stderr, "Usage: ./test begin end dict...\n");
194+
exit(-1);
195+
}
196+
197+
printf("%d\n", ladderLength(argv[1], argv[2], argv + 3, argc - 3));
198+
return 0;
199+
}

0 commit comments

Comments
 (0)