【C/C++刷题集】string类

C/C++ 刷题集:string 类常见考点与高频题型(2025-2026面试/比赛视角)

string 是 C++ 中使用频率最高的标准库类之一,也是面试和算法比赛中最容易踩坑的地方之一。

下面按照难度递增 + 考察频率的顺序整理 string 相关的高频考点和典型题目类型,适合快速查漏补缺或系统复习。

一、基础但极易出错的考点(必须0失误)

序号考点典型错误写法正确/推荐写法考察频率
1string + char* / chars += “hello”; s = s + ‘a’;s += ‘a’; s.push_back(‘a’);★★★★★
2string::npos 的类型if(s.find(“x”) == -1)if(s.find(“x”) == string::npos)★★★★★
3substr(start, len) vs substr(pos)s.substr(5) 以为取后面所有s.substr(5) 就是从5到末尾,长度可省略★★★★
4字符串比较大小(字典序)s1 > s2直接用 < > == != 即可(按字典序)★★★★
5清空 string 最快的方式s = “”; s.clear();s.clear(); 或 s = string();★★★
6reserve() 和 capacity() 的关系reserve(100) 后 size()==100reserve 只影响 capacity,size 不变★★★★
7at() vs operator[]s[100](越界未定义行为)s.at(100) 会抛异常,[] 不检查★★★★

二、高频算法题型 & 典型代码模板(比赛/面试必备)

1. 字符串查找与统计类(出现频率最高)

// 统计子串出现次数(可重叠/不可重叠两种写法)
int count_substr(const string& s, const string& t, bool overlap = false) {
    int cnt = 0, pos = 0;
    while ((pos = s.find(t, pos)) != string::npos) {
        cnt++;
        pos += overlap ? 1 : t.length();
    }
    return cnt;
}

2. 字符串分割(最常考,手写 split)

// 方法1:istringstream(最常用,面试最稳)
vector<string> split(const string& s, char delim = ' ') {
    vector<string> res;
    istringstream iss(s);
    string token;
    while (getline(iss, token, delim)) {
        if (!token.empty()) res.push_back(token);
    }
    return res;
}

// 方法2:find + substr(不依赖流,性能更好)
vector<string> split2(const string& s, char delim) {
    vector<string> res;
    size_t start = 0;
    while (true) {
        size_t end = s.find(delim, start);
        if (end == string::npos) {
            res.push_back(s.substr(start));
            break;
        }
        res.push_back(s.substr(start, end - start));
        start = end + 1;
    }
    return res;
}

3. 字符串替换(全部替换 / 部分替换)

// 全部替换(推荐写法)
string& replace_all(string& s, const string& from, const string& to) {
    size_t pos = 0;
    while ((pos = s.find(from, pos)) != string::npos) {
        s.replace(pos, from.length(), to);
        pos += to.length();
    }
    return s;
}

4. 去除首尾空白 / 全部空白

// C++11 后推荐写法(trim)
string trim(const string& str) {
    size_t first = str.find_first_not_of(" \t\n\r\f\v");
    if (first == string::npos) return "";
    size_t last = str.find_last_not_of(" \t\n\r\f\v");
    return str.substr(first, last - first + 1);
}

// 去除所有空白(erase-remove idiom)
s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());

5. 字符串转数字 & 数字转字符串(安全写法)

// string → int/long/double(推荐)
int    to_int   (const string& s) { return stoi(s);   }
long   to_long  (const string& s) { return stol(s);   }
double to_double(const string& s) { return stod(s);   }

// 带异常处理版本(生产常用)
optional<long long> safe_stoll(const string& s) {
    try {
        size_t pos;
        long long val = stoll(s, &pos);
        if (pos != s.size()) return nullopt; // 后面有非法字符
        return val;
    } catch (...) {
        return nullopt;
    }
}

// 数字 → string(C++11 后首选 to_string)
string num2str = to_string(12345) + "." + to_string(3.14);

三、LeetCode / NowCoder / 面试高频 string 题目(分类)

简单 / 基础类

  • 剑指 Offer 05. 替换空格
    1. 反转字符串
    1. 反转字符串 II
    1. 有效的字母异位词
    1. 最长回文串

中等 / 字符串模拟

  • 3. 无重复字符的最长子串(滑动窗口)
  • 5. 最长回文子串(中心扩展 / Manacher / DP)
  • 8. 字符串转换整数 (atoi)(边界最多)
    1. 字母异位词分组
    1. 反转字符串中的单词(或剑指 Offer 58 – I)
    1. 找到字符串中所有字母异位词
    1. 回文子串(计数)

较难 / 构造 / KMP / 字符串哈希

    1. 正则表达式匹配
    1. 通配符匹配
    1. 最长有效括号
    1. 最小覆盖子串
    1. 最短回文串(KMP)
    1. 回文对
    1. 密钥格式化

四、string 面试/比赛最常被问到的 trick & 易错点

  1. s += s[i] 连续拼接 → 可能产生二次分配,建议用 reserve
  2. string s = "abc" + 'd'; 合法,但 char c = 'd'; s = "abc" + c; 非法
  3. find() 从 0 开始,rfind() 从后往前
  4. append() / push_back()+= 更高效(尤其循环中)
  5. C++20 starts_with / ends_with / contains(非常方便)
  6. string_view(C++17)在只需要只读子串时性能更好

有哪一类题目或哪个具体题目你想看详细题解 + 多种写法对比(比如最长回文子串的五种解法、atoi 的边界处理、KMP 模板等),可以直接告诉我~

文章已创建 4791

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部