PTA总是在输入数据这块搞些个奇奇怪怪的东西
之前是那个空白行,这次来了个这个
输入共一行,包含三个字符串S,S1,S2,字符串之间用逗号隔开。
输入样例:
abcd123ab888efghij45ef67kl,ab,ef
那么呢 根据上次的经验,我们还是要巧妙地利用**&&**。
解决方法:
char s[1000], s1[20], s2[20], c;
int l = 0 , l1 = 0 , l2 = 0;
while ((c = getchar()) && c != ',')//一个一个字符地接收
s[l++] = c;//输入字符数组s
while ((c = getchar()) && c != ',')
s1[l1++] = c;//输入字符数组s1
while ((c = getchar()) && c != EOF)
s2[l2++] = c;//输入字符数组s2
(或者这样子 (学长的方法)(有点子神奇))
string str;
getline(cin, str);//先接收整个一行输入的东西
int len = str.size();
int pos1 = -1, pos2 = -1;
for(int i = 0; i < len; i++) {
if(str[i] == ',') {
if(pos1 == -1) {//这个判断就是看遍历到的是第一个逗号还是第二个
pos1 = i;//记录下逗号的位置为字符串分开的标志
} else {
pos2 = i;//同上
}
}
}
string s = str.substr(0, pos1);//巧妙地运用string.substr函数把字符串提出来
string s1 = str.substr(pos1+1, pos2 - pos1 - 1);
string s2 = str.substr(pos2+1, len);
这道题感觉还
是不错的,记录一下吧
7-7 h0093. 字符串最大跨距 (20 分)
有三个字符串S,S1,S2,其中,S长度不超过300,S1和S2的长度不超过10。
现在,我们想要检测S1和S2是否同时在S中出现,且S1位于S2的左边,并在S中互不交叉(即,S1的右边界点在S2的左边界点的左侧)。
计算满足上述条件的最大跨距(即,最大间隔距离:最右边的S2的起始点与最左边的S1的终止点之间的字符数目)。
如果没有满足条件的S1,S2存在,则输出-1。
例如,S = “abcd123ab888efghij45ef67kl”, S1=”ab”, S2=”ef”,其中,S1在S中出现了2次,S2也在S中出现了2次,最大跨距为:18。
输入格式:
输入共一行,包含三个字符串S,S1,S2,字符串之间用逗号隔开。
数据保证三个字符串中不含空格和逗号。
输出格式:
输入共一行,包含三个字符串S,S1,S2,字符串之间用逗号隔开。
数据保证三个字符串中不含空格和逗号。
输入样例:
abcd123ab888efghij45ef67kl,ab,ef输出样例:
18
我还以为这道题要用kmp,发现好像不用那么麻烦
-
//我们想要检测S1和S2是否同时在S中出现,且S1位于S2的左边,并在S中互不交叉
-
//所以我们要检查s1在s中第一次出现的位置和s2在s中最后一次出现的位置
-
//后者减前者为最大跨度,如果小于零说明不满足题意则要输出-1
#include<bits/stdc++.h> using namespace std;
int main() { string str; //先接收全部输入的东西 getline(cin,str); int len = str.size(); int pos1 = -1, pos2 = -1;//设置两个标志逗号的变量初始化为不会作为下标的数-1 for(int i = 0; i < len; i++) { if(str[i] == ',') { if(pos1 == -1)//如果pos1等于-1说明遇到的是第一个逗号 pos1=i; else //否则遇到的是第二个 pos2=i; } } int l = pos1,l1 = pos2-pos1-1,l2=len-pos2-1;//注意字符串下标是从0开始记录的哦 //cout<<l<<endl<<l1<<endl<<l2<<endl;//测试长度是否运算正确 string s=str.substr(0,l); string s1=str.substr(pos1+1,l1); string s2=str.substr(pos2+1,l2); //cout<<s<<endl<<s1<<endl<<s2<<endl;//测试字符串提取是否正确
int ans = 0;//ans=s2最后出现的首字母前一个字符下标-s1第一次出现的最后一个字符的后一个字符下标 int i,k=0;//k为连续匹配字符长度 for(i = 0; i < l; i++) { if(s[i] == s1[k]) k++;//相同就继续匹配,k++ else k=0;//否则k重置为0 if(k == l1) { ans-=i+1;//找到了第一个匹配处,最后的结果是要减去s1第一次出现的后面一个位置的下标 break;//跳出循环 } } int j=l2-1; for(i = l;i >= 0; i--)//从后往前遍历 { if(s[i] == s2[j]) j--;//相同就继续匹配,子字符串也反过来遍历匹配 else j=l2-1;//否则重置为l2-1(因为字符串是从下标0开始的,所以要-1) if(j == 0) { ans+=i-1;//找到了s2最后出现的匹配处,它的前一个位置下标作为减数 break; } } if(ans >= 0)//如果ans<0说明不满足题目要求 cout<<ans; else cout<<"-1"; return 0;}