设计BF算法,完成如下功能: 1)建立目标串s=“abcabcabdabba”和模式串t=“abcabd”。 2)采用BF算法求t在s中的位置。用数据结构c语言写
时间: 2024-10-19 10:11:09 浏览: 38
设计Bollman-Franklin (BF) 算法(也称为Boyer-Moore 搜索算法),用于在一个字符串`s`中查找给定的模式串`t`,你可以按照以下步骤进行:
1. 初始化:
- 定义两个指针:i 和 j,分别表示字符串`s`和`t`的当前字符位置。
- 创建两个长度与模式串`t`相同的布尔数组`badchar[]`,用于存储模式串中每个字符最后出现的位置,如果某字符未出现,则设为-1。
2. 设置坏字符规则(Bad Character Rule):
- 遍历模式串`t`,对于每个字符`t[j]`,将`badchar[t[j]] = j`,表示`t[j]`最后一次出现在模式串中的位置。
3. 设置好后缀规则(Good Suffix Rule):
- 对于模式串`t`的所有后缀,计算它们最长的公共前后缀长度。例如,对于后缀`t[j:]`,找到最长的后缀`l`使得`s[i-l..i-1] == t[j-l..j-1]`,并将这个值存储到一个数组`longest_prefix[]`中。
4. 主循环:
- 当`j < strlen(t)`时,进行以下操作:
a. 如果`s[i] == t[j]`,则同时向右移动i和j,即`i++, j++`。
b. 否则,比较`i`和`badchar[t[j]] + j`(若存在),取两者较大的那个值作为新的`i`值,并保持`j`不变。
- 如果`i > badchar[t[j]] + j`,说明`t[j]`在`s`中已经不存在了,从`t[j+1]`开始尝试匹配。
5. 查找结束:
- 如果`j == strlen(t)`,那么`i-j`就是模式串`t`在字符串`s`中的起始位置;如果`j >= strlen(t)`,则模式串不在`s`中。
以下是用 C 语言实现的简化版代码片段:
```c
#include <stdio.h>
#include <string.h>
// 辅助函数,用于获取最长公共前后缀长度
int get_longest_prefix(int* longest_prefix, char s[], int i, char t[], int j);
int main() {
char s[] = "abcabcabdabba";
char t[] = "abcabd";
int n = strlen(s);
int m = strlen(t);
// 初始化坏字符数组和最长前缀数组
int badchar[m];
memset(badchar, -1, sizeof(badchar));
int longest_prefix[m];
// 计算坏字符规则
for (int j = 0; j < m; j++) {
badchar[t[j]] = j;
}
// 获取最长前缀
for (int j = 0; j < m; j++) {
longest_prefix[j] = get_longest_prefix(longest_prefix, s, n - 1, t, m - 1 - j);
}
// 开始搜索
int i = n - 1, j = m - 1;
while (i >= 0 && j >= 0) {
if (s[i] == t[j]) {
i--;
j--;
} else if (i < badchar[t[j]]) {
break; // 如果在坏字符之后,直接跳过
} else {
i -= longest_prefix[j]; // 使用好后缀规则
}
}
if (j < 0) {
printf("Pattern found at position: %d\n", i + 1); // 返回模式串的位置
} else {
printf("Pattern not found in the string.\n");
}
return 0;
}
// 辅助函数,获取最长公共前后缀长度
int get_longest_prefix(int* longest_prefix, char s[], int si, char t[], int tj) {
int l = 0;
while (si >= 0 && tj >= 0 && s[si] == t[tj]) {
si--;
tj--;
l++;
}
return l;
}
```
阅读全文