1.AcWing 760. 字符串长度
这是做的第一道字符串题目哈哈哈!
题目不难,思路很多,但有很多要注意的地方。
(1)cin和scanf读入字符串的时候,读入的字符串不能有空格,否则只读入空格前面的部分。所以可以用fgets和getline读入。
(2)fgets()是不会过滤掉回车符的,而getline可以过滤掉回车符。
这个题可以分为用char数组或者string来做
char数组:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[110];
fgets(str,110,stdin);
int len=0;
for(int i=0;str[i]&&str[i]!='\n';i++)//fgets会把回车符给读入,所以要在处理一下.
len++;
cout<<len;
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[110];
cin.getline(str,110);
int len = strlen(str);
cout<<len;
return 0;
}
后来看到别人的题解时提到了用cin.get.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char a[105];
cin.get(a,105);//需要注意cin.get()不会把换行符取出删除,影响下一次读入!
cout<<strlen(a)<<endl;
return 0;
}
注意:关于getline函数,getline()手册上说到Get line from stream into string,Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n')也就是说遇到定界符如'\n',就会停止输入。郭炜的新标准C++程序设计教程P106上写到,getline()函数函数原型如下:getline(char buf[],int bufSoze),其功就是将用户从键盘输入的一整行,当做一个字符串读入到内存缓冲区buf中,并且在末尾自动添加'\0'。为避免缓冲区溢出,函数最多只会读人bufSize--1个字符.
但是cin.get()不会把回车符删除,这在多次读入的时候会有影响( [https://www.acwing.com/solution/content/10357/](https://) )
对于char型数组字符串求长度:
char prisonName[N];
len = size(prisonName);//len为N,即数组长度
len = sizeof(prisonName);//len为N,即数组长度
len = strlen((prisonName);//len为字符串长度,而不是数组长度
也可以:
int len=0;
for(int i=0;str[i]!='\0';i++)
len++;
`
string
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
int len = str.length();
cout<<len;
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
int len = size(str);
cout<<len;
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
int len = str.size();
cout<<len;
return 0;
}
以上三个代码都可以运行通过
但是下边5行就不可以了:
string str;
len = strlen(str);
len = str.strlen();//这都不行!!!
len = length(str);这样不行)
len = str.sizeof();//报错
len = sizeof(str);//不计算空格!!!!
刚开始这脑壳有点乱www
当然啊,这个题还可以用C来做
#include<string.h>
#include<stdio.h>
int main()
{
char s[105];
gets(s);
printf("%d",strlen(s));
return 0;
}
2. AcWing 761. 字符串中的数字个数
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char ch[110];
int cnt=0;
cin.getline(ch,110);
for(int i=0;ch[i];++i)
if(ch[i]<='9'&&ch[i]>='0')
cnt++;
cout<<cnt;
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char ch;
int cnt;
while(cin>>ch)
if(ch>='0'&&ch<='9')
cnt++;
cout<<cnt;
return 0;
}
啥也不说了,y总牛逼!!!
第二次做这道题:运行结果就是0
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
int len=0;
getline(cin,s);
for(int i=0;s[i];++i)
if(s[i]<=9&&s[i]>=0)
len++;
cout<<len;
return 0;
}
问题出在哪呢?应该是if(s[i]<='9'&&s[i]>='0')
因为此时s[i]是一个字符.所以要用单引号括起来,以后要出注意!!!
3.AcWing 763. 循环相克令
整个题思路一看就能明白:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
string s1,s2;
cin>>s1>>s2;
if(s1==s2) cout<<"Tie"<<endl;
else
{
if(s1=="Hunter")
{
if(s2=="Bear") cout<<"Player2"<<endl;
else cout<<"Player1"<<endl;
}
if(s1=="Bear")
{
if(s2=="Hunter") cout<<"Player1"<<endl;
else cout<<"Player2"<<endl;
}
if(s1=="Gun")
{
if(s2=="Hunter") cout<<"Player2"<<endl;
else cout<<"Player1"<<endl;
}
}
}
return 0;
}
上面思路虽然好想,但是有点复杂耗时,效率不高.
下面来看一个简单的思路:既然是循环相克令,有循环两个字,那么就可以考虑用取模.
#include<iostream>
#include<cstring>
using namespace std;
int get(string s)
{
if(s=="Hunter") return 0;
if(s=="Bear") return 1;
return 2;
}
int main()
{
int t;
string a,b;
cin>>t;
while(t--)
{
cin>>a>>b;
int x=get(a),y=get(b);
if(x==y) cout<<"Tie"<<endl;
else if((x+1)%3==y) cout<<"Player2"<<endl;
else cout<<"Player1"<<endl;
}
return 0;
}
用y总的一句话来说,比赛的时候要用最好想的思路,没必要去用更高效的思路,只要能做出来就行
4. AcWing 765. 字符串加空格
不修改数组,在输出的时候顺便把空格输出:
//char:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char ch[210];
cin.getline(ch,210);
for(int i=0;ch[i];++i)
cout<<ch[i]<<" ";
return 0;
}
//string:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string str;
getline(cin,str);
for(int i=0;str[i];++i)
cout<<str[i]<<" ";
return 0;
}
修改数组,然后输出:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
int len=str.size();
// for(int i=0,j=1;i<len;i+=1){
// str.insert(j," ");
// j+=2;
// }这个也行
for(int i=1;i<=2*len;i+=2)
str.insert(i," ");
cout<<str<<" ";
return 0;
}
还有就是另开一个数组,存一个字符再存一个空格.
#include<iostream>
using namespace std;
int main()
{
string a;
getline(cin,a);
string b;
for(auto c : a)
b = b + c +' ';
cout<< b << endl;
}
y总得代码总是那么简短又实用.
5.AcWing 769. 替换字符
char数组
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char ch[33];
char c;
cin>>ch>>c;
for(int i=0;ch[i];++i)
if(ch[i]==c)
ch[i]='#';
cout<<ch;
return 0;
}
string
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
char ch;
cin>>str>>ch;
for(int i=0;i<str.size();++i)
if(str[i]==ch)
str[i]='#';
cout<<str;
return 0;
}
//把for里面修改一下也可以:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
char ch;
cin>>str>>ch;
for(int i=0;str[i];++i)
if(str[i]==ch)
str[i]='#';
cout<<str;
return 0;
}
因为没有空格,所以当然也可以用scanf输入,不过这个是两行,需要在输入第一行以后吸收掉回车!!!
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
char str[31];
scanf("%s",str);
char ch;
scanf("\n%c",&ch);//吸收掉!!!!
for(int i=0;str[i];i++)
if(str[i]==ch)
str[i]='#';
puts(str);
return 0;
}
还发现了y总写的一个看不懂的代码:
#include<iostream>
using namespace std;
int main()
{
string str;
char x;
cin>>str>>x;
for(auto &c : str)
if(c==x)
c='#';
cout<<str;
}
6. AcWing 773. 字符串插入
最笨的方法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[15],substr[3];
while(cin>>str>>substr){
int p=0,len=strlen(str);
for(int i=1;i<len;++i)
if(str[i]>str[p])
p=i;//确定ASCII码最大的那个字符得下标
for(int i=0,j=len+2,k=len-1;i<len-p-1;i++,j--,k--)
str[j]=str[k];//将p后边得字符后移三个位置
for(int i=p+1,j=0;i<=p+3;i++,j++)
str[i]=substr[j];//把substr添加到空出来的位置
for(int i=0;i<len+3;++i)
cout<<str[i];//输出
cout<<endl;
}
return 0;
}
使用string成员函数:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string a,b;
while(cin>>a>>b){
int p=0;
for(int i=0;i<a.size();++i)
if(a[i]>a[p])
p=i;
cout<<a.substr(0,p+1)+b+a.substr(p+1)<<endl;
// cout<<a.insert(p+1,b)<<endl;
}
return 0;
}
//或者使用插入成员函数---insert()
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string a,b;
while(cin>>a>>b){
int p=0;
for(int i=0;i<a.size();++i)
if(a[i]>a[p])
p=i;
cout<<a.insert(p+1,b)<<endl;
}
return 0;
}
7.AcWing 772. 只出现一次的字符
刚开始的思路:用一个数组a[]存储每个字符出现的次数,然后用另一个数组b[]存储出现次数为1的字符是第几个出现的。最后将两个数组中数值都为1的字符输出。
但是这样当第一个为b[]=1的字符在后边又出现了一次或者多次,这样就使得b数组中没有为1的字符。这样是不对的
#include<iostream>
#include<cstring>
using namespace std;
int a[150];//记录每个字符出现的次数
int b[150];//记录为1的字符是第几个出现的
int cnt=1;
int main()
{
string s;
bool st=true;//默认没有出现一次的字符
cin>>s;
for(int i=0;s[i];++i)
{
a[s[i]]++;
if(a[s[i]]==1)
b[s[i]]=cnt++;
}
for(int i=97;i<=122;++i)
if(a[i]==1) st=false;//表示有出现一次的字符
if(st) cout<<"no";
else
{
for(int i=97;i<=122;++i)
if(a[i]==1&&b[i]==1)
cout<<(char)i;
}
return 0;
}
既然数组b[]没有发挥它该发挥的作用,那么就换一个思路:
用数组a[]来表示每个字符出现的顺序,然后用b[]来表示每个字符出现的次数.遍历完输入的字符串后,再来遍历数组a[].当b[a[i]]==1的字符就是要求的那个字符.
#include<iostream>
#include<cstring>
using namespace std;
bool st[150];//默认为false,没出现过
int a[150];//存储每个字符出现的顺序
int b[150];//存储每个字符出现的次数
int cnt=1;
int main()
{
string s;
cin>>s;
for(int i=0;s[i];++i)
{
if(!st[s[i]])//这个字符第一次出现
{
st[s[i]]=true;
a[cnt++]=s[i];
b[s[i]]++;
}
else
b[s[i]]++;
}
bool bo=true;//表示没有出现次数为1的字符
for(int i=0;i<cnt;++i)
if(b[a[i]]==1)
{
cout<<(char)a[i];
bo=false;//表示有出现次数为1的字符
break;
}
if(bo) cout<<"no";
return 0;
}
AC啊哈哈哈哈哈哈
看完y总的思路后发现想复杂了:
y总先遍历字符串,同时用一个数组a[]来存储字符出现的次数,然后再来遍历字符串,当第一个a[]为1的字符就是要求的答案.压根就不用另开一个数组来存储每个字符出现的顺序.
#include<iostream>
#include<cstring>
using namespace std;
int cnt[26];
int main()
{
string str;
cin>>str;
int len=strlen(str);
for(int i=0;i<len;++i) cnt[str[i]-'a']++;
for(int i=0;i<len;++i)
if(cnt[str[i]-'a']==1)
{
cout<<str[i]<<endl;
return 0;
}
cout<<"no";
return 0;
}
从上面y总的代码能学到不少东西:
- 在存储每个字符出现的次数的时候,数组下标我是从97开始,y总是从0开始的,方法就是cnt[str[i]-‘a’]++;
- 我在最后还用一个变量bo来特判一下没有字符为1的情况,而y总就是直接return 0.
return 0的巧用!!!
8. AcWing 762. 字符串匹配
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a,b;
double k;
cin>>k;
cin>>a>>b;
int cnt=0;
for(int i=0;a[i];++i)
if(a[i]==b[i])
cnt++;
int len=a.size();
if(cnt*1.0/len>=k) cout<<"yes";
else cout<<"no";
return 0;
}
有一个注意的地方:这个因为cnt和len是int型,所以,要将一个乘以1.0,要不就是取整了,还一种方式就是 if((double)cnt/len>=k)
9. AcWing 768. 忽略大小写比较字符串大小
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
getline(cin,b);
int i;//记录两个字符串前i个字符是相同的
for(i=0;a[i]&&b[i];++i)
{
if(a[i]==b[i]||a[i]-32==b[i]||a[i]+32==b[i])
{
}
else
{
if(a[i]>b[i]) cout<<">";
else cout<<"<";
return 0;
}
}
//运行到这里,表示两个字符串在i前所有的字符都相同,下面有两种情况:两个字符串相等,两个字符串不相等.
if(b.size()>i)
{
cout<<"<";
return 0;
}
if(a.size()>i)
{
cout<<">";
return 0;
}
//上面是不相等
cout<<"=";
return 0;
}
但是提交后报错:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
getline(cin,b);
int i;//记录两个字符串前i个字符是相同的
for(i=0;a[i]&&b[i];++i)
{
if(a[i]==b[i]||a[i]-32==b[i]||a[i]+32==b[i])
{
}
else
{
if(a[i]>b[i]||a[i]+32>b[i]) cout<<">";
else cout<<"<";
return 0;
}
}
//运行到这里,表示两个字符串在i前所有的字符都相同,下面有两种情况:两个字符串相等,两个字符串不相等.
if(b.size()>i)
{
cout<<"<";
return 0;
}
if(a.size()>i)
{
cout<<">";
return 0;
}
cout<<"=";
return 0;
}
提交后还报错:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
getline(cin,b);
int i;//记录两个字符串前i个字符是相同的
for(i=0;a[i]&&b[i];++i)
{
if(a[i]==b[i]||a[i]-32==b[i]||a[i]+32==b[i])
{
}
else
{
if(a[i]>=65&&a[i]<=122)//进行特判!!!!!
{
if(a[i]>b[i]||a[i]+32>b[i]) cout<<">";
else cout<<"<";
}
else
{
if(a[i]>b[i]) cout<<">";
else cout<<"<";
}
return 0;
}
}
//cout<<i<<endl;
//运行到这里,表示两个字符串在j前所有的字符都相同,下面有两种情况:两个字符串相等,两个字符串不相等.
if(b.size()>i)
{
cout<<"<";
return 0;
}
if(a.size()>i)
{
cout<<">";
return 0;
}
cout<<"=";
return 0;
}
这样后就AC了
其实在调代码的时候就发现这个题想复杂了:
首先将两个字符串中的大写字母都改成小写字母(都改成大写字母也一样),然后遍历两个字符串,中间发现不一样的判断输出结果,如果没有发现不一样的话就表明两个字符串相等.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
getline(cin,b);
for(int i=0;a[i];++i)
if(a[i]>='A'&&a[i]<='Z') a[i]=a[i]+32;
for(int i=0;b[i];++i)
if(b[i]>='A'&&b[i]<='Z') b[i]=b[i]+32;
for(int i=0;a[i]||b[i];++i)
if(a[i]!=b[i])
{
if(a[i]>b[i]) cout<<">";
else cout<<"<";
return 0;
}
cout<<"=";
return 0;
}
y总思路:将两个字符串的字母全部换成小写以后,使用strcmp()函数来判断
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char a[110],b[110];
cin.getline(a,110);
cin.getline(b,110);
for(int i=0;a[i];++i)
if(a[i]>='A'&&a[i]<='Z') a[i]=a[i]+32;
for(int i=0;b[i];++i)
if(b[i]>='A'&&b[i]<='Z') b[i]=b[i]+32;
int t=strcmp(a,b);
if(t==0) cout<<"=";
else if(t>0) cout<<">";
else cout<<"<";
return 0;
}
注意:此处是用了char数组,因为string不能使用strcmp()函数!!!!
10. AcWing 766. 去掉多余的空格
刚开始想到用删除字符串子串的函数—erase(),但是不行
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string str;
getline(cin,str);
for(int i=0;str[i];++i)
if(str[i]==' '&&str[i+1]==' ')
str.erase(i,1);
cout<<str;
return 0;
}
//但是不行,因为啥呢自己也搞不大明白~~~
输 入:Hello world.This is c language.
标准答案:Hello world.This is c language.
运行答案:Hello world.This is c language.
能看出来这个连续空格的时候不会完全删除的只剩一个,等到后边再去了解了解erase函数的运行过程.
第二个思路是一个一个字符输出,然后加一个判断条件,如果当前是空格,下一个字符还是空格,那就不输出当前字符.
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string str;
getline(cin,str);
for(int i=0;str[i];++i)
if(str[i]!=' '||str[i]==' '&&str[i+1]!=' ')//第一次写的时候没有想到str[i]==' '&&str[i+1]!=' '这种情况,特判一下就好了
cout<<str[i];
return 0;
}
这样运行是可以通过的
最简单的思路是利用cin读入的时候自动过滤空格,那么读入一段然后接着输出,输出后加上个空格,然后循环读入,直到读入结束
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
while(cin>>str)
cout<<str<<" ";
return 0;
}
//当时看到y总说完这种思路后写出来运行通过后,我X牛逼,大写的服!!!
下面说一下双指针法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
int i=0,j=0;//i为左指针,j为右指针
while(true)
{
while(s[j]!=' '&&j<s.size())//刚开始没加j<s.size(),一直显示Segmentation Fault错误
j++;//让j往右走,走到空格的时候停下来
if(j==s.size())
{
cout<<s.substr(i,j-i);
break;
}//当j走到最末尾的时候,说明到头了,输出后就要跳出来了
cout<<s.substr(i,j-i)<<" ";
while(s[j]==' ')
j++;//输出以后,j要继续往右走,确定下一个左指针的位置
i=j;
}
return 0;
}
y总的双指针法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
for(int i=0;i<s.size();++i)
{
int j=i;
string str;
while(j<s.size()&&s[j]!=' ') str+=s[j++];
cout<<str<<" ";
while(s[j]==' ') j++;
i=j-1;//注意:因为上边还要++i.
}
return 0;
}
当然还可以再开一个字符串,存储去掉多余空格的字符,然后输出:
//这个思路呢还有两种写法:
//局部判断法:
#include<iostream>
using namespace std;
int main()
{
string s;
getline(cin,s);
string r;
for(int i=0;i<s.size();++i)
if(s[i]!=' ') r+=s[i];
else
{
if(!i||s[i-1]!=' ') r+=' ';
}
cout<<r<<endl;
return 0;
}
//双指针法:
#include<iostream>
using namespace std;
int main()
{
string s;
getline(cin,s);
string r;
for(int i=0;i<s.size();++i)
if(s[i]!=' ') r+=s[i];
else
{
r+=' ';
int j=i;
while(j<s.size()&&s[j]==' ') j++;
i=j-1;
}
cout<<r<<endl;
return 0;
}
11.AcWing 767. 信息加密
这个题思路不难,但就是看怎么做最快了
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
for(int i=0;str[i];++i){
if(str[i]<='y'&&str[i]>='a'||str[i]>='A'&&str[i]<='Y')
str[i]++;
else if(str[i]=='z') str[i]='a';
else if(str[i]=='Z') str[i]='A';
}
cout<<str;
}
y总
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
for(int i=0;s[i];++i)
if(s[i]<='z'&&s[i]>='a') s[i]=(s[i]-'a'+1)%26+'a';
else if(s[i]<='Z'&&s[i]>='A') s[i]=(s[i]-'A'+1)%26+'A';
cout<<s;
return 0;
}
第二次做:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
char ch1[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char ch2[26]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
for(int i=0;s[i];++i)
if(s[i]>='a'&&s[i]<='z') s[i]=ch1[((s[i]-'a')+1)%26];
else if(s[i]>='A'&&s[i]<='Z') s[i]=ch2[((s[i]-'A')+1)%26];
cout<<s;
return 0;
}
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
char ch1[26];
char ch2[26];
for(int i=0,j=97,k=65;i<26;++i,++j,++k)
{
ch1[i]=j;
ch2[i]=k;
}
for(int i=0;s[i];++i)
if(s[i]>='a'&&s[i]<='z') s[i]=ch1[((s[i]-'a')+1)%26];
else if(s[i]>='A'&&s[i]<='Z') s[i]=ch2[((s[i]-'A')+1)%26];
cout<<s;
return 0;
}
y总那个对于字符和整型之间的转换是最简单的!!!!!!!!背过
12. AcWing 764. 输出字符串
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
for(int i=0;i<a.size()-1;i++)
b+=a[i]+a[i+1];
b+=a[a.size()-1]+a[0];
cout<<b;
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a,b;
getline(cin,a);
int len=a.size();
for(int i=0;i<len;i++)
b+=a[i]+a[(i+1)%len];//b+=(char)(a[i]+a[(i+1)%len]);
cout<<b;
return 0;
}
AcWing 766. 去掉多余的空格
这个题思路不难,大致有两个思路,一个是利用cin读入忽略字符的特性来读入,帮助我们过滤空格,读入一节,然后输出,并加一个空格,然后在读入…直到结束.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
while(cin>>s)
cout<<s<<" ";
return 0;
}
还一个呢就是进行遍历:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
for(int i=0;i<s.size();++i)
{
int j=i;
string str;
while(s[j]!=' ') str+=s[j++];//这个地方while(j<s.size()&&s[j]!=' ')这两个都行.
cout<<str<<" ";
while(s[j]==' ') j++;
i=j-1;//注意:因为上边还要++i.
}
return 0;
}
用for来遍历,while来计算是否满足条件这个组合比两个for嵌套思路和代码上要简单!
13.AcWing 770. 单词替换
这个题思路不难,因为字符串长度是100,所以一个一个遍历就行,遍历到一个字符时,判断其后的a.size()个字符是否和b字符相等。相等的话运用replace函数替换,不相等的话下一位。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
for(int i=0;i<s.size();++i)
if(s.substr(i,a.size())==a)
s.replace(i,a.size(),b);
cout<<s;
return 0;
}
运行样例能通过
输入
You want someone to help you
You
I
输出
I want someone to help you
但是提交后不通过:
输入
It will eventually become a stone Buddha and be respected by everyone
a
b
输出
It will eventublly become b stone Buddhb bnd be respected by everyone
标准答案
It will eventually become b stone Buddha and be respected by everyone
通过对比能发现,还有加个限定条件,即i的后a.size()个字符后边必须是空格或者是结束符,那么:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
for(int i=0;i<s.size();++i)
if(s.substr(i,a.size())==a&&(s[i+a.size()]==' '||s[i+a.size()]=='\0'))
s.replace(i,a.size(),b);
cout<<s;
return 0;
}
这样的话and的问题是解决了,但是又出来了新问题:
输入
It will eventually become a stone Buddha and be respected by everyone
a
b
输出
It will eventually become b stone Buddhb and be respected by everyone
标准答案
It will eventually become b stone Buddha and be respected by everyone
通过观察发现要再加一个判断条件,看i-1是否是空格:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
for(int i=0;i<s.size();++i)
if(s.substr(i,a.size())==a&&(s[i+a.size()]==' '||s[i+a.size()]=='\0')&&s[i-1]==' ')
s.replace(i,a.size(),b);
cout<<s;
return 0;
}
但是加上后运行又出现了个新问题:
输入
You want someone to help you
You
I
输出
You want someone to help you
最开始通过的那个现在又不行了,因为如果要替换的字符在第一个的话就不替换,因为限定条件中必须要前一个字符是空格
不行啊,上边思路想起来挺简单的,但是写出来要加的限定条件太多了。其实刚开始的时候就在想如果要是先输入a,b再输入s那个就能用while(cin>>s)然后在判断,和a相等就输出b,不相等输出a.但是却是先输入s。那么看似这个思路不行啊,但其实是可以的,用输入流
#include<iostream>
#include<sstream>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
stringstream ssin(s);
string str;
while(ssin>>str)
if(str==a) cout<<b<<" ";
else cout<<str<<" ";
return 0;
}
后来想了想,其实除了使用流输入,也可以遍历,只不过这次思路不是挨个便利,然后比较后a.size()个字符了,而是通过遍历,找两个空格间的字符来看和a是否相等.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
for(int i=0,j=0;i<=s.size();++i){//这个地方要等于s.size(),因为下边是到i为空格的下标时开始运算,所以考虑到最后一个单词,要到最后一个字符的下一位
if(s[i]==' '||s[i]=='\0'){//这个地方也可以写成if(s[i]==' '||i==s.size())
if(s.substr(j,i-j)==a) cout<<b<<" ";
else cout<<s.substr(j,i-j)<<" ";
j=i+1;
}
}
return 0;
}
//注意:这个题里边for循环的范围要等于s.size().!!!!
按照这个思路,来看看y总代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a,b;
getline(cin,s);
cin>>a>>b;
for(int i=0,d=0;i<s.size();++i)
{
string word;
while(j<s.size()&&s[j])!=' ')
word+=line[j++];
if(word==a) cout<<b<<' ';
else cout<<word<<' ';
}
return 0;
}
//牛逼!!!!!!!!!!!
第二次做:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,ch1,ch2;
getline(cin,s);
cin>>ch1>>ch2;
for(int i=0,j=0;s[i];++i)
{
while(s[j]!=' '&&s[j])
j++;
if(s.substr(i,j-i)==ch1) cout<<ch2<<" ";
else cout<<s.substr(i,j-i)<<" ";
i=j;j++;
}
return 0;
}
上面的思路和这个题 差不多,用的双指针法.
14.AcWing 771. 字符串中最长的连续出现的字符
做这个题之前做了这个和这个题。所以看完题干第一反应就是用双指针法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
string s;
cin>>s;
int max=0;
char c;
for(int i=0,j=0;s[i];++i)
{
int cnt=0;
while(s[j]==s[i])
j++;
if(j-i>max)
{
max=j-i;
c=s[i];
}
i=j-1;
}
cout<<c<<" "<<max<<endl;
}
return 0;
}
没想到提交AC
了hahahahh开心
y总思路也是用双指针法,跟上面差不多.
15.AcWing 774. 最长单词
整体思路:用while挨个读入,首先判断是否是最后一个单词,如果是最后一个单词,需要先把最后的点去掉,然后判断,如果不是最后一个单词,就不用去掉最后一个点,直接进行判断处理.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
int max=0;
string c;
while(cin>>s)
{
if(s[s.size()-1]=='.')
{
if(s.size()-1>max)
{
max=s.size()-1;
c=s.substr(0,s.size()-1);
}
break;
}
else
{
if(s.size()>max)
{
max=s.size();
c=s;
}
}
}
cout<<c;
return 0;
}
下面来写一下双指针法:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,res;
getline(cin,s);
for(int i=0,j=0;s[i];++i)
{
while(s[j]!=' '&&s[j]!='.')
j++;
if(j-i>res.size())
res=s.substr(i,j-i);
i=j;j++;
}
cout<<res;
return 0;
}
y总的代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string res,str;
while(cin>>str)
{
if(str.back()=='.') str.pop_back();
if(str.size()>res.size()) res=str;
}
cout<<res<<endl;
return 0;
}
不愧是y总,代码就是简单高效orz.
16.AcWing 775. 倒排单词
这个题思路不难,可以从后往前遍历,找到空格就输出他后边的单词,最后再把第一个单词输出,当然,还需要一个变量来记录上一个空格的位置,然后用substr函数输出就行了.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str;
getline(cin,str);
int len=str.size(),last=len;
for(int i=len-1;i>=0;--i){
if(str[i]==' '){
cout<<str.substr(i+1,last-i-1)<<" ";
last=i;
}
}
cout<<str.substr(0,last);
return 0;
}
还一种更简单的思路就是用string数组存下来,然后倒序输出就好了.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str[100];
int n=0;
while(cin>>str[n]) n++;
for(int i=n-1;i>=0;--i)
cout<<str[i]<<" ";
return 0;
}
第二次做:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
for(int i=s.size()-1,j=i;i>=0;--i)
{
while(s[j]!=' '&&j>=0)
j--;
cout<<s.substr(j+1,i-j)<<" ";
i=j;j--;
}
return 0;
}
17.AcWing 776. 字符串移位包含问题
刚看到这个题的时候思路就是暴力,反正最多只有30个字符。首先,对于一个长度为len的字符串,移动len次就会回到最初的字符串。所以对于一个个长度为len的字符串,这个若干次最多就是len-1次就能判断出是否含有这个子串。那么就循环len-1次,然后每次调用find函数看包不包含那个子串。包含的话退出。整体思路不难,但运行的时候出现了几个小问题
//第一次代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str,s;
cin>>str>>s;
int len=str.size();
bool b;
for(int i=0;i<len-1;i++){
if(str.find(s)){
b=true;
break;//表示找到了包含的子串
}
else{//没找到,将第一个移到最后一位.
char s1=str[0];//s1表示字符串第一个字符,也就是往后移的字符
string str1=str.substr(1);
str=s1+str1;
}
}
if(b) cout<<"true";
else cout<<"false";
return 0;
}
//运行样例:AABCD CDAA是通过的,但是提交后报错,这个样例:3eo7vy3emg y3emg3oe7不通过,那就从这个样例找原因
//感觉都挺对的,没毛病,那就拿出来单独调试,先输出看看每次移位后的子串看看:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str,s;
cin>>str;
int len=str.size();
bool b;
for(int i=0;i<len-1;i++){
cout<<str<<endl;
char s1=str[0];
string str1=str.substr(1);
str=s1+str1;
}
return 0;
}
//输入3eo7vy3emg,发现输出的全是3eo7vy3emg,没变化,那问题出在哪了呢,本来以为字符串在for里边是不会变的,就一直是刚读入的状态,想了想发现不是,原来是这 `str=s1+str1;`出了错,应该是 `str=str1+s1;`这样就对了,这样再调试就输出的是每行移位的情况。
//但提交还是不通过,那是哪的问题呢,其实是这句话的问题`if(str.find(s))`.首先啊,这个find返回的是子串的位置或者是nops。如果子串是从第一个位置开始的呢,那就是返回零,返回零的话表明不包含子串。所以这个地方应该改成`if(str.find(s)!=string::npos)`这样的话`:3eo7vy3emg y3emg3oe7`这个样例通过了。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str,s;
cin>>str>>s;
int len=str.size();
bool b;
for(int i=0;i<len-1;i++){
if(str.find(s)!=string::npos){
b=true;
break;//表示找到了包含的子串
}
else{//没找到,将第一个移到最后一位.
char s1=str[0];
string str1=str.substr(1);
str=str1+s1;
}
}
if(b) cout<<"true";
else cout<<"false";
return 0;
}
//但是提交还是报错,`rvEfT8v92wgptkusQZ rvEfT8v92wgptkusQZoKaXVhkN0wkW`,这次这个样例不通过,之前两个都是第一个字符串长,这次是第二个字符串长,所以要用if使得长的字符串在前边,短的在后边,这也是读题不仔细的原因。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string str,s;
cin>>str>>s;
if(str.size()<s.size())
swap(str,s);
int len=str.size();
bool b;
for(int i=0;i<len-1;i++){
if(str.find(s)!=string::npos){
b=true;
break;//表示找到了包含的子串
}
else{//没找到,将第一个移到最后一位.
char s1=str[0];
string str1=str.substr(1);
str=str1+s1;
}
}
if(b) cout<<"true";
else cout<<"false";
return 0;
}
//终于AC
y总整体思路和上边是一样的,不过在找子串的时候没用find函数,而是枚举的。下面来写一下
//自己先写的:
#include<iostream>
using namespace std;
int main()
{
string str,s;
cin>>str>>s;
if(str.size()<s.size()) swap(str,s);
int lenx=str.size(),leny=s.size();
bool b;
for(int i=0;i<lenx-1;++i){
for(int j=0;j<=lenx-leny;j++){
if(str.substr(j,leny)==s){
b=true;
break;
}
}
if(b) break;
else{
char s1=str[0];
string str1=str.substr(1);
str=str1+s1;
}
}
if(b) cout<<"true";
else cout<<"false";
return 0;
}
//y总是连substr()都没用,完全暴力:
#include<iostream>
#include<cstdio>//puts()
#include<algorithm>//swap()
using namespace std;
int main()
{
string a,b;
cin >> a >> b;
if(a.size() < b.size()) swap(a , b);
for(int i = 0;i < a.size(); i ++)
{
a = a.substr(1)+a[0];
for(int j = 0; j + b.size() <= a.size();j++){
int k=0;
for(; k < b.size();k ++)
if(a[j + k] != b[k])
break;
if(k == b.size())//这个地方,上边for循环完以后,因为k<b.size(),所以k=b.size()
{//如果k == b.size(),那么就表示有相对应的子串,这时输出就可以了
puts("true");
return 0;
}
}
}
puts("false");
return 0;
}
第二次做:这次较上次做有所高效
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,a;
cin>>s>>a;
if(s.size()<a.size()) swap(s,a);//直接使用swap()函数,不借助于第三个变量
//上面代码是保证让第一个字符串长度大于等于第二个字符串长度
int len=s.size(),lena=a.size();
string str=s;
for(int i=0;i<len;++i)
{
for(int i=0;str[i+lena];++i)//这个地方i+lena可以使的代码运行更快
if(str.substr(i,lena)==a)
{
cout<<"true";
return 0;
}
str=str.substr(1)+str[0];//将str进行更新,在这个地方substr()函数的第二个参数可以省略
}
cout<<"false";
return 0;
}
18.AcWing 777. 字符串乘方
这个题刚开始没有思路,脑子嗡嗡的,嗡了好一会以后,有了,无外乎挨个试白。对于长度为n的字符串,看看前一个子串满足条件吗,满足的话输出,不行的话前2个子串,前3个子串,前4个子串…一直到前n个子串。如果上面都不满足,那么就输出1。下面来看看代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,str;
bool b;
while(cin>>s&&s!="."){
int len=s.size();
for(int i=1;i<=len;++i){
str=s.substr(0,i);
//int lens=str.size();//这个其实不要也行,str的长度lens等于i;
int j,k;//k表示和后边比对的子串的第一个字符的下标
for(j=1,k=0;j<=len/i-1;j++){
k+=i;
//cout<<s.substr(k,i)<<endl;测试
if(s.substr(k,i)!=str)
break;
}
if(j==len/i){//表示当前前i个子串和后边len/i个长度为i的子串相等,所以输出。
cout<<len/i<<endl;//注意读题,刚开始以为是i,但其实是求len/i.
b=false;
break;
}
}
if(b) cout<<"1"<<endl;
}
return 0;
}
下面看看y总的思路:
和y总整体思路不一样借鉴y总的思路把我的改进一下。y总是将前i个字符连续加len/i次,然后看加完的字符串是否和输入的字符串相等,相等的话就停止,找到最佳的了,不相等的话i++,直到i=n.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
while(cin>>s,s!="."){
int i;
for(i=1;i<=s.size();++i){
string str=s.substr(0,i);
string last;
for(int j=1;j<=s.size()/i;++j)//str的长度为i
last+=str;
if(last==s){
cout<<s.size()/i<<endl;
break;
}
}
if(i==s.size()+1)
cout<<"1"<<endl;
}
return 0;
}//这样比之前的那个简单了不少!!!以后就背过这个就行了。
//下面看看y总的代码:
#include<iostream>
using namespace std;
int main()
{
string str;
while(cin>>str,str!="."){
int len=str.size();
for(int n=len;n;n--)
if(len%n==0)
{
int m = len/n;
string s=str.substr(0,m);
string r;
for(int i=0;i<n;++i) r+=s;
if(r==str){
cout<<n<<endl;
break;
}
}
}
return 0;
}
第二次做:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
while(cin>>s&&s!=".")
{
string a;
for(int i=1;i<=s.size();++i)
{
a=s.substr(0,i);
bool st=true;
for(int j=0;j+i<=s.size();++j)
{
if(s.substr(j,i)!=a)
{
st=false;
break;
}
j=j+i-1;
}
if(st)
{
cout<<s.size()/i<<endl;
break;
}
}
}
return 0;
}
WA了,通过调试样例后发现了问题,思路不严谨,改正后AC了:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s;
while(cin>>s&&s!=".")
{
string a;
for(int i=1;i<=s.size();++i)
{
if(s.size()%i!=0)
continue;
a=s.substr(0,i);
bool st=true;
for(int j=0;j+i<=s.size();++j)
{
if(s.substr(j,i)!=a)
{
st=false;
break;
}
j=j+i-1;
}
if(st)
{
cout<<s.size()/i<<endl;
break;
}
}
}
return 0;
}
AcWing 778. 字符串最大跨距( https://www.acwing.com/problem/content/780/ )
这个题思路不难,在满足了那三个条件后(同时在S中出现,且S1位于S2的左边,并在S中互不交叉),就表明一定有一个或多个S1和一个或多个S2存在,只需要找最左边的S1的终点下标和最右边的S2的起点下标,然后相减就可以了。
不过这个题的输入不会弄…
//不过也有两个思路,一个是用find()和rfind()函数确定两个下标,另一个是手动确定两个下标
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int cnt=0;
string s,s1,s2;
char ch;
while(cin>>ch){
if(ch==',') cnt++;
else {
if(cnt==0) s+=ch;
else if(cnt==1) s1+=ch;
else s2+=ch;
}
}
int len=s.size(),len1=s1.size(),len2=s2.size();
if(s.find(s1)==string::npos||s.find(s2)==string::npos) cout<<"-1";//其实这个地方当find找不到时,会返回-1.
else{
int x=s.find(s1);
int y=s.rfind(s2);
if(x+len1-1>=y) cout<<"-1";
else cout<<y-(x+len1);
}
return 0;
}
//手动写:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,s1,s2;
int cnt=0;
char ch;
while(cin>>ch){
if(ch==',') cnt++;
else if(cnt==0) s+=ch;
else if(cnt==1) s1+=ch;
else s2+=ch;
}
int left=-1,right=-1;
for(int i=0;i+s1.size()<s.size();++i)
if(s.substr(i,s1.size())==s1){
left=i;break;
}
for(int j=s.size()-s2.size();j>=0;--j)
if(s.substr(j,s2.size())==s2){
right=j;break;
}
//cout<<left<<" "<<right;
if(left>=0&&right>=0&&left+s1.size()<=right) cout<<right-left-s1.size();
else cout<<"-1";
return 0;
}
//当然substr()函数也可以手写;
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string s,s1,s2;
int cnt=0;
char ch;
while(cin>>ch){
if(ch==',') cnt++;
else if(cnt==0) s+=ch;
else if(cnt==1) s1+=ch;
else s2+=ch;
}
int len=s.size();
int len1=s1.size();
int len2=s2.size();
int left=-1,right=-1;
bool is_same=true;
int k;
for(int i=0;i+len1<len;++i){
for(k=0;k<len1;++k)
if(s[i+k]!=s1[k]){
//is_same=false;
break;
}
if(k==len1){
left=i;
break;
}
}
bool is_same1=true;
for(int j=len-len2;j>=0;--j){
for(k=0;k<len2;++k)
if(s[j+k]!=s2[k]){
//is_same1=false;
break;
}
if(k==len2){
right=j;
break;
}
}
if(left>=0&&right>=0&&left+len1<=right) cout<<right-left-len1;
else cout<<"-1";
return 0;
}
下面来说一下这个题其他的读入方法:
string s, s1, s2;
char c;
while (cin >> c, c != ',') s += c;
while (cin >> c, c != ',') s1 += c;
while (cin >> c) s2 += c;
string s,s1,s2;
getline(cin,s,',');
getline(cin,s1,',');
getline(cin,s2,'\n');
https://www.acwing.com/solution/content/11623/
string s,s1,s2;
cin>>s;
int index1=s.find(","),index2=s.rfind(",");
s1=s.substr(index1+1,index2-index1-1);
s2=s.substr(index2+1);
s=s.substr(0,index1);
https://www.acwing.com/solution/content/9163/
下面来看看y总的代码:
#include<iostream>
using namespace std;
int main()
{
string s,s1,s2;
char c;
while(cin>>c,c!=',') s+=c;
while(cin>>c,c!=',') s1+=c;
while(cin>>c) s2+=c;
if(s.size()<s1.size()||s.size()<s2.size()) puts("-1");
else{
int l=0;
while(l+s1.size()<=s.size())
{
int k=0;
while(k<s1.size())
{
if(s[l+k]!=s1[k]) break;
k++;
}
if(k==s1.size()) break;
l++;
}
int r=s.size()-s2.size();
while(r>=0)
{
int k=0;
while(k<s2.size())
{
if(s[r+k]!=s2[k]) break;
k++;
}
if(k==s2.size()) break;
r--;
}
l+=s1.size()-1;
if(l>=r) puts("-1");
else printf("%d\n",r-l-1);
}
return 0;
}
//y总这两个while()循环嵌套值得借鉴
AcWing 779. 最长公共字符串后缀( https://www.acwing.com/problem/content/781/ )
刚开始代码如下,运行样例只输出几行空格
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
string str[200];
while(cin>>n,n){//刚开始没有加“,n”这样是不对的。
for(int i=0;i<n;++i)
cin>>str[i];
int min=200;
for(int i=0;i<n;++i)
if(str[i].size()<min) min=str[i].size();//求出输入的n个字符串中最短的字符串长度
int cnt=0,len=str[0].size();
for(int j=len-1;j>=len-min;j--){
//cout<<str[0].substr(j)<<endl;
int k;
for(int k=1;k<n;++k)//遍历剩下的n-1个字符串看看字符串s是否和剩下n-1个相同
if(str[k].substr(j)!=str[0].substr(j))
break;
if(k==n)
cnt++;//计算公共后缀的个数
}
//cout<<cnt<<endl;
if(cnt==0) cout<<endl;
else cout<<str[0].substr(len-cnt)<<endl;
}
return 0;
}
//注释的几行是调试找问题出在哪个地方的,最后发现break的那个for只跑一次,原因出在if中`str[k].substr(j)`substr的参数不应该是j.
改进后运行通过
//第一次运行出来
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
string str[200];
while(cin>>n,n){
for(int i=0;i<n;++i)
cin>>str[i];
int min=200;
for(int i=0;i<n;++i)
if(str[i].size()<min) min=str[i].size();//求出输入的n个字符串中最短的字符串长度
int cnt=0,len=str[0].size();
for(int j=len-1;j>=len-min;j--){
int k;
//cout<<str[0].substr(j)<<endl;
for(k=1;k<n;k++){//遍历剩下的n-1个字符串看看字符串s是否和剩下n-1个相同
//cout<<str[k].substr(j)<<","<<endl;
int lenk=str[k].size();
int m=lenk-1;
if(str[k].substr(m-cnt)!=str[0].substr(j))
break;
}
//cout<<k<<endl;
if(k==n)
cnt++;//计算公共后缀的个数
}
//cout<<cnt<<endl;
if(cnt==0) cout<<endl;
else cout<<str[0].substr(len-cnt)<<endl;
}
return 0;
}
//第二次没看上一个代码,又写了一个不一样的,虽然整体思路一样,但是比较的那个地方不同,感觉下边的更简单:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
string str[210];
while(cin>>n,n){
for(int i=0;i<n;++i)
cin>>str[i];
int min=200;
for(int i=0;i<n;++i)
if(str[i].size()<min)
min=str[i].size();
int len=str[0].size(),i;
for(i=1;i<=min;++i){//后i子串
string s=str[0].substr(len-i);
int j;
for(j=1;j<n;j++)//和后n-1个字符串做对比
if(str[j].substr(str[j].size()-i)!=s)
break;
if(j!=n)//表示不能和剩下n-1个字符串匹配,所以就break,不往下执行了,下边的肯定不满足情况
break;
}
if(i==1) cout<<endl;
else cout<<str[0].substr(len-i+1)<<endl;
}
return 0;
}
这个题的整体思路不难想,选择最后第一个字符串为基准,从后往前开始查找,看和另外n-1个字符串是否为公共后缀,直到找到有不相同的那个,然后跳出。
下面看看y总的代码:我是从小到大开始枚举,y总是从大到小开始枚举。
#include<iostream>
using namespace std;
const int N = 200;
int n;
string str[N];
int main()
{
while (cin >> n, n){
int len = 200;
for(int i = 0; i < n; ++ i)
{
cin >> str[i];
if(len > str[i].size()) len = str[i].size();
}
while(len)
{
bool success = true;
for(int i = 1; i < n; i ++)
{
bool is_same =true;
for(int j = 1; j <=len; j++)
if(str[0][str[0].size() - j] != str[i][str[i].size() - j])
{
is_same = false;//表示有一个不同的,跳出来就行了吗,不用比较了
break;
}
if (!is_same)//等价于if(is_same==false),即后len个子序列和后面某个字符串不同,那么就不用继续再比较了,跳出来就行,再试下一个len.
{
success = false;
break;
}
}
if(success) break;//如果后len个字符在n-1个字符串中都有时,那么就找到了最长公共子序列,这时跳出循环就好了.
len--;//如果上边的success是false,那么说明后len个序列不是公共子串,这时要让len--.
}
cout << str[0].substr(str[0].size()-len) << endl;
}
return 0;
}
总结的很棒呀!
注意:getline函数在读入一个字符串时,会自动把结尾的回车符给删除
。感觉自动删除说法有点不太准确,查了下getline()的手册,说到Get line from stream into string,
Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character,
'\n'
)也就是说遇到定界符如
'\n'
,就会停止输入~好的,感谢大佬指点~~~
最近也被输入输出折磨,随意就查手册看看究竟,一起学习
我也是,还好有大佬相助