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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy