woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

AC自动机 字符串搜索

 

http://blog.csdn.net/soberman/archive/2009/03/10/3978071.aspx

 

view plaincopy to clipboardprint?

1. /*

2. 程序说明:多模式串匹配的AC自动机算法

3. 此题通过hdu 2222

4. 自动机算法可以参考《柔性字符串匹配》里的相应章节,讲的很清楚

5. */

6. #include <stdio.h>

7. #include <string.h>

8.

9.

10. const int MAXQ = 500000+10;   

11. const int MAXN = 1000000+10;   

12. const int MAXK = 26;  //自动机里字符集的大小

13. struct  TrieNode   

14. {   

15.     TrieNode* fail;   

16.     TrieNode* next[MAXK];   

17. bool danger;   //该节点是否为某模式串的终结点

18. int  cnt;    //以该节点为终结点的模式串个数

19.     TrieNode()   

20.     {   

21.         fail = NULL;   

22.         memset(next, NULL, sizeof(next));   

23.         danger = false;   

24.         cnt = 0;   

25.     }   

26. }*que[MAXQ], *root;   

27. //文本字符串

28. char  msg[MAXN];   

29. int   N;   

30. void  TrieInsert(char *s)   

31. {   

32. int  i = 0;   

33.     TrieNode *ptr = root;   

34. while(s[i])   

35.     {   

36. int  idx = s[i]-'a';   

37. if(ptr->next[idx] == NULL)   

38.             ptr->next[idx] = new TrieNode();   

39.         ptr = ptr->next[idx];   

40.         i++;   

41.     }   

42.     ptr->danger = true;   

43.     ptr->cnt++;   

44. }   

45.

46. void  Init()   

47. {   

48. int  i;   

49. char  s[100];   

50.     root = new TrieNode();   

51.     scanf("%d", &N);   

52. for(i = 0; i < N; i++)   

53.     {   

54.         scanf("%s", s);   

55.         TrieInsert(s);   

56.     }   

57. }   

58.

59. void  Build_AC_Automation()   

60. {   

61. int  rear = 1, front = 0, i;   

62.     que[0] = root;   

63.     root->fail = NULL;   

64. while(rear != front)   

65.     {   

66.         TrieNode *cur = que[front++];   

67. for(i = 0; i < 26; i++)   

68. if(cur->next[i] != NULL)   

69.             {   

70. if(cur == root)   

71.                     cur->next[i]->fail = root;   

72. else

73.                 {   

74.                     TrieNode *ptr = cur->fail;   

75. while(ptr != NULL)   

76.                     {   

77. if(ptr->next[i] != NULL)   

78.                         {   

79.                             cur->next[i]->fail = ptr->next[i];   

80. if(ptr->next[i]->danger == true)   

81.                                 cur->next[i]->danger = true;   

82. break;   

83.                         }   

84.                         ptr = ptr->fail;   

85.                     }   

86. if(ptr == NULL) cur->next[i]->fail = root;   

87.                 }   

88.                 que[rear++] = cur->next[i];   

89.             }   

90.     }   

91. }   

92.

93. int  AC_Search()   

94. {   

95. int  i = 0, ans = 0;   

96.     TrieNode *ptr = root;   

97. while(msg[i])   

98.     {   

99. int  idx = msg[i]-'a';   

100. while(ptr->next[idx] == NULL && ptr != root) ptr = ptr->fail;   

101.         ptr = ptr->next[idx];   

102. if(ptr == NULL) ptr = root;   

103.         TrieNode *tmp = ptr;   

104. while(tmp != NULL && tmp->cnt != -1)   

105.         {   

106.             ans += tmp->cnt;   

107.             tmp->cnt = -1;   

108.             tmp = tmp->fail;   

109.         }   

110.         i++;   

111.     }   

112. return  ans;   

113. }   

114.

115. int  main()   

116. {   

117. int  T;   

118.     scanf("%d", &T);   

119. while(T--)   

120.     {   

121.         Init();   

122.         Build_AC_Automation();   

123. //文本

124.         scanf("%s", msg);   

125.         printf("%d\n", AC_Search());   

126.     }   

127. return 0;   

128. } 

posted on 2009-09-25 20:52 肥仔 阅读(337) 评论(0)  编辑 收藏 引用 所属分类: 状态机 & 自动机 & 形式语言


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理