void Insert(char * str) { Trie * p = root; int len = strlen(str); for(int i = 0; i < len; i++) { int idx = hash(str[i]); if(!p->child[idx]) p->child[idx] = NewTrie(); p = p->child[idx]; } p->isword = 1; }
Trie * add_Trie(const char *name, Trie **triepp) { Trie *curp; if ( *name == NUL ) { /* See if name already exists. */ if ( *triepp == TRIE_NULL ) { /* Name does not exist, make leaf node. */ NewTrie( *triepp ); (*triepp)->l.t_altr = (*triepp)->l.t_next = TRIE_NULL; (*triepp)->l.t_octp = OCLIST_NULL; } else if ( (*triepp)->n.t_next != TRIE_NULL ) { /* Name is subset of another name. */ return add_Trie( name, &(*triepp)->n.t_altr ); } return *triepp; } for ( curp = *triepp; curp != TRIE_NULL && *name != curp->n.t_char; curp = curp->n.t_altr ) ; if ( curp == TRIE_NULL ) { /* No Match, this level, so create new alternate. */ curp = *triepp; NewTrie( *triepp ); (*triepp)->n.t_altr = curp; (*triepp)->n.t_char = *name; (*triepp)->n.t_next = TRIE_NULL; return add_Trie( ++name, &(*triepp)->n.t_next ); } else /* Found matching character. */ return add_Trie( ++name, &curp->n.t_next ); }
void TrieInsert(Trie *pnt,char *s,int len) { Trie *temp = pnt; for(int i=0;i<len;++i) { if(temp->son[s[i]-base]==NULL) temp->son[s[i]-base]=NewTrie(); else temp->son[s[i]-base]->num++; temp = temp->son[s[i]-base]; } temp->terminal = true; }
/* ## FT.SUGGADD key string score [INCR] [PAYLOAD {payload}] Add a suggestion string to an auto-complete suggestion dictionary. This is disconnected from the index definitions, and leaves creating and updating suggestino dictionaries to the user. ### Parameters: - key: the suggestion dictionary key. - string: the suggestion string we index - score: a floating point number of the suggestion string's weight -INCR: if set, we increment the existing entry of the suggestion by the given score, instead of replacing the score. This is useful for updating the dictionary based on user queries in real time - PAYLOAD: Add a payload to the suggestion string that will be used as additional information. ### Returns: Integer reply: the current size of the suggestion dictionary. */ int RSSuggestAddCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc < 4 || argc > 7) { return RedisModule_WrongArity(ctx); } int incr = 0, rv = AC_OK; RSPayload payload = {0}; ArgsCursor ac = {0}; ArgsCursor_InitRString(&ac, argv + 4, argc - 4); while (!AC_IsAtEnd(&ac)) { const char *s = AC_GetStringNC(&ac, NULL); if (!strcasecmp(s, "INCR")) { incr = 1; } else if (!strcasecmp(s, "PAYLOAD")) { if ((rv = AC_GetString(&ac, (const char **)&payload.data, &payload.len, 0)) != AC_OK) { return RMUtil_ReplyWithErrorFmt(ctx, "Invalid payload: %s", AC_Strerror(rv)); } } else { return RMUtil_ReplyWithErrorFmt(ctx, "Unknown argument `%s`", s); } } RedisModule_AutoMemory(ctx); /* Use automatic memory management. */ RedisModuleKey *key = RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE); int type = RedisModule_KeyType(key); if (type != REDISMODULE_KEYTYPE_EMPTY && RedisModule_ModuleTypeGetType(key) != TrieType) { return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); } RedisModuleString *val = argv[2]; double score; if ((RedisModule_StringToDouble(argv[3], &score) != REDISMODULE_OK)) { return RedisModule_ReplyWithError(ctx, "ERR invalid score"); } /* Create an empty value object if the key is currently empty. */ Trie *tree; if (type == REDISMODULE_KEYTYPE_EMPTY) { tree = NewTrie(); RedisModule_ModuleTypeSetValue(key, TrieType, tree); } else { tree = RedisModule_ModuleTypeGetValue(key); } /* Insert the new element. */ Trie_Insert(tree, val, score, incr, &payload); RedisModule_ReplyWithLongLong(ctx, tree->size); RedisModule_ReplicateVerbatim(ctx); return REDISMODULE_OK; }
/* Trie *addTrie(char *name, Trie **triepp) Insert the name in the trie specified by triepp, if it doesn't already exist there. Return pointer to leaf node associated with name. */ Trie * addTrie(char *name, Trie **triepp) { Trie *curp; if (*name == NUL) { /* End of name, see if name already exists. */ if (*triepp == TRIE_NULL) { /* Name does not exist, make leaf node. */ NewTrie(*triepp); (*triepp)->l.t_altr = (*triepp)->l.t_next = TRIE_NULL; (*triepp)->l.t_func = NULL_FUNC; } else if ((*triepp)->n.t_next != TRIE_NULL) /* Name is subset of another name. */ return addTrie(name, &(*triepp)->n.t_altr); /* else -- Name already inserted, so do nothing. */ return *triepp; } /* Find matching letter, this level. */ for (curp = *triepp; curp != TRIE_NULL && *name != curp->n.t_char; curp = curp->n.t_altr ) ; if (curp == TRIE_NULL) { /* No Match, this level, so create new alternate. */ curp = *triepp; NewTrie(*triepp); (*triepp)->n.t_altr = curp; (*triepp)->n.t_char = *name; (*triepp)->n.t_next = TRIE_NULL; return addTrie(++name, &(*triepp)->n.t_next); } else /* Found matching character. */ return addTrie(++name, &curp->n.t_next); }
int main() { int n, m; while(scanf("%d %d", &m, &n) != EOF) { idx = 0; root = NewTrie(); while(m--) { scanf("%s", str); Insert(str); } Fail(); memset(M.mat, 0, sizeof(M.mat)); for(int i = 0; i < idx; i++) for(int j = 0;j < 4; j++) { Trie * son = t[i].child[j]; if(!son->isword && !t[i].isword) M.mat[i][son->id] ++; } M = M ^ n; ll ans = 0; for(int i = 0; i < idx; i++) ans = (ans + M.mat[0][i]) % MOD; printf("%I64d\n", ans); } return 0; }
RS_Suggestions *RS_SuggestionsCreate() { #define SUGGESTIONS_ARRAY_INITIAL_SIZE 10 RS_Suggestions *ret = calloc(1, sizeof(RS_Suggestions)); ret->suggestionsTrie = NewTrie(); return ret; }