본문 바로가기
Computer Science

Boyer-Moore Pattern Matching

by OKOK 2021. 4. 24.

뒤부터 매칭을 함

두 개의 suffice 중 더 쉬프트 많이 할 수 있는 것을 선택해서 이동 함.

Bad suffice 는 패턴의 마지막 자리수에서 부터 얼마만큼 그 캐릭터가 떨어져 있는지 파악하는 것.

Good suffice는 원하는 패턴이 만날 수 있도록. 

suff는 몇 칸 필었을 때 뒤에 패턴이 일치 하는가. 정해 둔 것.

맨 처음에 틀린 경우는 한 칸 을 밀면 되는 것임.

 

#include <stdio.h>
#include <string.h>

#define OUTPUT(x)    printf("%d\n", x )
#define MAX(a,b)  (((a)>(b))?(a):(b))
#define ASIZE  256
#define XSIZE  256

void preBmBc(char *x, int m, int bmBc[]) {
	int i;

	for (i = 0; i < ASIZE; ++i)
		bmBc[i] = m;
	for (i = 0; i < m - 1; ++i)
		bmBc[x[i]] = m - i - 1;
}


void suffixes(char *x, int m, int *suff) {
	int f, g, i;

	suff[m - 1] = m;
	g = m - 1;
	for (i = m - 2; i >= 0; --i) {
		if (i > g && suff[i + m - 1 - f] < i - g)
			suff[i] = suff[i + m - 1 - f];
		else {
			if (i < g)
				g = i;
			f = i;
			while (g >= 0 && x[g] == x[g + m - 1 - f])
				--g;
			suff[i] = f - g;
		}
	}
}

void preBmGs(char *x, int m, int bmGs[]) {
	int i, j, suff[XSIZE];

	suffixes(x, m, suff);

	for (i = 0; i < m; ++i)
		bmGs[i] = m;
	j = 0;
	for (i = m - 1; i >= 0; --i)
		if (suff[i] == i + 1)
			for (; j < m - 1 - i; ++j)
				if (bmGs[j] == m)
					bmGs[j] = m - 1 - i;
	for (i = 0; i <= m - 2; ++i)
		bmGs[m - 1 - suff[i]] = m - 1 - i;
}


void BM(char *x, int m, char *y, int n) {
	int i, j, bmGs[XSIZE], bmBc[ASIZE];

	/* Preprocessing */
	preBmGs(x, m, bmGs);
	preBmBc(x, m, bmBc);

	/* Searching */
	j = 0;
	while (j <= n - m) {
		for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i);
		if (i < 0) {
			OUTPUT(j);
			j += bmGs[0];
		}
		else
			j += MAX(bmGs[i], bmBc[y[i + j]] - m + 1 + i);
	}
}
int main()
{
	int i;
	char y[] = "how are you gagggagg world hello";
	char x[] = "gagggagg";

	BM( x, strlen(x), y, strlen(y));
	return 0;
}

'Computer Science' 카테고리의 다른 글

타입의 의존성 제거(container_of 버전)  (0) 2021.04.28
Generic swap  (0) 2021.04.24
Knuth-Morris-Pratt Pattern Matching (KMP)  (0) 2021.04.24
Morris-Pratt Pattern Matching  (0) 2021.04.24
Shift Or pattern mathcing  (0) 2021.04.24

댓글