1.substr
函数原型
string substr(size_t pos = 0, size_t count = npos) const;
- pos:起始下标(从 0 开始)
- npos:截取长度(不是下标)
- count:截取字符个数
- 省略 count:从 pos 一直截取到字符串末尾
2.find
函数原型
// 1. 查找 string 类型子串 size_t find(const string& str, size_t pos = 0) const noexcept; // 2. 查找 C 风格字符串(const char*) size_t find(const char* s, size_t pos = 0) const; // 3. 查找 C 字符串前 n 个字符 size_t find(const char* s, size_t pos, size_t n) const; // 4. 查找单个字符 size_t find(char c, size_t pos = 0) const noexcept;通用前提
**1.**下标从 0 开始
**2.**查找失败统一返回:
string::npos
if(s.find("java") == string::npos) { cout << "未找到" << endl; }**3.**二者不修改原字符串
**4.**支持查找:单个字符、子串
- 作用:从左→右查找,返回第一个匹配的下标
- pos:可选,指定开始查找的起始位置,默认从头
0开始
rfind及相关函数
从后往前找,返回最后一次出现的子串 / 字符位置。
它和
find(从前往后找)正好相反,是面试和开发里超常用的函数
函数 方向 含义 一句话记忆 find_first_of 左→右 第一个是目标字符 找第一个出现的 find_last_of 右→左 最后一个是目标字符 找最后一个出现的 find_first_not_of 左→右 第一个不是目标字符 找第一个不一样的 find_last_not_of 右→左 最后一个不是目标字符 找最后一个不一样的
s.find("ab"); // 必须找到 "ab" 才返回 s.find_first_of("ab"); // 找到 a 或 b 就返回使用范例
示例 1:去掉字符串前后空格
string s = " Hello World "; // 找到第一个不是空格的位置 size_t start = s.find_first_not_of(" "); // 找到最后一个不是空格的位置 size_t end = s.find_last_not_of(" "); // 截取中间内容 string res = s.substr(start, end - start + 1); cout << res; // Hello World示例 2:查找第一个标点符号
string s = "Hello,World!"; // 找第一个 逗号 或 感叹号 size_t pos = s.find_first_of(",!"); // pos = 5
3.getline
函数原型
getline (cin, str) (读取整行)
- 用于读取 带空格 的完整一行
- 从当前位置读到 ** 换行符
\n** 为止- 包含空格,不包含最后的换行
- 会吃掉换行符
函数 读取规则 遇到空格 / 回车 适用场景 cin >> 变量 读取****连续字符 自动停止,并丢弃换行 **读数字、**单个单词 getline (cin, 变量) 读取一整行 遇到回车才停止,保留空格 读带空格的句子
string s; cin >> s; // 输入:hello world cout << s; // 输出:hello (只读到空格前) getline(cin, s); // 输入:hello world cout << s; // 输出:hello world (完整读取)
题目理解:
125. 验证回文串
https://leetcode.cn/problems/valid-palindrome/
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串
s,如果它是 回文串 ,返回true;否则,返回false。题解:
class Solution { public: bool isPalindrome(string s) { string w; for(int begin=0;begin<s.size();begin++) { if(s[begin]>='A'&&s[begin]<='Z') { s[begin]+=32; } if(s[begin]>='a'&&s[begin]<='z') w+=s[begin]; if(s[begin]>='0'&&s[begin]<='9') w+=s[begin]; } if(w[0]==NULL) return true; int begin1=0,end1=w.size()-1; while(w[begin1]==w[end1]&&begin1<end1) { begin1++; end1--; } if(w[begin1]!=w[end1]) return false; return true; } };
4.关系运算符重载
1.比较运算符
string 比较不是比较长度,而是:从左到右逐个字符比较 ASCII 值,谁的字符 ASCII 小,谁就更小。
ASCII 大小规律(记住就会用)
- 数字
'0'~'9'< 大写字母'A'~'Z'< 小写字母'a'~'z'- 相同字符:继续比下一个
- 前面都相同:短字符串更小
2."=="运算符
如果
operator==只写成 string 的成员函数:
- 只能支持:
string 对象 == 其他类型✅str == "abc"- 完全不支持:
其他类型 == string 对象❌"abc" == str编译报错!原因只有一句话:*成员函数的左操作数,必须是当前类(string)的对象,不能是别的类型(如 const char)。**
bool string::operator==(const string& other) const { return 内容相等; } s1 == s2 s1.operator==(s2) "hello" == s "hello".operator==(s)//错误 "hello" 是 const char*,不是 string,根本没有 operator== 成员函数。如果要使用,可以使用全局非成员函数。
题目练习
1.反转字符串2
541. 反转字符串 II
https://leetcode.cn/problems/reverse-string-ii/
给定一个字符串
s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符,再重新计数。
- 如果剩余字符少于
k个,则将剩余字符全部反转。- 如果剩余字符小于
2k但大于或等于k个,则反转前k个字符,其余字符保持原样题解:
版本一:
class Solution { public: string reverseStr(string s, int k) { if (s.size() <= k) { reverse(s.begin(), s.end()); return s; } if (s.size() < 2 * k) { reverse(s.begin(), s.begin() + k); return s; } int x = 2, xx = 0; if (s.size() >= 2 * k) { reverse(s.begin(),s.begin()+k); string::iterator it; for (it = s.begin()+k; it != s.end(); ++it) { if (xx == (x-1) * k) { if(it+k<=s.end()) { reverse(it, it + k); x += 2; } else reverse(it,s.end()); } xx++; } } return s; } };版本二:
class Solution { public: string reverseStr(string s, int k) { for (int i = 0; i < s.size(); i += 2 * k) { int end = min(i + k, (int)s.size()); reverse(s.begin() + i, s.begin() + end); } return s; } };
2.反转字符串中的单词
给定一个字符串
s,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。题解:
class Solution { public: string reverseWords(string s) { char* left=&s[0],*right=&s[0]; for(int aim=2;aim<=s.size();aim++) { right++; if(*right==' ') { reverse(left,right); left=right; left++; } } reverse(left,right+1); return s; } };扩展:
class Solution { public: string reverseWords(string s) { istringstream iss(s); // 构建字符串流 string word; string result = ""; 复制 while (iss >> word) { // 流会自动以空格为界读取单词 reverse(word.begin(), word.end()); // 反转当前单词 result += word + " "; // 拼接到结果,加个空格 } // 去掉最后多余的那个空格,并返回 return result.substr(0, result.length() - 1); }
3.找出字符串中第一个只出现一次的字符
对于给定的字符串,找出第一个只出现一次的字符。如果不存在,则输出 −1−1。
在一行上输入一个长度为 1≦len(s)≦1031≦len(s)≦103、仅由小写字母构成的字符串 ss。
如果存在只出现一次的字符,输出第一个满足条件的字符;否则,直接输出 −1−1。
题解:
版本一:
#include <iostream> #include <string> using namespace std; int main() { string str; while (getline(cin, str)) { for (int i = 0; i < str.size(); i++) { if (str.find_first_of(str[i]) == str.find_last_of(str[i])) { cout << str[i] << endl; break; } if (i == str.size()-1) cout << -1<<endl; } } return 0; }版本二:
#include <iostream> using namespace std; int main() { int arr[26]={0}; string s; cin>>s; for(auto ch:s) { arr[ch-'a']++; } for(auto ch:s) { if(arr[ch-'a']==1) { cout<<ch<<endl; return 0; } } cout<<-1<<endl; return 0; }

