Skip to content

Commit

Permalink
Word break
Browse files Browse the repository at this point in the history
Signed-off-by: begeekmyfriend <[email protected]>
  • Loading branch information
begeekmyfriend committed Sep 22, 2017
1 parent 3ab8518 commit 5c5b1cf
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 18 deletions.
2 changes: 2 additions & 0 deletions 140_word_break_ii/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
gcc -O2 -o test word_break.c
208 changes: 208 additions & 0 deletions 140_word_break_ii/word_break.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct list_head {
struct list_head *next, *prev;
};

static inline void
INIT_LIST_HEAD(struct list_head *list)
{
list->next = list->prev = list;
}

static inline int
list_empty(const struct list_head *head)
{
return (head->next == head);
}

static inline void
__list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}

static inline void
list_add(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head, head->next);
}

static inline void
list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}

static inline void
__list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
}

static inline void
list_del(struct list_head *entry)
{
__list_del(entry);
entry->next = entry->prev = NULL;
}

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))

#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

#define list_for_each(p, head) \
for (p = (head)->next; p != (head); p = p->next)

#define list_for_each_safe(p, n, head) \
for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)

struct word_node {
char *word;
struct list_head link;
};

struct recur_cache {
int num;
int cap;
struct list_head **heads;
};

static struct recur_cache *resize(struct recur_cache **caches, int index)
{
int i;
struct recur_cache *cache = caches[index];
if (cache->num + 1 > cache->cap) {
cache->cap *= 2;
struct list_head **heads = malloc(cache->cap * sizeof(*heads));
for (i = 0; i < cache->cap; i++) {
if (i < cache->num) {
heads[i] = cache->heads[i];
} else {
heads[i] = malloc(sizeof(struct list_head));
INIT_LIST_HEAD(heads[i]);
}
}
free(cache->heads);
cache->heads = heads;
}

return cache;
}

static struct recur_cache *recursive(char *s, char **words, int *sizes, int num,
struct recur_cache **caches, int len, int index)
{
int i, j;
struct word_node *wn;
struct recur_cache *result;

if (*s == '\0') {
return NULL;
} else if (caches[index] != NULL) {
return caches[index];
} else {
result = malloc(sizeof(*result));
result->num = 0;
result->cap = 1;
result->heads = malloc(sizeof(struct list_head *));
result->heads[0] = malloc(sizeof(struct list_head));
INIT_LIST_HEAD(result->heads[0]);
caches[index] = result;
for (i = 0; i < num; i++) {
if (!memcmp(s, words[i], sizes[i])) {
struct recur_cache *next = recursive(s + sizes[i], words, sizes, num, caches, len, index + sizes[i]);
if (next != NULL) {
int k = result->num;
for (j = k; j < k + next->num; j++) {
result = resize(caches, index);
wn = malloc(sizeof(*wn));
wn->word = words[i];
list_add(&wn->link, result->heads[j]);

struct list_head *p;
list_for_each(p, next->heads[j - k]) {
struct word_node *wnn = list_entry(p, struct word_node, link);
wn = malloc(sizeof(*wn));
wn->word = wnn->word;
list_add_tail(&wn->link, result->heads[j]);
}
result->num++;
}
} else {
wn = malloc(sizeof(*wn));
wn->word = words[i];
list_add(&wn->link, result->heads[result->num++]);
}
}
}

return result;
}
}

/**
** Return an array of size *returnSize.
** Note: The returned array must be malloced, assume caller calls free().
**/
static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnSize)
{
if (wordDictSize == 0) {
*returnSize = 0;
return NULL;
}

int i, total = 0;
int len = strlen(s);
int *sizes = malloc(wordDictSize * sizeof(int));

/* Add into hash list */
for (i = 0; i < wordDictSize; i++) {
sizes[i] = strlen(wordDict[i]);
total += sizes[i];
}

struct recur_cache **caches = malloc(len * sizeof(*caches));
memset(caches, 0, len * sizeof(*caches));
struct recur_cache *cache = recursive(s, wordDict, sizes, wordDictSize, caches, len, 0);

char **results = malloc(cache->num * sizeof(char *));
for (i = 0; i < cache->num; i++) {
results[i] = malloc(total + 100);
char *p = results[i];
struct list_head *n;
list_for_each(n, cache->heads[i]) {
struct word_node *wn = list_entry(n, struct word_node, link);
char *q = wn->word;
while ((*p++ = *q++) != '\0') {}
*(p - 1) = ' ';
}
*(p - 1) = '\0';
}

*returnSize = cache->num;
return results;
}

int main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "Usage: ./test word dictionary...\n");
exit(-1);
}

int i, count = 0;
char **list = wordBreak(argv[1], argv + 2, argc - 2, &count);
for (i = 0; i < count; i++) {
printf("%s\n", list[i]);
}
return 0;
}
24 changes: 6 additions & 18 deletions 146_lru_cache/lru_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ static inline void hlist_del(struct hlist_node *n)
#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)

#define list_for_each(p, head) \
for (p = (head)->next; p != (head); p = p->next)
for (p = (head)->next; p != (head); p = p->next)

#define list_for_each_safe(p, n, head) \
for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)

struct list_head {
struct list_head *next, *prev;
Expand All @@ -81,18 +81,6 @@ list_empty(const struct list_head *head)
return (head->next == head);
}

static inline int
list_is_first(const struct list_head *list, const struct list_head *head)
{
return list->prev == head;
}

static inline int
list_is_last(const struct list_head *list, const struct list_head *head)
{
return list->next == head;
}

static inline void
__list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{
Expand Down Expand Up @@ -124,15 +112,15 @@ __list_del(struct list_head *entry)
static inline void
list_del(struct list_head *entry)
{
__list_del(entry);
entry->next = entry->prev = NULL;
__list_del(entry);
entry->next = entry->prev = NULL;
}

static inline void
list_move(struct list_head *list, struct list_head *head)
{
__list_del(list);
list_add(list, head);
__list_del(list);
list_add(list, head);
}

static inline void
Expand Down

0 comments on commit 5c5b1cf

Please sign in to comment.