原题目OJ4925
描述:给定一个短字符串(不含空格),再给定若干字符串,在这些字符串中删除所含有的短字符串。
Input
输入只有1组数据。
输入一个短字符串(不含空格),再输入若干字符串直到文件结束为止。
Output
删除输入的短字符串(不区分大小写)并去掉空格,输出。
样例输入:
in
#include
int main()
{
printf(" Hi ");
}
样例输出:
#clude
tma()
{
prtf(“Hi”);
}
众所周知,上面这个题目如果仅用char类型的数组去写是一件很烦恼的事(因为它不方便对数组的部分东西修改)所以,用上了string就很无脑了。
一 AC代码及原理分析
#include<bits/stdc++.h>
using namespace std;
string a,b,c;
int main(){
cin>>a;//a数组就是要删除的字符串
scanf(" ");//吸收回车
for(int i=0;i<a.size();i++){
a.at(i)=tolower(a.at(i));//a.at(i)==a[i]
}//将a数组都转为小写
while(getline(cin,b)){
//当读入不为空,无限读入
c=b;//数组可以直接赋值
for(int i=0;i<b.size();i++){
b.at(i)=tolower(b.at(i));
}//b为待删除的字符串,也要全部转为小写,由于题目(不区分大小写)要求,c便作为副本
int t=b.find(a);//返回在b里找到a的第一个数的地址
while(t!=string::npos){
//相当于t不为空,也就是b里面还存在a
b.erase(t,a.size());//在b里删去第t个数开始,长度为a.size()的字符串
c.erase(t,a.size());//副本也要删去,只不过c没有进行小写操作就可以保持输入的原样
t=b.find(a,t);//找到下一个a的地址,类似于递归
}
//getline会读入空格,接下来是删去空格的事情
t=c.find(' ');//找到第一个空格的位置
while(t!=string::npos){
//还存在空格
c.erase(t,1);//删去t位置的长度为1的东西(也就是空格)
t=c.find(' ');//递归
}
cout<<c<<endl;//输出
}
return 0;
}
二 用法详解
1.getline
①getline(cin,a):读入一行的,包括空格的数据存到a里
②getline(cin,a,x):读入一行的,包括空格的数据存到a里,但是碰到字符x就不再读入
③cin,getline(a,10):读入长度为10的,包括空格的数据存到a里,位置10存着结束符’\0’,未填满10长度的位置都按空填充
2.tolower&toupper
tolower(a[i]):返回a[i]的小写
toupper(a[i]):返回a[i]的大写
3.at(i)
a.at(i)相当于a[i],只不过前者不会栈溢出
4.size()
a.size()相当于strlen(a),得到a数组的长度,但是前者如果这么写“<=a.size()-1”会有栈溢出的风险,必须这么写“<a.size()”
5. find
①a.find(b):返回在a里面找到包含b数组的第一个字符的地址
②a.find(b,10):从第10个位置开始找,返回在a里面找到包含b数组的第一个字符的地址
6. string::npos
a!=string::npos是a还存在的意思,通常与while结合来循环查找或删除某数组内的另一个多次存在的东西
7.erase
①a.erase(10):从a数组的第10位置个开始删除后面的所有字符串
②a.erase(10,x):从a数组的第10位置个开始删除后面的长度为x的字符串