BF 알고리즘 과 KMP 알고리즘
9298 단어 데이터 구조
int BF(const char *s,const char *sub, int pos)
// s sub, pos ,
{
assert(sub != NULL);
assert(s != NULL);
int lens = strlen(s);
int lensub = strlen(sub);
if (pos<0 || pos>lens)
{
return -1;
}
int i = pos;//i pos
int j = 0;//j 0
while (i < lens && j < lensub)
{
if (s[i] == sub[j])// ,
{
i++;
j++;
}
else// ,i ,j 0
{
i = i - j + 1;
j = 0;
}
}
if (j >= lensub)
{
return i - j;// j , [i-j]
}
else
{
return -1;
}
}
KMP 알고리즘: BF 알고리즘 과 달리 BF 알고리즘 에 비해 KMP 알고리즘 이 더욱 효율 적 입 니 다. 그 이 유 는 BF 알고리즘 의 시간 복잡 도 는 O (mn) M 이 메 인 문자열 의 길 이 를 대표 하고 n 은 하위 문자열 의 길 이 를 대표 하기 때 문 입 니 다.KMP 의 경우 시간 복잡 도가 O (m + n) 로 변 합 니 다.KMP 와 BF 가 유일 하 게 다른 곳 에 있 습 니 다. 메 인 문자열 의 i 는 되 돌아 가지 않 고 j 도 0 번 위치 로 이동 하지 않 습 니 다.그러나 여기 서 j 는 k 위치 로 되 돌아 가 야 하기 때문에 문자열 의 각 위치 에 대응 하 는 k 값 을 저장 하 는 next [] 배열 을 가 져 왔 습 니 다. 즉, next [j] = k 로 표시 합 니 다. 서로 다른 j 는 K 값 에 대응 합 니 다. 이 K 는 앞으로 이동 할 j 가 이동 할 위치 입 니 다.한편, K 의 값 은 이렇게 구 합 니 다. 1. 규칙: 성공 부분 과 일치 하 는 두 개의 똑 같은 진자 꼬치 (자체 포함 되 지 않 음) 를 찾 습 니 다. 하 나 는 아래 표 0 으로 시작 하고 다른 하 나 는 j - 1 로 끝 납 니 다.2. 어떤 데이터 든 next [0] = - 1;next[1] = 0;여기 서 우 리 는 아래 표 시 를 시작 하고, 말 한 몇 번 째 표 시 는 1 부터 시작한다.1. 이유: 메 인 문자열 이 – "defrdes" 하위 문자열 이: "abc" 였 을 때 처음부터 일치 하지 못 했 습 니 다.0 의 이유: 하위 문자열 이 1 번 아래 에 표시 되 어 있 을 때 0 입 니 다.next 배열 의 최적화, 즉 nextval 배열 을 어떻게 얻 는 지: 다음 과 같은 문자열 이 있 습 니 다. aaaaaaaab, 그의 next 배열 은 - 1, 0, 1, 2, 3, 4, 5, 6, 7 입 니 다. 수정 후의 배열 nextval 은 - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, 7 입 니 다.왜 수 정 된 수조 가 나 타 났 는 지, 5 번 에서 실패했다 고 가정 하면 한 걸음 물 러 설 까요, 아니면 a 입 니까, 아니면 똑 같 습 니까? 이어서 물 러 설 까요, 아니면 a 입 니까?예: 꼬치: a b c a b c a b c a b c a a b d a b next: - 1 0 0 1, 1, 2, 0, 1, 2, 3, 5, 6, 1 nextval: - 1, 0 - 1, 0, 2, 0 - 1, 0 흑체 a 의 nextval 구법: a 의 next 는 4 이 고 4 번 아래 에 표 시 된 값 도 a 이기 때문에 nextval 은 흑체 a 의 next 값 이 아니 라 4 번 아래 에 표 시 된 a 의 next 값, 즉 1 이다.
//next : 。
//
// 0 , j-1
void GetNext(int *next,const char *sub)// next
{
assert(sub != NULL);
int lensub = strlen(sub);
next[0] = -1;
next[1] = 0;
int i = 2;//
int k = 0;// k
while (i < lensub)// :abcababcabc-1 0 0 0 1 2 1 2 3 4 5 a next a k -1, b 0, 。。。
{
if ((k == -1) || sub[k] == sub[i - 1])// b k a b ,else
{
next[i] = k + 1;//** k , k+1, c k -1+1=0
i++;
k++;
}
else
{
k = next[k];//**next[0]=-1 k,k=-1 if()
}
}
}
int KMP(const char *s,const char *sub, int pos)
{
int lens = strlen(s);
int lensub = strlen(sub);
int *next = (int *)malloc(sizeof(int)*(lensub+1));// next[] , 1
assert(next != NULL);
GetNext(next,sub);// next , next
if (pos<0 || pos>lens)
{
return -1;
}
int i = pos;//i pos
int j = 0;//j 0
while (i < lens && j < lensub)
{
if ((j == -1) || s[i] == sub[j])
{
i++;
j++;
}
else
{
j = next[j];//i ,j next
}
}
free(next);
if (j >= lensub)
{
return i - j;// j , [i-j]
}
else
{
return -1;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.