【题目链接】
【题目考点】
1. 字符串
2. string类
string s, s1;
s.find(s1)
:查找s1在s中第一次出现的位置(从左至右查找),如不存在,返回string::npos
。s.rfind(s1)
:查找s1在s最后一次出现的位置(从右至左查找),如不存在,返回string::npos
。s.substr(pos, len)
: 从下标pos起截取长度为len 的字符串
【解题思路】
解法1:使用字符数组
先读入整个字符串,遍历字符串,通过逗号将整个字符串拆分为s, s1, s2三个字符串。
读到第一个逗号时,将该数组元素改为’\0’,那么该字符串就是题目中说的字符串s。
继续向后遍历,遍历到的字符向s1做数组填充,读到第二个逗号时停止。s1末尾添加’\0’。
继续向后遍历到’\0’,将遍历到的字符填充到s2。至此完成s,s1,s2三个字符串的构造。
以下类似找子串的方法。
- 从前向后遍历s,看有没有一段字符与s1相同。方法为给s1也设一个下标i1,如果看到相同字符,i1增加。如果不同,i1变为0。如果i1已经等于s1的长度,那么说明s中包含s1,跳出循环。此时i指向的是s1在s中最后一个字符的后一个位置,如果s中不存在s1,那么i为s的长度l。最后i的值记为a。
- 从后向前遍历s,对s2也从后向前遍历,看s中是否存在s2,方法与上面类似。如果s中包含s2,i指向s2在s中第一个字符的前一个位置,如果s中不包含s2,i的值为-1。最后i的值记为b。
- 从s1的后一个字符a到s2的前一个字符b,包括a和b,这段字符的个数即为字符串的跨度。其长度为b-a+1。如果二者重叠,或其中有一个不存在b-a+1一定是负数。
解法2:使用string类
输入s,遍历s,找到两个逗号的下标c1,c2。
s1为从c1+1位置开始,长度为c2-(c1+1)
s2为从c2+1位置开始,到s的末尾
最后修改s,为从第0位置开始,长度为c1。
使用成员函数find()在s中查找子串s1,使用rfind()在s中查找s2。如果二者存在,即可确定s1的最后一个字符和s2第一个字符的位置,而后求出s1到s2的跨度。
【题解代码】
解法1:使用字符数组
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s[355], s1[15], s2[15];
cin >> s;//先把整个字符串读入s
int l, l1 = 0, l2 = 0, i, i1, i2, a, b;//l,l1,l2:s,s1,s2的长度 i,i1,i2:s,s1,s2的下标
for(i = 0; s[i] != ',' ; ++i);
s[i] = '\0';//去掉第一个逗号后面的字符
l = i;//更新s的长度
i++;
while(s[i] != ',')//构造s1
s1[l1++] = s[i++];
s1[l1] = '\0';
i++;
while(s[i] != '\0')//构造s2
s2[l2++] = s[i++];
s2[l2] = '\0';
i = i1 = 0;
while(i < l)
{
if(s[i] == s1[i1])
{
i++;
i1++;
if(i1 == l1)
break;
}
else if(i1 > 0)//如果i1大于0,那么把i1指向第0位置,再做比较
i1 = 0;
else//如果i1已经为0 s[i]与s1[i1]还是不同,那么看后面的字符
i++;
}
a = i;//此时i指向s1最后一个字符在s中的后一个位置。如果s中不存在s1,该值为l
i = l - 1;//i与i2都指向字符串最后一个字符
i2 = l2 - 1;
while(i >= 0)
{
if(s[i] == s2[i2])
{
i--;
i2--;
if(i2 < 0)
break;
}
else if(i2 != l2 - 1)
i2 = l2 - 1;
else
i--;
}
b = i;//此时i指向s2第0个字符在s中的前一个位置。如果不存在s2,该值为-1
//此时,s1和s2间的字符为下标a到b(包括a和b)
if(b - a + 1 >= 0)
cout << b - a + 1;
else
cout << -1;
return 0;
}
解法2:使用string类
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s, s1, s2;
int i, c1, c2, a, b;//c1,c2:第一个逗号和第二个逗号的下标
cin >> s;//先把整个字符串读入s
for(i = 0; s[i] != ','; ++i);
c1 = i;
for(i = c1 + 1; s[i] != ','; ++i);
c2 = i;
s1 = s.substr(c1 + 1, c2 - c1 - 1);
s2 = s.substr(c2 + 1);//从c2+1到末尾
s = s.substr(0, c1);
a = s.find(s1);//a为s1在s中第一次出现时第一个字符在s中的位置。
b = s.rfind(s2);//b为s2在s中最后一次出现时第一个字符在s中的位置。
if(a == string::npos || b == string::npos)//如果s1或s2不存在
{
cout << -1;
return 0;
}
a = a + s1.length();//a指向s1最后一个字符的后一个位置
if(b - a >= 0)
cout << b - a;
else
cout << -1;
return 0;
}