일요일 문자열 매칭 알고리즘 (C ++ 구현)

요약 :

일요일 알고리즘은 다니엘 M.Sunday 1990 매칭 알고리즘에 의해 제안 된 문자열 모델입니다. 핵심 아이디어가있다 : 일치하는 과정에서, 패턴 문자열이 왼쪽 또는 왼쪽이나 오른쪽이 발견 일치하지 않는 비교 오른쪽을 눌러해야 할 필요가 없습니다, 알고리즘에 많은 문자를 건너 뛸 수 있습니다 향상된 매칭 효율이 일치의 다음 단계.

아이디어 :

다음 문자를 일치하도록 실패에 관심을 백업하는 전면으로 일요일 KMP 알고리즘과 매칭 알고리즘은 문자열의 마지막 비트가 주요 경기에 참여하는 것입니다.
하나의 문자열이 스킵 모드로 표시되지 않는 경우, 즉, 모드 전환 비트 번호 문자열 + = 1,
2, 그렇지 않으면, 비트의 움직임 패턴 문자열 길이 = 번호 - 문자의 우측 위치 (0로 시작) = 문자열 패턴의 위치는, 거리의 끝에서 1 + 가장 오른쪽에 나타난다.

코드 :

사용법 #include <iostream> 
사용법 #include < 문자열 > 
사용법 #include <cstdio> 
사용법 #include <sstream> 
사용법 #include <벡터> 은 Using 네임 스페이스 STD; INT 주 () { 문자열 소스 = " 여보세요 세계, 안녕하세요 중국, 베이징 안녕하세요 " ;
     문자열 부 = " 베이징 " ; INT의 인덱스 = 0 ; // 기본적으로 모든 경기의 위치를 기록하는 데 사용 INT의 I = 0 ; // 위치 시작 때마다 새로운주기를 INT J, 다음을; //

 


    
    
    
    
    
    j는 위치를 시작한 다음 레코드를 문자열의 기록 위치를 탐색하는 데 사용되는 
    그동안을 (I는 < source.length ()) 
    { 
        COUT << " 시작 인덱스 : " << I << " , 문자 : " << 원본 [I] << ENDL는, 
        다음 = 난 + part.length을 (), 
        인덱스 = 난; 
        J는 = 0 ;
         IF는 (! 부품 [J] = 소스 [색인]) 
        { 
            // 다음 위치 나 계산 
            IF를 ( 다음 < source.length ()) 
            { 
                INT의 컷 = 0 ;
                 ( INT Z = 0 ; Z <part.length (); Z ++ ) 
                { 
                    경우 (소스 [다음] == 부 [Z]) 
                    {  = Z; 
                    } 
                } 
                경우 (컷 == 0 [다음] = && 소스 부 [! 0 ]) 
                { 
                    다음 ++ ; 
                } 
                다른 
                { 
                    다음 - = 절단; 
                } 
            } 
            I =다음 것;
            계속 ; 
        } 
        다른 
        { 
            동안 (j < part.length ()) 
            { 
                경우 (부 [J]! = 소스 [인덱스]) 
                { 
                    // 重新计算난的下一个位置
                    경우 (다음 < source.length ()) 
                    { 
                        INT의 컷 = 0 ;
                         ( INT Z = 0 ; Z <part.length (); Z ++ ) 
                        { 
                            경우 (소스 [다음] == 부 [Z]) 
                            { Z; = 
                            } 
                        } 
                        경우 (컷 == 0 && 소스 [다음] = 부분 [! 0 ]) 
                        { 
                            다음 ++ ; 
                        } 
                        다른 
                        { 
                            다음 - = 절단; 
                        } 
                    } 
                    I = 다음;
                    휴식 ; 
                } 
                인덱스 ++ ; 
                J ++ ; 
            }
            만약 (j == part.length는 ()) 
            { 
                중단 ; 
            } 
        } 
    } 
    경우 (j는 == part.length ()) 
    { 
        COUT은 << " 예, 시작 인덱스가 " << 인덱스 J << ENDL; 
    } 
    다른 
    { 
        COUT << " 일치 " << ENDL; 
    } 
    
    
    반환  0 ; 
}

 

결과 :

, 시작 인덱스 : 0 , 문자 : H는 
시작 인덱스 : 8 , , R 
인덱스 시작 : 16 , 문자 : O 
시작 인덱스 : 24 , 문자 : H는 
시작 인덱스 : 30 , : B 
네 인덱스 시작  (30)

 

분석 :

관통 처음 시작 H :

H 여보세요 세계 헬로 중국 베이징 안녕하세요
 ^ 
B의 eijing의 

H ! = B

H 여보세요 W O RLD 안녕하세요 중국 베이징 안녕하세요 
^ 다음 ^ 여기서 
B의 eijing의 

다음 위치로부터 일이 없기 때문에, 즉 # 번째 라운드 (R)를 통과하는 내부 다음 문자열을 발생
H 여보세요 W O R & LT LD 안녕하세요 중국 베이징 안녕하세요 
^^ 위치로 이송 B의 eijing
 

두 번째 패스는 연구 시작 :

헬로 WO R의 LD, 헬 L O 중국 베이징 안녕하세요
         ^^ 다음  eijing의 

R ! = B

셋째 패스, O를 시작합니다

안녕하세요 세계, 지옥  중국 , 시간 여보세요 베이징
                 ^ ^ 다음 
                B의 eijing의

 오! = B

넷째 통과, h를 시작합니다

세계 안녕하세요, 안녕하세요 중국, H 여보세요 B의 E의 ijing
                         ^ ^ 다음
                         B의 eijing의

 H는! = B 

다음 E 다음 시간을 이동해야하므로이 부분을 "eijing", 찾을 수있는 "베이징"을 부분 문자열 전자에,이 시간 길이

다섯 번째 통과, B 시작 :

안녕하세요 안녕하세요 중국 헬로  EIJING
                               ^ 
                              B의 EIJING

 ㄴ == B의 
전자 E ==
J J ==
I == I
N N ==
g g ==

끝이 일치 할 수 있도록

 

알고리즘의 시간 복잡도 : O (㎚)

알고리즘 일요일의 관점에서 쉽고 빠르게 KMP 알고리즘보다 더 큰 비율을 상쇄하기 때문에

 

추천

출처www.cnblogs.com/lyc94620/p/11420092.html