利用find函数完成对字符串的查找操作
注意:
查找字符串a是否包含子串b,不是用strA.find(strB) > 0 而是 strA.find(strB) != string:npos
其中string:npos是个特殊值,说明查找没有匹配
int idx = str.find(“abc”); if (idx == string::npos) … 上述代码中,idx的类型被定义为int,这是错误的,即使定义为 unsigned int 也是错的,它必须定义为 string::size_type。 npos 是这样定义的: static const size_type npos = -1;
因为 string::size_type (由字符串配置器 allocator 定义) 描述的是 size,故需为无符号整数型别。因为缺省配置器以型别 size_t 作为 size_type,于是 -1 被转换为无符号整数型别,npos 也就成了该型别的最大无符号值。不过实际数值还是取决于型别 size_type 的实际定义。不幸的是这些最大值都不相同。事实上,(unsigned long)-1 和 (unsigned short)-1 不同(前提是两者型别大小不同)。因此,比较式 idx == string::npos 中,如果 idx 的值为-1,由于 idx 和字符串string::npos 型别不同,比较结果可能得到 false。 要想判断 find() 的结果是否为npos,最好的办法是直接比较:
if (str.find(“abc”) == string::npos) { … }
错误:if(str.find(“abc”) ) 注:找不到abc会返回-1,不为0为True。0为False
通常来说,find函数用于寻找某个序列的在string中第一次出现的位置。
例洛谷P1598
写一个程序从输入文件中去读取四行大写字母(全都是大写的,每行不超过100个字符),然后用柱状图输出每个字符在输入文件中出现的次数。严格地按照输出样例来安排你的输出格式。
输入输出格式 输入格式: 四行字符,由大写字母组成,每行不超过100个字符
输出格式: 由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的。在任何一行末尾不要打印不需要的多余空格。不要打印任何空行。
输入输出样例 输入样例#1: THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG. THIS IS AN EXAMPLE TO TEST FOR YOUR HISTOGRAM PROGRAM. HELLO! 输出样例#1: * * * * * * * * * * * *
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 说明 每行输出后面不允许出现多余的空格。
解:
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int main(){ string s; char s1[800],s2[800],s3[800],s4[800],f; int sum[30],length=0,maxnum=0; cin.getline(s1,800); cin.getline(s2,800); cin.getline(s3,800); cin.getline(s4,800); int counter,begin=-1; strcat(s1,s2); strcat(s1,s3); strcat(s1,s4); s.assign(s1);//字符数组转化字符串,string转化char[],strcpy(ch,str.c_str()) for(char x='A';x<='Z';x++){ counter=0; while((begin=s.find(x,begin+1))!=string::npos){ counter++; } sum[length++]=counter; } for(int i=0;i<length;i++) maxnum=max(maxnum,sum[i]); for(int i=maxnum;i>0;i--){ for(int j=0;j<26;j++){ if(sum[j]>=i) cout<<"*"; else cout<<" "; if(j!=25) cout<<" "; } cout<<endl; } for(char x='A';x<='Z';x++) cout<<x<<" "; return 0; }例2:
题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章
中的某一独立单词在不区分大小写的情况下完全相同(参见样例1 ),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2 )。
输入输出格式 输入格式: 输入文件名为stat.in ,2 行。
第1 行为一个字符串,其中只含字母,表示给定单词;
第2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
输出格式: 输出文件名为stat.out 。
只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从 0 开始);如果单词在文章中没有出现,则直接输出一个整数-1。
输入输出样例 输入样例#1: To to be or not to be is a question 输出样例#1: 2 0
输入样例#2: to Did the Ottoman Empire lose its power at that time 输出样例#2: -1 说明 数据范围
1≤ 单词长度≤10。
1≤ 文章长度≤1,000,000。
noip2011普及组第2题
解:
#include<iostream> #include<cstring> using namespace std; int main(){ int counter=0,begin=-1,pos=-1; string s1,s2; getline(cin,s1);//整行输入 getline(cin,s2); for(int i=0;i<s1.size();i++) s1[i]=toupper(s1[i]); for(int i=0;i<s2.size();i++) s2[i]=toupper(s2[i]); s1=' '+s1+' '; s2=' '+s2+' '; while((begin=s2.find(s1,begin+1))!=string::npos){ counter++; if(counter==1) pos=begin; } if(pos!=-1) cout<<counter<<" "<<pos; else cout<<pos; return 0; }Acwing776. 字符串移位包含问题
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。
例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串。
输入格式 共一行,包含两个字符串,中间由单个空格隔开。
字符串只包含字母和数字,长度不超过30。
输出格式 如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出true,否则输出false。
输入样例: AABCD CDAA 输出样例: true
#include<bits/stdc++.h> using namespace std; int main() { string a,b; cin>>a>>b; if(a.size()<b.size()) swap(a,b); a+=a; size_t t=a.find(b); if(t!=string::npos) cout<<"true"; else cout<<"false"; return 0; }