题目
有一个主串 S = {a,b,c,a,c,a,b,d,c},模式串 T = {a,b,d};请找到模式串在主串中第一次出现的位置;(提示:并不需要考虑字符串大小写的问题,字符均为小写字母)
BF算法思想
BF算法,即暴力(Brute Force)算法,其核心思想是:将主串和模式串逐个比较,如上图所示,从下标1开始,s[1] = a,T[1] = a,相同就接着往后比较,直到s[3] = c,T[3] = d,说明匹配不成功,需要对主串下标进行回退到下标2,子串回退到下标1,重新新一轮的比较,此时s[2] != T[1],匹配不成功,此时主串下标指向3,子串又回退到下标1,继续比较,直到完全匹配成功。
BF算法实现
#define OK 1
#define ERROR 0
#define MAXSIZE 40 /* 存储空间初始分配量 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef char String[MAXSIZE+1]; /* 0号单元存放串的长度 */
/* 生成一个其值等于chars的串T */
Status StrInit(String T,char *chars) {
if (strlen(chars) > MAXSIZE) {
return ERROR;
}
T[0] = strlen(chars);
for (int i = 1; i < T[0] + 1; i ++) {
T[i] = *(chars+i-1);
}
return OK;
}
/* 输出串T*/
void StrPrint(String T) {
for (int i = 1; i < T[0] + 1; i++) {
printf("%c",T[i]);
}
printf("\n");
}
/* BF算法 */
int Index_BF(String S, String T,int pos){
//i用于主串S中当前位置下标值,若pos不为1,则从pos位置开始匹配
int i = pos;
//j用于子串T中当前位置下标值
int j = 1;
//若i小于S的长度并且j小于T的长度时,循环继续
while (i <= S[0] && j <= T[0]) {
//比较的2个字母相等,则继续比较
if (S[i] == T[j]) {
i++;
j++;
}else
{
//不相等,则指针后退重新匹配
//i 退回到上次匹配的首位的下一位;
//加1,因为是子串的首位是1开始计算;
//再加1的元素,从上次匹配的首位的下一位;
i = i-j+2;
//j 退回到子串T的首位
j = 1;
}}
//如果j>T[0],说明T已经遍历结束,表示匹配成功
if (j > T[0]) {
//i母串遍历的位置 - 模式字符串长度 = index 位置
return i - T[0];
}else{
return -1;
}
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
String s;
StrInit(s, "abcacabdc");
String t;
StrInit(t, "abd");
int index = Index_BF(s, t, 1);
printf("index = %d\n",index);
}
return 0;
}
BF算法优缺点
优点:暴力,实用,代码简单,易理解
缺点:时间复杂度高,有很多无意义的遍历,例如主串为“0000000000”,子串为“000000001”