/*
void mstrcpy(char dst[], const char src[])
{
int c = 0;
while ((dst[c] = src[c]) != 0)
++c;
}
int mstrlen(const char str[])
{
int ret = 0;
while (str[ret])
++ret;
return ret;
}
int mstrcmp(const char str1[], const char str2[])
{
int c = 0;
while (str1[c] != 0 && str1[c] == str2[c])
++c;
return str1[c] - str2[c];
}
*/
struct NODE {
char name[20];
int id;
int count;
bool band;
};
NODE NodePool[25000];
int nodeIndex;
struct TRIE {
TRIE *Child[26];
NODE *Recommend;
NODE *Word;
void init() {
for (register int i = 0; i < 26; i++)
Child[i] = 0;
Recommend = Word = 0;
}
};
TRIE Trie[500000];
TRIE root;
TRIE *Temp[20];
int trieIndex;
int wordId;
int tempIndex;
int mstrCPY(char *des, char *src) {
int i = 0;
while (src[i]) {
des[i] = src[i];
i++;
}
des[i] = 0;
return i;
}
TRIE *AddWord(char *s) {
int i = 0;
tempIndex = 0;
TRIE *cur = &root;
while (s[i]) {
int childIndex = s[i] - 'a';
if (cur->Child[childIndex] == 0) {
Trie[trieIndex].init();
cur->Child[childIndex] = &Trie[trieIndex];
trieIndex++;
}
cur = cur->Child[childIndex];
Temp[tempIndex] = cur;
tempIndex++;
i++;
}
return cur;
}
void UpdateRecommend(NODE *w) {
for (register int i = 0; i < tempIndex; i++) {
if (Temp[i]->Recommend == 0)
Temp[i]->Recommend = w;
else if (w->count >= Temp[i]->Recommend->count)
Temp[i]->Recommend = w;
}
}
void init() {
nodeIndex = trieIndex = 0;
root.init();
}
void inputWord(char mWord[20]) {
TRIE *t = AddWord(mWord);
if (t->Word == 0) {
NodePool[nodeIndex].band = false;
NodePool[nodeIndex].count = 1;
NodePool[nodeIndex].id = wordId;
mstrCPY(NodePool[nodeIndex].name, mWord);
t->Word = &NodePool[nodeIndex];
UpdateRecommend(&NodePool[nodeIndex]);
nodeIndex++;
}
else {
if (t->Word->band == false) {
t->Word->id = wordId;
t->Word->count++;
UpdateRecommend(t->Word);
}
}
wordId++;
}
int recommend(char mUser[20], char mAnswer[20]) {
int i = 0;
TRIE *cur = &root;
while (mUser[i]) {
int childIndex = mUser[i] - 'a';
if (cur->Child[childIndex] == 0) {
cur = 0;
break;
}
cur = cur->Child[childIndex];
i++;
}
if (cur == 0 || cur->Recommend == 0)
return mstrCPY(mAnswer, mUser);
return mstrCPY(mAnswer, cur->Recommend->name);
}
void banWord(char mWord[20]) {
TRIE *cur = AddWord(mWord);
if (cur->Word == 0) {
NodePool[nodeIndex].band = true;
cur->Word = &NodePool[nodeIndex];
nodeIndex++;
}
else {
cur->Word->band = true;
NODE *max = 0;
NODE *x = 0;
for (register int i = tempIndex - 1; i >= 0; i--) {
if (Temp[i]->Recommend == cur->Word) {
max = 0;
for (register int j = 0; j < 26; j++) {
if (Temp[i]->Child[j] && Temp[i]->Child[j]->Recommend) {
x = Temp[i]->Child[j]->Recommend;
if (max == 0)
max = x;
else if (x->count > max->count || (x->count == max->count && x->id > max->id))
max = x;
}
}
Temp[i]->Recommend = max;
}
else
return;
}
}
}