字符串的朴素匹配算法:
(BruteForce 暴力匹配算法)
从主串头开始,依次选取和模拟串等长的子串,挨个字符匹配,如果匹配失败,立马检索下一个子串。
假设主串长为n 模拟串长为m
朴素匹配算法匹配成功的最好的时间复杂度为O(m)
匹配失败的最好的时间复杂度为O(n-m+1)~O(n)
匹配成功的最坏的时间复杂度为O(n-m+1)*m~O(nm)
匹配失败的最坏的时间复杂度为O(n-m+1)*m~O(nm)
代码实现及结果测试:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
字符串的朴素匹配算法:
(BruteForce 暴力匹配算法)
从主串头开始,依次选取和模拟串等长的子串,挨个字符匹配,如果匹配失败,立马检索下一个子串。
假设主串长为n 模拟串长为m
朴素匹配算法匹配成功的最好的时间复杂度为O(m)
匹配失败的最好的时间复杂度为O(n-m+1)~O(n)
匹配成功的最坏的时间复杂度为O(n-m+1)*m~O(nm)
匹配失败的最坏的时间复杂度为O(n-m+1)*m~O(nm)
*/
// mother是主串 imitate是模拟串
int BruteForce(char mother[],char imitate[]){
int k=0; //用于指向当前所对比子串的起始位置
int i=k;
int j=0; //i,j分别指向子串和模式串的对应位置
while(i < strlen(mother) && j < strlen(imitate)){
if(mother[i] == imitate[j]){
i++;
j++;
}else{
k++; //放弃当前子串、转而对比下一个子串
i=k;
j=0;
}
}
//用j是否超出模拟串的边界,作为是否匹配成功的判断依据
if(j>=strlen(imitate)){
//模拟串在主串中首次出现的位置,位置得从1开始,不然也无法与下面的return 0 区分开。
return k+1;
}
return 0;
}
int main(int argc, char *argv[])
{
char mother[]="nihao,shijie";
char imitate[] = ",sh";
int index = BruteForce(mother,imitate);
printf("模拟串在主串中首次出现的位置是%d\n",index);
return 0;
}
别人的优雅暴力破解代码:
//暴力破解法(版本2),匹配返回下标,不匹配返回-1
int BruteForce2(char txt[],char pat[]){
int n = strlen(txt);
int m = strlen(pat);
for(int i=0;i<=n-m;i++){
int j;
for(j=0;j<m;j++){
if(pat[j]!=txt[i+j])break;
}
//pat全部匹配了
if(j==m) return i;
}
//txt中不存在pat子串
return -1;
}
此代码中 变量i既充当了k的角色,每次都指向要比较子串的起始位置,i+j又充当了子串遍历指针的角色。