보이어 무어 알고리즘의 또 다른 접근 방식입니다. 때로는 Good Suffix 휴리스틱 방법이라고 합니다. 이 경우 전처리 테이블이 접미사 테이블로 생성됩니다. 이 절차에서는 패턴의 마지막 문자에서 부분 문자열 또는 패턴을 검색합니다. 주 문자열의 하위 문자열이 패턴의 하위 문자열과 일치하면 일치하는 하위 문자열의 다른 항목을 찾기 위해 이동합니다. 메인 문자열의 접미사인 패턴의 접두사를 찾기 위해 이동할 수도 있습니다. 그렇지 않으면 패턴의 전체 길이를 이동합니다.
입력 및 출력
Input: Main String: “ABAAABCDBBABCDDEBCABC”, Pattern: “ABC” Output: Pattern found at position: 4 Pattern found at position: 10 Pattern found at position: 18
알고리즘
fullSuffixMatch(shiftArray, borderArray, 패턴)
입력 - 검색할 이동 위치, 테두리 배열 및 패턴을 저장할 배열입니다.
출력 - shift 배열과 border 배열을 채웁니다.
Begin n := pattern length j := n j := n+1 borderArray[i] := j while i > 0, do while j <= n AND pattern[i-1] ≠ pattern[j-1], do if shiftArray[j] = 0, then shiftArray[j] := j-i; j := borderArray[j]; done decrease i and j by 1 borderArray[i] := j done End
partialSuffixMatch(shiftArray, borderArray, 패턴)
입력- 검색할 이동 위치, 테두리 배열 및 패턴을 저장할 배열입니다.
출력 - shift 배열과 border 배열을 채웁니다.
Begin n := pattern length j := borderArray[0] for index of all characters ‘i’ of pattern, do if shiftArray[i] = 0, then shiftArray[i] := j if i = j then j := borderArray[j] done End
searchPattern(텍스트, 패턴)
입력: 검색할 본문 및 패턴
출력 - 패턴이 발견된 인덱스
Begin patLen := pattern length strLen := text size for all entries of shiftArray, do set all entries to 0 done call fullSuffixMatch(shiftArray, borderArray, pattern) call partialSuffixMatch(shiftArray, borderArray, pattern) shift := 0 while shift <= (strLen - patLen), do j := patLen -1 while j >= 0 and pattern[j] = text[shift + j], do decrease j by 1 done if j < 0, then print the shift as, there is a match shift := shift + shiftArray[0] else shift := shift + shiftArray[j+1] done End
예
#include<iostream> using namespace std; void fullSuffixMatch(int shiftArr[], int borderArr[], string pattern) { int n = pattern.size(); //find length of pattern int i = n; int j = n+1; borderArr[i] = j; while(i > 0) { //search right when (i-1)th and (j-1)th item are not same while(j <= n && pattern[i-1] != pattern[j-1] ) { if(shiftArr[j] == 0) shiftArr[j] = j-i; //shift pattern from i to j j = borderArr[j]; //update border } i--; j--; borderArr[i] = j; } } void partialSuffixMatch(int shiftArr[], int borderArr[], string pattern) { int n = pattern.size(); //find length of pattern int j; j = borderArr[0]; for(int i = 0; i<n; i++) { if(shiftArr[i] == 0) shiftArr[i] = j; //when shift is 0, set shift to border value if(i == j) j = borderArr[j]; //update border value } } void searchPattern(string mainString, string pattern, int array[], int *index) { int patLen = pattern.size(); int strLen = mainString.size(); int borderArray[patLen+1]; int shiftArray[patLen + 1]; for(int i = 0; i<=patLen; i++) { shiftArray[i] = 0; //set all shift array to 0 } fullSuffixMatch(shiftArray, borderArray, pattern); partialSuffixMatch(shiftArray, borderArray, pattern); int shift = 0; while(shift <= (strLen - patLen)) { int j = patLen - 1; while(j >= 0 && pattern[j] == mainString[shift+j]) { j--; //reduce j when pattern and main string character is matching } if(j < 0) { (*index)++; array[(*index)] = shift; shift += shiftArray[0]; }else { shift += shiftArray[j+1]; } } } int main() { string mainString = "ABAAABCDBBABCDDEBCABC"; string pattern = "ABC"; int locArray[mainString.size()]; int index = -1; searchPattern(mainString, pattern, locArray, &index); for(int i = 0; i <= index; i++) { cout << "Pattern found at position: " << locArray[i]<<endl; } }
출력
Pattern found at position: 4 Pattern found at position: 10 Pattern found at position: 18