这是ib同学的做法~~ 今天下午看了半天终于看懂,然后重写了一个,当然,重写的自然没有原版那么飘逸了。。
用一个链表记录各个pattern匹配的指针,因为字符串最长只有50,所以可以保证同时只有至多50个字符串在匹配状态,所以链表节点也只有50个
ib同学写了个自己的内存管理,我写的就比较惨了。。
貌似现在操作环形双向链比较顺手了~
这种云输入法面对高延迟网络很恶心。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <utility>
#include <memory.h>
using namespace std;
struct trie_node {
int count;
trie_node *childs[26];
};
struct matching_ptr {
trie_node *trie_root;
matching_ptr *next;
matching_ptr *previous;
};
trie_node trie_nodes[250000];
trie_node *trie_root(trie_nodes), *trie_node_ending(trie_nodes + 1);
matching_ptr matching_link_head;
int total_matched(0);
char very_big_buffer[1000001];
void
global_init(void)
{
memset(trie_nodes, 0, sizeof(trie_nodes));
trie_root = trie_nodes;
trie_node_ending = trie_nodes + 1;
matching_link_head.previous = matching_link_head.next = &matching_link_head;
matching_link_head.trie_root = 0;
total_matched = 0;
return;
}
void
create_matching_node(void)
{
matching_ptr *new_ptr;
new_ptr = new matching_ptr;
new_ptr->trie_root = trie_root;
new_ptr->next = &matching_link_head;
new_ptr->previous = matching_link_head.previous;
new_ptr->previous->next = new_ptr;
new_ptr->next->previous = new_ptr;
return;
}
void
free_matching_node(matching_ptr *ptr)
{
ptr->previous->next = ptr->next;
ptr->next->previous = ptr->previous;
delete ptr;
return;
}
void
add_string(char * str)
{
int c;
trie_node *p(trie_root);
--str;
while (*++str) {
if (!p->childs[c = *str - 'a']) {
p->childs[c] = trie_node_ending++;
}
p = p->childs[c];
}
++p->count;
return;
}
void
match_char(char c)
{
c -= 'a';
for (matching_ptr *current = matching_link_head.next; current != &matching_link_head; current = current->next) {
if (current->trie_root->childs[c]) {
current->trie_root = current->trie_root->childs[c];
total_matched += current->trie_root->count;
current->trie_root->count = 0;
} else {
matching_ptr *t;
t = current->previous;
free_matching_node(current);
current = t;
}
}
return;
}
int
main()
{
int nr_cases;
int nr_keywords;
char *current_matching;
freopen("test.txt", "r", stdin);
scanf("%d", &nr_cases);
while (nr_cases--) {
global_init();
scanf("%d", &nr_keywords);
while (nr_keywords--) {
scanf("%s", very_big_buffer);
add_string(very_big_buffer);
}
scanf("%s", very_big_buffer);
current_matching = very_big_buffer;
--current_matching;
while (*++current_matching) {
create_matching_node();
match_char(*current_matching);
}
printf("%d\n", total_matched);
}
return 0;
}