DS\BF、BM、KMP算法
本帖最后由 ~风介~ 于 2014-5-23 16:37 编辑先贴代码,晚一点出详解~ ^_^
BF算法比较简单上一张图:
#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
typedef unsigned char SString;
int BF_Match(SString s,SString t)
{
int i=0,j=0;
int n=strlen(s),m=strlen(t);
while((i<n)&&(j<m))
{
if(s==t) /*匹配成功后,继续下一轮匹配,最后匹配成功后,i和j还要加一,然后跳出循环*/
{
i++;
j++;
}
else /*匹配失败,i回溯j置零,下一趟匹配*/
{
i = i-j+1;
j=0;
}
}
if(j==m)/*如果匹配成功的话,返回匹配成功的第一个位置*/
return (i-m);
else
return -1;
}
int main()
{
SString s,t;
int i;
printf("请输入主串s:");
scanf("%s",s);
printf("请输入模式串t:");
scanf("%s",t);
i = BF_Match(s,t);
if(i!= -1)
{
printf("模式串在主串中第一次出现的下标为:%d\n",i);
}
else
{
printf("主串中不存在模式串!\n");
}
return 0;
}BM算法
#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
typedef unsigned char SString;
int BM(SString S,SString T)
{
int lenS,lenT,i,j;
lenS=strlen(S);
lenT=strlen(T);
for(i=0;i<=lenS-lenT;i++)/*当主串的字符小于模式串t时停止*/
{
if(T==S&&T==S)/*比较第一个和最后一个字符*/
{
for(j=1;j<lenT-1;j++)/*比较*/
{
if(T!=S)
break;
}
if(j==lenT-1) return i+1;
}
}
return 0;
}
int main()
{
int i;
SString S,T;
printf("请输入主串S:");
scanf("%s",S);
printf("请输入模式串T:");
scanf("%s",T);
i=BM(S,T);
if(i==0)
printf("主串中不存在模式串!\n");
else
printf("模式串在主串中第一次出现的下标为%d\n",i);
return 0;
}KMP算法
#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
typedef unsigned char SString;
void get_next(SString T, int next[])
{
int lenT,i=1,j=0;
lenT=strlen(T);
next=0;
while(i<lenT)
{
if(j==0 || T==T)
{++i; ++j; next=j;}
else
j=next;
}
printf("模式串T的next函数值为:");
for(i=1;i<=lenT;i++)
printf("%d ",next);
printf("\n");
}
int KMP(SString S, SString T)
{
int next;
int lenS,lenT,i=1,j=1;
lenS=strlen(S);
lenT=strlen(T);
get_next(T,next);
while(i<=lenS && j<=lenT)
{
if(j==0 || S==T)
{++i; ++j;}
else
j=next;
}
if(j>lenT) return i-lenT;
else return 0;
}
int main()
{
SString S,T;
int i;
printf("请输入主串S:");
scanf("%s",S);
printf("请输入模式串T:");
scanf("%s",T);
i=KMP(S,T);
if(i==0)
printf("主串中不存在模式串!\n");
else
printf("模式串在主串中第一次出现的下标为%d\n",i);
return 0;
}
强烈支持楼主中。。。。
运行了BF算法程序,添加了一些注释和一小点修改:#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
//typedef unsigned char SString;//mingw中报错:不能把‘unsigned char*’
//转换为'const char*'所以修改如下:
typedef char SString ;
/*************************************
/* BF *
**************************************/
int BF_Match(SString MainStr,SString PattStr)
{
int i=0,j=0;
int iMainStrLen=strlen(MainStr),iPattStrLen=strlen(PattStr);//取得字符串长度
while((i<iMainStrLen)&&(j<iPattStrLen))
{
if(MainStr==PattStr) /*最后匹配成功后,i和j还要加一,然后跳出循环*/
{
i++;
j++;
}
else /*匹配失败,i回溯,下一趟匹配*/
{
i = i-j+1;
j=0;
}
}
if(j==iPattStrLen) /*匹配成功*/
return (i-iPattStrLen);
else
return -1;
}
//----------------main func------------------
int main()
{
SString MainStr,PattStr;
int i;
printf("请输入主串MainStr:");
//scanf("%s",MainStr);//不能读空格
gets(MainStr);
printf("请输入模式串PattStr:");
//scanf("%s",PattStr);
gets(PattStr);
i = BF_Match(MainStr,PattStr); //调用BF匹配算法
if(i!= -1) //匹配成功
{
printf("模式串在主串中第一次出现的下标为:%d\n",i);
}
else
{
printf("主串中不存在模式串!\n");
}
return 0;
}
强烈支持楼主。。。。
BM算法个人见解。。。。。修改了一下地方#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
///typedef unsigned char SString;///
typedef char SString;
int BM(SString MainStr,SString PattStr)
{
int iMainStrLen,iPattStrLen,i,j;
iMainStrLen=strlen(MainStr); //获取字符串长度
iPattStrLen=strlen(PattStr);
for(i=0;i<=iMainStrLen-iPattStrLen;i++)/*当主串的字符小于模式串t时停止*/
{
if(PattStr==MainStr&&PattStr==MainStr)/*比较第一个和最后一个字符*/
{
//下面无法处理模式字符串PattStr的长度为1,如果iPattStrLen=1了
// 则不进入for循环,但是现在j=1
//下面的if判断语句则不能return(此时已经匹配成功的,但不能返回)
//于是在for循环后面加一句 if(iPattStrLen==1) return i;
for(j=1;j<iPattStrLen-1;j++)/*比较*/
{
//if(T!=S)/////////这里应该是j+i
if(PattStr!=MainStr)
break;
}
if(iPattStrLen==1) return i;
if(j==iPattStrLen-1) return i; //匹配成功 指示在主字符串中的下标,这里应该返回i而不是i+1吧
}
}
return 0;
}
//-------------main func--------
int main()
{
int i;
SString MainStr,PattStr;
printf("请输入主串MainStr:");
//scanf("%s",S);
gets(MainStr); //可以读取空格
printf("请输入模式串PattStr:");
//scanf("%s",T);
gets(PattStr);
i=BM(MainStr,PattStr);
if(i==0)
printf("主串中不存在模式串!\n");
else
printf("模式串在主串中第一次出现的下标为%d\n",i);
return 0;
}
强烈支持楼主中。。。。
KMP这个。。。修改了一些地方,只是个人理解#include<stdio.h>
#include<string.h>
#define MAXSTRLEN 255
//typedef unsigned char SString;
typedef char SString;
//---------GetNext-------------------------
/* KMP最核心的便是如何确定next数组,即模板字符串PattStr与
/* 主字符串MainStr不匹配时 ,下次该从何处开始匹配
/*比如模板字符串PattStr=abchabcdaab
/*与主字符串匹配时当 PattStr='c'与主字符串MainStr不匹配,
/*例如主字符串MainStr= ... abchabf...(省略号代码还有其他字符,只没有写出来)
/*发现主字符串中不匹配的'f'前的'ab'和开头ab一样,所以此时只需要匹配一下PattStr与'f'是否匹配
/*而不用再从PattStr匹配。如何知道主字符串如何与PattStr字符串的第3个字符比较呢?这就引进了next
/*数组,来存储这个PattStr的下标值。 ---额,上面说得不好 :-(
/*
/*******************************************
/*求next数组,举一个例子(用上面的例子):
/* PattStr = abchabcdaab
/*则 next = -1,0,0,0,-1,0,0,3,-1,1,0
/* 这里要理解 PattStrandPattStr的next!=1和next!=2 以及 next=1
/*比如主字符串MainStr= ...abchabd...当 PattStr='c' 与主字符串相对应的'd'不匹配时
/*next=2还是等于0呢?如果等于2,则用 PattStr='c'继续与主字符串比较,但这明显重复运算了,所以此时next=0
*/
void GetNext(SString PattStr, int next[])
{
int iPattStrLen,i=0,j=-1;
iPattStrLen=strlen(PattStr);//获得模式字符串的长度
next=-1; //next初始化为-1,任何串的第一个字符的模式值规定为-1。
while(i < iPattStrLen-1)
{
if(j==-1 || PattStr==PattStr)
{
++i;
++j;
//下面4行修改了 即是实现了上面的next=0而不等于2的功能
if(PattStr != PattStr)
next=j;
else
next=next;
}
else
j=next;
}
printf("模式串PattStr的next函数值为:");
for(i=0;i<=iPattStrLen-1;i++)
printf("%d ",next);
printf("\n");
}
//-------------KMP----------
int KMP(SString MainStr, SString PattStr)
{
int next;
int iMainStrLen,iPattStrLen,i=0,j=0;
iMainStrLen=strlen(MainStr); //获得字符串长度
iPattStrLen=strlen(PattStr);
GetNext(PattStr,next); // 获得next数组
while(i < iMainStrLen && j < iPattStrLen)
{
if(j==-1 || MainStr==PattStr)
{
++i;
++j;
}
else
j=next;
}
if(j>=iPattStrLen) return i-iPattStrLen;//匹配成功
else return 0;
}
//------------main func--------------
int main()
{
SString MainStr,PattStr;
int i;
printf("请输入主串MainStr:");
//scanf("%s",S);
gets(MainStr); //可以获得空格字符
printf("请输入模式串PattStr:");
//scanf("%s",T);
gets(PattStr);
i=KMP(MainStr,PattStr);//调用KMP
if(i==0)
printf("主串中不存在模式串!\n");
else
printf("模式串在主串中第一次出现的下标为%d\n",i);
return 0;
}
学习一下~~ elvo 发表于 2014-5-23 12:58
强烈支持楼主。。。。
BM算法个人见解。。。。。修改了一下地方
对于单个字符就检测不到!\n 看毛片算法还是有点难呀,学习下。 支持下小甲鱼。 学习一下 支持支持 留着看看 我是来领鱼币的 cool 对照算法实际应用,理解更快。
页:
[1]