写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数

来源:互联网 发布:阳光网络伴我成长绘画 编辑:程序博客网 时间:2024/04/20 22:57
//==========================================================================
//程序功能:写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数
//程序实现思路:kmp算法,BM算法(不实现,但是会贴出基本思路)
//程序设计语言:c++
//
//===========================================================================


#include<iostream>


using namespace std ;




int find_firststr(const char* str,const char* first_str)
{
int res = -1 ;
//对输入的数据进行检查
int sLen = strlen(str) ;//查看strlen内部构造方式,方便这个地方进行差错检查
int fLen = strlen(first_str);
if( sLen==0 || fLen==0 || sLen<fLen )
{
cout<<" insert string error"<<endl;
return -1 ;
}


//进行查找
//kmp算法:定义一个辅助数组,记录比较字符串的真前缀(具体概念名词忘了)1 构造数组,
//2:查找,当发现不匹配时根据辅助数组跳转相应的位数(最大真前缀的位置)
int i = 0 ;
int j = -1 ;
int next[256] ;//其实next的大小只需要和模式串的大小一致就好了,但是这里无法获取常量的大小,所以只能定义一个最大值了


next[0] = -1 ;
while( j < fLen)//构造next数组
{//将next、模式串放在一起,没走动一个i,那么必须给next赋值,
if( j == -1 || first_str[i] == first_str[j] )//如果这两个值相等,那么next值等于前面一个next的值(此时任为j)加1
{
i++ ;
if( i >= fLen)
break ;
j++ ;
next[i] = j ;
}
else //如果这两个值不相等,那么就跳到前面最近的相等的地方,在重复比较这两个值,如果一直都不想等,那么就会置-1
{
j = next[j] ;
}
}


i = 0 ;
j = 0 ;


while(j < fLen  && i < sLen)
{
if(j==-1 || str[i] == first_str[j] )
{
i++ ;
j++ ;
}
else
{
j = next[j] ;
}
}


if(j<fLen) //表明此时没有匹配的字符串
return 0 ;


//BM算法(现在不实现了,以后有机会在弄):
//这是在kmp算法的基础上面改进的,它有两个辅助数组,坏字符辅助数组,好后缀辅助数组,这时候将模式串和源串第一个字符对齐,
//并从模式串的最后一个字符开始比较,如果直接发现不匹配,寻找坏字符辅助数组中跟坏字符相等的最右边的一个位置,并移动模式串
//如果模式串在当前位置已经匹配了一个子字符串,此时才出现不匹配现象,那么通过好后缀辅助数组进行移动模式串


return i - j + 1 ;

}


int main()
{


int res = 0 ;
//测试用例
char* str = "abcdefgfgfhabfsgegysufgdscdvdsfgfhuilads";
char* first_str1 = "gfhu";//唯一的子串
char* first_str2 = "fgfh";//有两个的子串
char* first_str3 = "duf" ;//没有子串


cout<<find_firststr(str,first_str1)<<endl;
cout<<find_firststr(str,first_str2)<<endl;
cout<<find_firststr(str,first_str3)<<endl;


system("pause");


return res ;
}
0 0
原创粉丝点击