引子:适合多个数据同时考虑
一
1.结构体模板
struct 名称1{
int 名称2;
string 名称3;
char 名称4;
........
}
2.如何排序(结构体很大的作用)
bool cmp(名称1 a,名称1 b)
{
if(........)
return a.名称(2~n)<b.名称(2~n);
if(........)
return a.名称(2~n)<b.名称(2~n);
}
以上是从小到大排列,从大到小则是将(<)改成(>),按所选的数据类型名称排列。(可以附加进行排列所需要的条件)
3.接下来是kmp算法。
先来说一下做题要注意的地方
<1>length(名称)和名称.size()用于返回字符串(string类型)的长度。
<2>strlen(名称)用于得到(char类型)的字符数组的长度。输入单个字符时 用 scanf("%c",&s)//设字符名称为s 输入字符数组时用 scanf("%s",s)//不加“&”符号。
<3>scanf("%s",s+1),其中输入字符数组是从是s[1]开始输入的,是s[0]为空。再来,strlen(s+1) 也是从是s[1]开始计算的,所以这两个要搭配使用哦。
4.kmp算法的原理。
<1>用两个指针i和j分别表示主串和模式串考虑到的位置,p数组表示两端重复的中点,像上图的模式串(不看最后的d)可以用p[5]=2来表示,5是串的长度。
但,如何得到任意的p[]值呢
void pre(char b[])
{
p[1]=0//单独一个字符是没有中点的
for(int i=1,j=0;i<m;i++)//m为b串的长度
{
while(j>0&&b[i+1]!=b[j+1])//下一个字符不相同
j=p[j]//不停地回到前缀相同的地方
if(b[i+1]==b[j+1])//下一个字符相同
j++;//往前进
p[i+1]=j;
}
}
这里i表示的是遍历到的地方j表示p[]的指针
--------------------------------------------------------------------------------------------------------------------------
<2>知道p数组那如何得到模式串在主串中出现的次数呢
inline int kmp(char a[],char b[])//a为主串,b为模式串
{
int ans=0;
for(int i=0,j=0;i<n;i++)//因为我们一直考虑的都是i+1,j+1,所以不用遍历到下标n
{
while(j>0&&b[j+1]!=a[i+1])
j++;
if(b[j+1]==a[i+1])
j++;
if(j==m)//模式串到结尾
ans++,j=p[j];//开始考虑找下一个串出现的地方
}
return ans;
}
注意:因为i和j都是从0开始的且我们不给a[0]和b[0]赋值。这就要用到---scanf("%s",a+1)---后面加上1,这样就从a[1]开始输入了。求它的长度就用strlen(a+1);
--------------------------------------------------------------------------------------------------