题面
编写一个程序,在环形字符串s中找到模式字符串p。
输入
在第一行中,给出字符串s。
在第二行中,给出字符串p。
输出
如果p在s中,则在一行中打印“是”,否则打印“否”。
数据范围
- 1 ≤ p的长度 ≤ s的长度 ≤ 100
- s和p由小写字母组成
- 示例输入1
-
vanceknowledgetoad advance
示例输出1
Yes
示例输入2
vanceknowledgetoad advanced
示例输出2
No
先上代码
#include<stdio.h>
int main()
{
char s[201] = {'\0'};
char p[101] = {'\0'};
gets(s);//读入字符串
gets(p);
int i = 0, j = 0;
int a = strlen(s);//计算长度
int b = strlen(p);
strncat(s, s, a);//连接字符串,将s中字符串复制自身增长了一倍
while (i < a*2 && j < b)//BF算法
{
if (s[i] == p[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j == b)//跳出循环有两种可能,i=a*2,说明已经遍历完主串,匹配失败;
//j=b,说明子串遍历完成,在主串中成功匹配
printf("Yes\n");
else
printf("No\n");
return 0;
}
在这道题中,有两个点需要注意,题中虽然给出1 ≤ p的长度 ≤ s的长度 ≤ 100,但别忘了‘\0’,所以p的长度最低是101,而s因为把自身复制了一次,最低长度为201。当然,你要是嫌麻烦,直接写成300或者以上就不用考虑了。
因为这题是环形字符串普通字符串,不用复制,a不用*2:
#include<stdio.h>
int main()
{
char s[101] = {'\0'};
char p[101] = {'\0'};
gets(s);//读入字符串
gets(p);
int i = 0, j = 0;
int a = strlen(s);//计算长度
int b = strlen(p);
while (i < a && j < b)//BF算法
{
if (s[i] == p[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j == b)//跳出循环有两种可能,i=a*2,说明已经遍历完主串,匹配失败;
//j=b,说明子串遍历完成,在主串中成功匹配
printf("Yes\n");
else
printf("No\n");
return 0;
}
普通模式匹配(BF)算法又称暴力算法,实现过程没有任何技巧,就是简单粗暴地拿一个串同另一个串中的字符一一比对,得到最终结果。
BF 算法的实现过程很 "无脑",不包含任何技巧,在对数据量大的串进行模式匹配时,算法的效率很低。