11#include <stdio.h>
22#include <stdlib.h>
33#include <string.h>
4- #include "../uthash.h"
5-
6- struct str_hash {
7- char * str ;
8- int * indexes ;
9- int freq ;
10- int cap ;
11- UT_hash_handle hh ;
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 int hlist_empty (struct hlist_head * h ) {
20+ return !h -> first ;
21+ }
22+
23+ static inline void hlist_add_head (struct hlist_node * n , struct hlist_head * h )
24+ {
25+ if (h -> first != NULL ) {
26+ h -> first -> pprev = & n -> next ;
27+ }
28+ n -> next = h -> first ;
29+ n -> pprev = & h -> first ;
30+ h -> first = n ;
31+ }
32+
33+ #define container_of (ptr , type , member ) \
34+ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
35+
36+ #define list_entry (ptr , type , member ) \
37+ container_of(ptr, type, member)
38+
39+ #define hlist_for_each (pos , head ) \
40+ for (pos = (head)->first; pos; pos = pos->next)
41+
42+ struct word_node {
43+ struct hlist_node node ;
44+ int index ;
1245};
1346
14- static struct str_hash * hash_table = NULL ;
47+ struct word_hash {
48+ struct hlist_head head ;
49+ char * word ;
50+ int num ;
51+ };
1552
1653static void insert_sort (char * s , int len )
1754{
18- long i , j ;
55+ int i , j ;
1956 for (i = 1 ; i < len ; i ++ ) {
2057 char tmp = s [i ];
2158 j = i - 1 ;
@@ -26,68 +63,81 @@ static void insert_sort(char *s, int len)
2663 }
2764}
2865
66+ static inline int BKDRHash (char * s , size_t size )
67+ {
68+ int seed = 31 ; /* 131 1313 13131... */
69+ unsigned long hash = 0 ;
70+ while (* s != '\0' ) {
71+ hash = hash * seed + * s ++ ;
72+ }
73+ return hash % size ;
74+ }
75+
2976/**
3077 ** Return an array of arrays of size *returnSize.
3178 ** The sizes of the arrays are returned as *columnSizes array.
3279 ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
3380 **/
3481static char * * * groupAnagrams (char * * strs , int strsSize , int * * columnSizes , int * returnSize ) {
3582 int i , j , count = 0 ;
36- struct str_hash * obj , * tmp ;
37- char * * words = malloc (strsSize * sizeof (char * ));
83+ struct word_node * wn ;
3884
85+ int hash_size = strsSize ;
86+ struct word_hash * ht = malloc (hash_size * sizeof (* ht ));
87+ for (i = 0 ; i < hash_size ; i ++ ) {
88+ INIT_HLIST_HEAD (& ht [i ].head );
89+ ht [i ].num = 0 ;
90+ }
91+
92+ char * * words = malloc (strsSize * sizeof (char * ));
3993 for (i = 0 ; i < strsSize ; i ++ ) {
4094 int len = strlen (strs [i ]);
4195 words [i ] = malloc (len + 1 );
4296 strcpy (words [i ], strs [i ]);
4397 insert_sort (words [i ], len );
44- HASH_FIND_STR (hash_table , words [i ], obj );
45- if (obj == NULL ) {
46- obj = malloc (sizeof (* obj ));
47- obj -> str = words [i ];
48- obj -> freq = 1 ;
49- obj -> cap = 1 ;
50- obj -> indexes = malloc (sizeof (int ));
51- obj -> indexes [0 ] = i ;
52- HASH_ADD_STR (hash_table , str , obj );
98+ int hash = BKDRHash (words [i ], hash_size );
99+ /* find available hash bucket */
100+ for (j = hash ; ht [j ].num > 0 && strcmp (ht [j ].word , words [i ]); j = ++ j % hash_size ) {}
101+ wn = malloc (sizeof (* wn ));
102+ wn -> index = i ;
103+ if (ht [j ].num == 0 ) {
104+ ht [j ].word = words [i ];
53105 count ++ ;
54- } else {
55- if (obj -> freq + 1 >= obj -> cap ) {
56- obj -> cap *= 2 ;
57- obj -> indexes = realloc (obj -> indexes , obj -> cap * sizeof (int ));
58- }
59- obj -> indexes [obj -> freq ++ ] = i ;
60106 }
107+ hlist_add_head (& wn -> node , & ht [j ].head );
108+ ht [j ].num ++ ;
61109 }
62110
63- char * * * ret_lists = malloc (count * sizeof (char * * ));
64- int * column_sizes = malloc (count * sizeof (int ));
65-
66- i = 0 ;
67- HASH_ITER (hh , hash_table , obj , tmp ) {
68- ret_lists [i ] = malloc (obj -> freq * sizeof (char * ));
69- column_sizes [i ] = obj -> freq ;
70- for (j = 0 ; j < column_sizes [i ]; j ++ ) {
71- ret_lists [i ][j ] = strs [obj -> indexes [j ]];
111+ j = 0 ;
112+ struct hlist_node * p ;
113+ char * * * lists = malloc (count * sizeof (char * * ));
114+ * columnSizes = malloc (count * sizeof (int ));
115+ for (i = 0 ; i < hash_size ; i ++ ) {
116+ if (ht [i ].num > 0 ) {
117+ (* columnSizes )[j ] = ht [i ].num ;
118+ lists [j ] = malloc (ht [i ].num * sizeof (char * ));
119+ int k = 0 ;
120+ hlist_for_each (p , & ht [i ].head ) {
121+ wn = list_entry (p , struct word_node , node );
122+ lists [j ][k ++ ] = strs [wn -> index ];
123+ }
124+ j ++ ;
72125 }
73- HASH_DEL (hash_table , obj );
74- free (obj );
75- i ++ ;
76126 }
77127
78- * columnSizes = column_sizes ;
79128 * returnSize = count ;
80- return ret_lists ;
129+ return lists ;
81130}
82131
83132int main (int argc , char * * argv )
84133{
85- int * column_sizes , count , i , j ;
134+ int * column_sizes , count = 0 , i , j ;
86135 char * * * lists = groupAnagrams (argv + 1 , argc - 1 , & column_sizes , & count );
87136 for (i = 0 ; i < count ; i ++ ) {
88137 for (j = 0 ; j < column_sizes [i ]; j ++ ) {
89- printf ("%s\n " , lists [i ][j ]);
138+ printf ("%s " , lists [i ][j ]);
90139 }
140+ printf ("\n" );
91141 }
92142 return 0 ;
93143}
0 commit comments