1. 보이어-무어법 살펴보기
- 패턴의 마지막 문자부터 앞쪽으로 검사를 진행하면서 일치하지 않는 문자가 있으면 미리 준비한 표에 따라 패턴을 옮길 크기를 결정
- Good Suffix method
: 접미사와 같은 문자열이 패턴 문자열 내에 존재하는지 검사
-Bad Character method
: 본문의 문자열과 패턴이 불일치하는 문자 (나쁜 문자)를 발견하면 패턴의 나쁜 문자와 텍스트의 나쁜 문자를 일치 시킴
ex) 텍스트 "ABCXDEZCABACABAC"에서 패턴 "ABAC"를 검색하는 경우
- 1) 텍스트와 패턴의 첫 번째 문자를 위, 아래로 겹치고 패턴의 마지막 문자 'C'를 검사
- 텍스트의 'X'는 패턴에 없음
- 텍스트 안에서 패턴에 들어 있지 않은 문자를 찾으면 해당 위치까지의 문자는 건너 뛸 수 있음
- 2)~4)의 비교는 생략하고 패턴을 4칸 뒤로 옮김
- 패턴의 마지막 문자 'C'와 텍스트의 'C'가 일치하기 때문에 패턴의 1칸 앞의 문자 'A'로 옮길 수 있음
- 'Z'는 패턴에 없는 문자이므로 3칸 이동
- 2)와 같이 패턴의 뒤쪽에 위치한 'A'가 텍스트와 위, 아래로 겹치도록 패턴을 1칸 옮김
- 4)와 같은 방법으로 3칸 이동 하면 안됨
- 2)에서 패턴과 텍스트의 모든 문자가 일치하므로 검색 성공!
- 각각의 문자를 만났을 때 패턴을 옮길 크기를 저장할 표(건너뛰기표)
- 패턴 문자열의 길이 n
1) 패턴에 들어 있지 않은 문자를 만난 경우
- 패턴을 옮길 크기는 n
2) 패턴에 들어 있는 문자를 만난 경우
- 마지막에 나오는 위치의 인덱스가 k이면 패턴을 옮길 크기는 n-k-1
- 같은 문자가 패턴안에 중복해서 들어 있지 않다면 패턴을 옮길 크기는 n
- 보이어 -무어법으로 문자열을 검색하는 프로그램
//보이어-무어법으로 문자열을 검색하는 프로그램
#include <stdio.h>
#include <string.h>
#include <limits.h>
//보이어-무어법으로 문자열을 검색하는 함수
int bm_match(const char txt[], const char pat[])
{
int pt; //txt 커서
int pp; //pat 커서
int txt_len = strlen(txt); //txt 문자 개수
int pat_len = strlen(pat); //pat 문자 개수
int skip[UCHAR_MAX+1]; //건너뛰기 표
//건너뛰기 표 만들기
for(pt = 0; pt <= UCHAR_MAX; pt++)
skip[pt] = pat_len;
for(pt = 0; pt < pat_len -1; pt++)
skip[pat[pt]] = pat_len - pt -1;
while(pt < txt_len) {
pp = pat_len -1; //pat의 마지막 문자부터 검사
while(txt[pt] == pat[pp]) {
if(pp == 0)
return pt;
pp--;
pt--;
}
pt += (skip[txt[pt]] >pat_len - pp) ? skip[txt[pt]] : pat_len - pp;
}
return -1;
}
int main()
{
char s1[256]; //텍스트
char s2[256]; //패턴
puts("보이어-무어법 ");
printf("텍스트:");
scanf("%s",s1);
printf("패턴:");
scanf("%s",s2);
int idx = bm_match(s1,s2); //문자열 s1에서 문자열 s2를 보이어-무어법을 사용해 검색
if(idx == -1)
puts("텍스트에 패턴이 없습니다.");
else
printf("%d번째 문자부터 match합니다.\n",idx+1);
return 0;
}
2. strstr 함수 알아보기
strstr 함수
- 문자열 검색
- char *strstr(const char *s1, const char *s2);
- s1이 가리키는 문자열에서 s2가 가리키는 문자열과 일치하는 (널문자를 포함하지 않는) 문자열을 찾음
가장 앞쪽에 나오는 문자열을 찾음
- strstr 함수를 사용한 프로그램
//strstr함수를 사용한 프로그램
#include <stdio.h>
#include <string.h>
int main()
{
char s1[256], s2[256];
puts("strstr함수");
printf("텍스트 :");
scanf("%s",&s1);
printf("패턴:");
scanf("%s",&s2);
char *p = strstr(s1,s2); //문자열 s1에서 문자열 s2를 검색
if(p == NULL)
printf("텍스트에 패턴이 없습니다.\n");
else {
int ofs = p -s1;
printf("\n%s\n",s1);
printf("%*s|\n",ofs,"");
printf("%*s%s\n",ofs,"",s2);
}
return 0;
}
'C언어 > 자료구조' 카테고리의 다른 글
8-2장 포인터를 이용한 연결 리스트(1) (0) | 2023.08.02 |
---|---|
8-1장 선형 리스트 (0) | 2023.08.02 |
7 -3장 KMP법 (0) | 2023.08.02 |
7-2장 브루트 - 포스법 (0) | 2023.08.01 |
7-1장 문자열의 기본 (0) | 2023.08.01 |