字符串从入门到精通

登录以参加训练计划

以下是针对 CSP-J 字符串算法 的详细解析与例题讲解,帮助您系统掌握相关知识点:


一、字符串基础操作

1. 字符串输入输出

  • C风格字符数组

    #include <cstdio>
    char str[100];
    scanf("%s", str);  // 输入(遇空格终止)
    printf("%s", str);
    

    注意scanf 会自动添加结束符 \0

  • C++ string类

    #include <string>
    #include <iostream>
    using namespace std;
    
    string s;
    cin >> s;         // 输入(遇空格终止)
    getline(cin, s);  // 输入整行(包含空格)
    cout << s;
    

2. 字符串遍历

  • 下标遍历
    for (int i = 0; i < s.size(); i++) {
        cout << s[i];  // 访问字符
    }
    
  • 范围遍历(C++11)
    for (char c : s) {
        cout << c;
    }
    

二、常用字符串函数

函数 功能 示例
s.size() / s.length() 返回字符串长度 int len = s.size();
s.substr(pos, len) 提取子串(从pos开始,长度len s.substr(2,3) → 第2字符起取3个
s.find(str) 查找子串位置,未找到返回string::npos if(s.find("abc") != string::npos)
s.replace(pos, len, str) 替换子串 s.replace(0,2,"xyz")

三、常见字符串算法

1. 回文判断

思路:双指针法,从两端向中间比较。

bool isPalindrome(string s) {
    int left = 0, right = s.size() - 1;
    while (left < right) {
        if (s[left] != s[right]) return false;
        left++; 
        right--;
    }
    return true;
}

2. 统计字符出现次数

int countChar(string s, char target) {
    int cnt = 0;
    for (char c : s) {
        if (c == target) cnt++;
    }
    return cnt;
}

3. 字符串反转

方法1:使用标准库函数:

reverse(s.begin(), s.end());

方法2:手动交换字符:

int n = s.size();
for (int i = 0; i < n/2; i++) {
    swap(s[i], s[n - i - 1]);
}

四、经典例题解析

例题1:字符替换

题目:将字符串中所有的小写字母 a 替换为 @

string s = "apple and banana";
for (char &c : s) {  // 引用修改原字符
    if (c == 'a') c = '@';
}
cout << s;  // 输出 "@pple @nd b@n@n@"

例题2:子串查找(CSP-J 2021 模拟题)

题目:统计字符串 s"CSP" 出现的次数。

string s = "CSP-J CSP-S CSP考试";
int cnt = 0, pos = 0;
while ((pos = s.find("CSP", pos)) != string::npos) {
    cnt++;
    pos += 3;  // 跳过已匹配部分
}
cout << cnt;  // 输出3

例题3:密码强度检测

题目:判断密码是否满足以下条件:

  1. 长度 ≥8;
  2. 包含至少一个大写字母;
  3. 包含至少一个数字。

代码实现

bool checkPassword(string pwd) {
    if (pwd.size() < 8) return false;
    bool hasUpper = false, hasDigit = false;
    for (char c : pwd) {
        if (isupper(c)) hasUpper = true;
        if (isdigit(c)) hasDigit = true;
    }
    return hasUpper && hasDigit;
}

五、易错点总结

  1. 越界访问:使用下标时确保 i < s.size()
  2. 忘记\0:C风格字符串操作需预留结束符空间。
  3. 混合输入cin >> n; getline(cin, s); 需清空缓冲区:
    cin.ignore();  // 忽略残留的换行符
    

六、练习题

  1. 反转单词顺序:输入一行句子,反转每个单词的顺序(如 "hello world""world hello")。
  2. 最长连续字符:找出字符串中最长的连续相同字符段(如 "aaabbcc"'a' 出现3次)。
  3. 字符串压缩:将连续重复字符压缩(如 "aaabbbcc""a3b3c2")。

参考答案可参考后续更新或联系作者获取。掌握这些内容后,字符串类题目将迎刃而解! 🚀

章节 1. string基础

开放

题目 尝试 AC 难度
1997   【入门】时间的差! 2 2 10
1908   【入门】数字和 4 3 10
1922   【基础】国王的魔镜 6 3 10
P363   【入门】简单加密 1 1 10
P456   【基础】找字典码最小的字符串 4 3 10
P451   【入门】字符串对比 0 0 (无)
P454   【入门】出现次数最多的小写字母 2 2 10
2127   【入门】判断是否构成回文 1 1 10
1998   【入门】字符串中的空格移位 0 0 (无)
1915   【基础】删除字符串中间的* 2 2 10
1921   【入门】字符串的反码 0 0 (无)
2113   【入门】看完动漫要几天? 0 0 (无)
2123   【基础】时钟旋转(2) 0 0 (无)
P378   【入门】字符串加密 0 0 (无)

章节 2. string常见函数

开放

题目 尝试 AC 难度
P560   【入门】求子串的位置 0 0 (无)
1909   【入门】调换位置 0 0 (无)
2198   【基础】字符串连接 0 0 (无)
P353   【提高】循环赛日程表 0 0 (无)
1919   【入门】删除指定字符 0 0 (无)
P542   【入门】字符替换 0 0 (无)
2000   【入门】查找子串并替换 0 0 (无)
P452   【基础】字符串编辑 0 0 (无)
2160   【入门】统计字符的个数 2 1 10
P384   【入门】合法的变量名 4 0 10
1989   【基础】重新排列 0 0 (无)
P541   【入门】字符串分离 0 0 (无)
P434   【入门】粉碎数字 0 0 (无)
P427   【入门】n个一位数能够组成的最大数 1 1 10
P428   【入门】n个一位数能够组成的最小数 1 0 10
1991   【基础】整数串拆段 0 0 (无)
1907   【基础】趣味填空 0 0 (无)
1918   【入门】简单a*b 1 1 10
1992   【入门】简单a+b 1 1 10
P301   【基础】表达式的值(III) 1 1 10

章节 3. string进阶问题

开放

题目 尝试 AC 难度
2185   【入门】词组缩写 0 0 (无)
2196   【基础】字符串压缩 0 0 (无)
2137   【基础】我是第几个单词 0 0 (无)
2005   【基础】整数的拼接 0 0 (无)
P312   【提高】分数计算 0 0 (无)
2199   【入门】统计单词个数 0 0 (无)
1988   【基础】找最长单词 0 0 (无)
1906   【基础】隐藏的最大整数 0 0 (无)
2197   【基础】字符串解压 0 0 (无)
1920   【入门】保留整数 0 0 (无)
1914   【基础】计算表达式 0 0 (无)
1990   【基础】表达式的值II 0 0 (无)
P315   【提高】求多个分数的和 0 0 (无)
 
参加人数
3
创建人