子串查找类似string的find功能返回子串在主串的子串起始下标。
基本的从字符主串寻找符合子串的下标的算法是从下标为0开始比较主串和子串,相等就主串索引加一继续比较直到索引的等于子串,不等于的话就主串索引加一,继续比较。
下面是程序
int findSubStr_base(string str,string target)
{
int len_str=str.size();
int len_tar=target.size();
if(len_str<len_tar)
return -1;
for(int i=0;i<len_str-len_tar;i++)
{
int j=0;
while(j<len_tar&&str[i+j]==target[j])
j++;
if(j==len_tar)
return i;
}
return -1;
}
测试程序
int main()
{
string str1="asdfgsdjlgakjpabcd0eowinkf";
string str2="abcd";
cout<<findSubStr_base(str1,str2)<<endl;
string str3="asdfgsdjlgakjpaacd0eowinkf";
string str4="aacd";
cout<<findSubStr_base(str3,str4)<<endl;
return 0;
}
运行结果
hancart提出了改进的not-so-native算法
1,从下标1开始进行比较,最后比较下标0位置的字母;
2,分开子串前两个字符相等于不相等的两种情况,分别设计循环步长;
在不等的情况下,寻找str里面匹配target[1]的步长是1,主串循环步长为2,因为target[0]!=target[1],所以加一之后与target相等的主串索引(i)位置str[i]不可能等于target[0],就将步长设置为2;
在相等的情况下,因为target[0]和target[1]相等所以寻找str里面匹配target[1]的步长是2,同理可得主串循环步长为1;
程序如下
int findSubStr(string str,string target)
{
int sEqual=2,sDiff=1;
int len_str=str.size();
int len_tar=target.size();
if(len_str<len_tar)
return -1;
if(len_tar>=2)
{
if(target[0]==target[1])
{
sEqual=1;
sDiff=2;
}
}
int i=0;
while(len_str-i>=len_tar)
{
if(str[i+1]!=target[1])
i+=sDiff;
else
{
int j=1;
while(j<len_tar&&str[i+j]==target[j])
j++;
if(j==len_tar&&str[i]==target[0])
return i;
i+=sEqual;
}
}
return -1;
}
下面是测试程序
int main()
{
string str1="asdfgsdjlgakjpabcd0eowinkf";
string str2="abcd";
cout<<findSubStr(str1,str2)<<endl;
string str3="asdfgsdjlgakjpaacd0eowinkf";
string str4="aacd";
cout<<findSubStr(str3,str4)<<endl;
return 0;
}
运行结果
两种方法对比出来not-so-native所花的时间减少了很多。