[템플릿] AC 오토마타

. (1) #INCLUDE <cstdio>
 2 #INCLUDE <CString을>
 . (3) #INCLUDE <알고리즘> 
 4. #INCLUDE <큐>
 5.  #DEFINE MAXN 5000000 + 10
 6.  은 USING  공간 STD]
 . 7   STR [MAXN * 2 ]
 . 8  구조체 노드 {
 . 9      INT 페일; // 불일치 포인터; 
10      INT CNT; // 단어의 출현 수, 
. 11      INT 다음 [ 62이다 ]; // 이 노드의 다음 (SON) 
(12)이다 } 트리는 [MAXN]; // 노드 구조 이들; 
13 INT K = 0 , ANS = 0 ;
 14 큐 < INT > Q; // 큐 :; 내장 불일치 포인터 
15  무효 build_trie ( INT의 ID,  *의 S) // 즉 ID가 여러 노드를 나타내는 모든 문자, 이러한 문자열 있음 * S 수단; 아래 0 번째 노드에서 스트링을 구축하기 시작 
16  {
 . 17      INT LEN = strlen 함수 (S); // 문자열의 길이 (문자열의 마지막 문자의 깊이에 상당) 
18      INT J = 0 ;
 . (19)      에 대해 ( int로 I = 0 ; I <렌 I ++가이 {)
 20 인          - J = S [I]가 ' ' ;
 21 인         IF (트리는는 [ID]가 [J] == 다음 내용 0 ) / * 이 경우, 다음에 깊이 문자가 현재 위치에 나타나지 않는다 * / 
22이다          {
 23이              트리는 [ID] 다음 내용 [J] = K ++; // 현재 노드의 위치 J 문자 노드, 즉, 문자 J의 노드 번호; 
24          }
 25          ID = 트리는 [ID] 다음 내용 [J]; // 다음 문자로 전달 된 어드레스 ID; 
26이다      }
 27      트리는 [ID]. ++ CNT; // ++ 단어의 수, 
28  }
 29  무효 build_fail ( INT의 ID)
 30  {
 31은      그동안 (! q.empty ()) q.pop는 (); // 보증 용 (큐 두려워는 없다 지우기) 
(32)      에 대한( 지능 I = 0 ; I는 < 26이고 , I는 ++) // 슈퍼 노드 내의 26 개 문자 이송, 
33는      {
 34          INT J = 다음 내용 [I] 트리는 [ID]
 35          IF (! J = 0 ) {
 36              Q .push (J)
 37              트리는 [J] ID .fail =; // 첫번째 계층 노드 일치 포인터 포인트 슈퍼 노드이고; 
38이다          }
 39      }
 40      그동안 (! q.empty ())
 (41)가      {
 42는          INT는 지금 q.front = (); q.pop (); // 현재 위치를 삭제 (큐의 헤드 소자) 
(43)는          에 대해 ( INT I =0 ; I는 < 26 것은 , I는 ++ )
 (44)가          {
 45              INT J = 트리는 [현재] 다음 내용 [I]
 46은              IF (J의 == 0 ) // 이 노드의 위치 아니며 불일치 포인터 포인트로 전송 노드에서이 편지 노드, 
47              {
 48                  트리는은 [지금] 다음 내용 [I]는 = 트리는 [그래서 답장 [지금] .fail]는 다음 내용 [내가]; // 0 경우, 점 슈퍼 노드에 영향을주지 않습니다; 
49                  계속 ] // 이 점은 반복 직접 이송 다음 노드로 완료; 
50              }
 51이고              ; 트리는 [J] = [현재 트리는 [] .fail] 트리는 다음 내용 [I]를 .fail // 이 경우, 현재 위치 문자 노드, 현재의 불일치 위치로 다음 노드 포인터가 불일치 포인터;
 52              //문자은 불일치에 대한 포인터의 현재 위치의 노드를 통과하지 않은 경우는 (0, 슈퍼 노드 점)에 영향을주지 않는다 
(53)는              (J) q.push; //이 배열로, 
54이다          }
 55      }
 56이다  }
 (57) 인  공극 solve_trie ( INT의 ID,  *의 S) // 조회 기능; 
58  {
 59      INT LEN = strlen 함수 (S), J = 0 ,
 60       ( INT I = 0 ; I 렌 <; I는 ++ )
 (61)가      {
 62          INT J = 트리는 [ID] 다음 내용 [S [I] - ' ' ]; // 다음 노드 위치의 현재 위치;
(63)이          그동안 (J && 트리는 [J] .CNT =! - 1. ) // 는 CNT 이송 동안이 노드가 존재하지 않는 경우, 
64          {
 65              + = 트리는 [J] .CNT ANS; // 검색된 않음 플러스 문자열에 포함되는 단어의 수 
66              트리는 [J] .CNT = - 1. ; // 태그 (대신 여러 번 등장의 패턴 문자열의 개수가 등장하기 때문에 참조) 
67              J = 트리는 [J]. 실패; // 포인터의 위치를 가리키는 직접 불일치 위치 (즉, 패턴의 문자열 패턴의 문자열의 일부를 삭제 앞이다) (즉, 일치하는 문자열 패턴 실패 찾을) (시간을 절약하기 위해) 
 68              // 일치에 실패한다 문자열의 앞 부분을 삭제, 사전 트리 패턴 문자열을 설립 
69          }
 70          ID = 트리는 [ID] 다음 내용 [S [I] - ' ' ]; // ID 승계, 다음 노드의 현재 위치; 0 문제가되지 않습니다
71이다      }
 72  }
 (73)는  지능 () 주
 74  {
 75      INT , N-
 76      는 scanf ( " %의 D " , 및 N-),
 77       ( INT I = . 1 , I는 <= N-; I는 ++ )
 78      {
 79          는 scanf ( " % S " , STR); // i 번째 짧은 스트링; 
80          build_trie ( 0 , STR) // 모든 문자열 즉 공통 조상 0 초 루트 노드 () (즉,)에서 내장 0 
81      } // 트라이 설립 완료; 
82     build_fail ( 0 ); // 불일치 포인터 구축, 
83      는 scanf ( " %의 S " , STR)를; // 입력 문자열 쿼리 요구; 
84      solve_trie ( 0 , STR); // 쿼리; 
85      의 printf ( " % D \ N- " , ANS); // 출력은 
86      반환  0 ,
 87  }
 88  // https://www.luogu.org/problemnew/solution/P3808 
89  // 도 함께 좋아진다

 

추천

출처www.cnblogs.com/xiaobuxie/p/11391875.html