C/C++基础知识——字符串(二)https://developer.aliyun.com/article/1437435
14.最长单词
知识点:s.back()与s.pop_back();的用法
一个以 .
结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。
输入格式
输入一行字符串,表示这个简单英文句子,长度不超过 500。
输出格式
该句子中最长的单词。如果多于一个,则输出第一个。
输入样例:
I am a student of Peking University.
输出样例:
University
(1)用cin过滤掉空格直接输入判断
#include <bits/stdc++.h> using namespace std; int main() { string str,res; while(cin >> str) { if(str.back() == '.') str.pop_back(); if(str.size() > res.size()) res = str; } cout << res; return 0; }
(2)用sstream流
#include <bits/stdc++.h> using namespace std; int main() { string s; getline(cin,s); stringstream ssin(s); string str,res; while(ssin >> str) { if(str.back() == '.') str.pop_back(); if(str.size() > res.size()) res = str; } cout << res; return 0; }
(3)双指针算法
//双指针算法 #include <bits/stdc++.h> using namespace std; int main() { string str; getline(cin,str); int x = 0,y = 0; int dix = 0; if(str.back() == '.') str.pop_back(); for(int i = 0; i < str.size(); i++) { int j = i; while(j < str.size() && str[j] != ' ') j++; if(j - i > dix) { dix = j - i; x = i; y = j; } i = j; } for(int i = x; i < y && str[i] != '.'; i++) cout << str[i]; return 0; }
15.倒排单词
知识点: string s[1000] s中存放的是字符串
编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。
输入格式
输入为一个字符串(字符串长度至多为 100)。
输出格式
输出为按要求排序后的字符串。
输入样例:
I am a student
输出样例:
student a am I
#include <bits/stdc++.h> using namespace std; int main() { string str[1000]; int i = 1; while(cin >> str[i]) i++; for(int j = i - 1; j > 0; j--) cout << str[j] << " "; return 0; }
16.字符串移位包含问题
知识点:去掉某个位置的字符:a.substr(1) 去掉了第一个位置的字符,循环暴力枚举
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串 s1 和 s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。
例如 CDAA
是由 AABCD
两次移位后产生的新串 BCDAA
的子串,而 ABCD
与 ACBD
则不能通过多次移位来得到其中一个字符串是新串的子串。
输入格式
共一行,包含两个字符串,中间由单个空格隔开。
字符串只包含字母和数字,长度不超过 30。
输出格式
如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出 true
,否则输出 false
。
输入样例:
AABCD CDAA
输出样例:
true
#include <bits/stdc++.h> using namespace std; int main() { string str1,str2; cin >> str1 >> str2; if(str1.size() < str2.size()) swap(str1,str2); for(int i = 0; i < str1.size(); i++) { //将a中第一个字符删掉再后面加上a[0] str1 = str1.substr(1)+str1[0]; //遍历起点 int j = 0; for(; j + str2.size() <= str1.size(); j++) { int k = 0; //遍历b的每一个字符位置 for(; k < str2.size(); k++) { if(str1[j + k] != str2[k]) break; } if(k == str2.size()) { cout << "true" << endl; return 0; } } } cout << "false" << endl; return 0; }
17.字符串最大跨距
知识点: 过滤,读入字符串a,b,c 字符串的遍历与判断
有三个字符串 S,S1,S2,其中,S 长度不超过 300,S1和 S2 的长度不超过 10。
现在,我们想要检测 S1 和 S2是否同时在 SS 中出现,且 S1 位于 S2的左边,并在 S 中互不交叉(即,S1的右边界点在 S2 的左边界点的左侧)。
计算满足上述条件的最大跨距(即,最大间隔距离:最右边的 S2 的起始点与最左边的 S1 的终止点之间的字符数目)。
如果没有满足条件的 S1,S2 存在,则输出 −1。
例如,S=S= abcd123ab888efghij45ef67kl
, S1= ab
, S2= ef
,其中,S1 在 S中出现了 2 次,S2也在 S 中出现了 2 次,最大跨距为:18。
输入格式
输入共一行,包含三个字符串 S,S1,S2,字符串之间用逗号隔开。
数据保证三个字符串中不含空格和逗号。
输出格式
输出一个整数,表示最大跨距。
如果没有满足条件的 S1 和 S2存在,则输出 −1。
输入样例:
abcd123ab888efghij45ef67kl,ab,ef
输出样例:
18
#include <bits/stdc++.h> using namespace std; int main() { string s,s1,s2; char c; //过滤,读入字符串s,s1,s2 while(cin >> c && c != ',') s += c; while(cin >> c && c != ',') s1 += c; while(cin >> c ) s2 += c; //判断字符串s的长度是否包含了字符串s1,s2 if(s1.size() > s.size() || s2.size() > s.size()) cout << "-1" << endl; else { int l = 0; //从字符串s的第一个位置开始寻找字符串s1 for(; l + s1.size() <= s.size() ;l++)//一直找到字符串s的末尾 { int k = 0; //从字符串s1的第一个字符串开始比较是否与字符串s相等 for(; k < s1.size() ;k++)//一直比较到字符串s1的末尾 { //如果字符串s中的某个字符与字符串s1中某个字符不相等则跳出循环 if(s[l + k] != s1[k]) break; //若相等则继续比较字符串b中的下一个字符 } //证明从l开始的长度为s1.size()的子串与s1相等且是字符串s的最左侧出现的一个字符串s1 if(k == s1.size()) break; //继续从字符串s中寻找是否有子串为字符串s1 } int r = s.size(); //从字符串s的右边开始找子串是否为字符串s2 for(; r >= 0; r--)//一直找到字符串s的最左侧 { int k = 0; for(; k < s2.size(); k++) { if(s[r + k] != s2[k]) break; } if(k == s2.size()) break; } //l为s中子串与字符串s1相等的子串的末尾一个字符 l += s1.size() - 1; //判断字符串s2是否在字符串s1的右侧 是则输出最大的跨距 if(r > l) cout << r - l - 1 << endl; else cout << "-1" << endl; } return 0; }
知识点:find大法
s.find(); // 在字符串s上从前往后找 s.rfind(); // 从后往前
s.find(s1)的返回值为所查找的子串的第一个字符的位置,找不到返回 -1
#include <bits/stdc++.h> using namespace std; int main() { string s, s1, s2, a; getline(cin, a); int f1, f2; // 两个','的位置 f1 = a.find(','); f2 = a.rfind(','); s = a.substr(0, f1); s1 = a.substr(f1 + 1, f2 - f1 - 1); s2 = a.substr(f2 + 1); int l, r; l = s.find(s1); // 在字符串s上从左往右找s1 r = s.rfind(s2); // 在字符串s上从右往左找s2 if (l == -1 || r == -1) // s1 或 s2 不在 s 上 { cout << "-1"; return 0; } l = s.find(s1) + s1.size() - 1; // l为s1最右面的下标 if ( l >= r ) // s1 s2 交叉 cout << "-1"; else cout << r - l - 1; return 0; }