查找---BF算法(1)
在对于字符串或者可以说是对于串的查找上,有两种比较常用的匹配算法。第一种为BF算法,第二种为KMP算法。由于KMP算法较为复杂,今天就先来说说BF算法,下次花一整次讲讲KMP。
第一次听说BF算法,是被人称作’男朋友算法’。。。。。。BF算法,即Brute Force算法,为一种暴力算法,至于其他想了解的可以自行百度。
算法思想
从上文中所说的暴力算法我们就可以了解到BF算法是将所有目标字符串中的子串与需查找的字符串进行比较,成功则返回该子串在目标字符串中的位置,失败则继续比较直至成功或所有子串全部比较,如果都失败,则返回一个成功是不可能出现的值。
在实现时有一个难点:如何获得全部子串。其实事实是并不用获取全部子串,只需要遍历整个目标字符串,分别让以目标字符串中的每个字符为开始位置的子串与需查找字符串对比,一旦对比失败,立即放弃所有以此字符开头的字符串,重新在目标字符串中以下一字符为开始的所有子串中查找需查找字符串。如果对比需查找字符串成功,直接返回该字符位置在目标字符串中的位置。在这里对比失败后需要定位目标字符串中下一字符的位置,这里使用双层循环跳出第二次循环的方法,也可以只用一层循环,使用当前目标字符串位置减去需查找字符串位置再加1。
(图片来自网络)
如图所示,目标字符串为caatcat,需查找字符串为cat。先对比以目标字符串第一个字符c为开始位置的子串,对比失败,再对比以目标字符串第二个字符a为开始位置的子串,以此类推,直到对比以目标字符串第五个字符c为开始位置的子串,对比成功,返回c的在目标字符串中的位置5。
代码实现
注意:算法描述中的字符串的初始位置为1,算法实现时字符串的初始位置为0.
int BF(const char *str, const char *sub, int pos)//str: 目标字符串 sub: 需查找字符串 pos: 开始查找位置
{
assert(str != NULL && sub != NULL);//判断参数是否正确
if (str == NULL || sub == NULL)
{
return -1;
}
if (pos < 0)
{
return -1;
}
int i = pos;
int j = 0;
while (str[i] != '\0' && sub[j] != '\0')//遍历整个目标字符串
{
if (str[i] == sub[j])//进行对比, 对比成功
{
i++;
j++;
}
else//对比失败
{
i = i - j + 1;//将对比的子串开始位置变为下一个字符
j = 0;//回到需查找字符串开始位置
}
}
if (sub[j] != '\0')//查找失败
{
return -1;
}
else//查找成功
{
return i - j;
}
}
我在这里定位目标字符串中下一字符的位置是使用当前目标字符串位置减去需查找字符串位置再加1。