C++信奥:字符串的操作及应用方法

这一章《字符类型和字符数组》是信奥赛的基石。在 CSP-J/S 中,字符串处理(模拟、解析、加密)是必考题型。


🚀 C++ 信奥赛笔记:字符串

🌟 第一课:charstring

1. 什么是字符?

如果把一句话比作一串糖葫芦,那么每一颗山楂就是一个字符(char)

  • 定义: char c = 'A'; (注意:必须用单引号 ' ' 包裹,且只能放一个东西)
  • ASCII 码的秘密: 计算机里,字符其实是数字!
    • 'A' 是 65,'a' 是 97,'0' 是 48。
    • 口诀: 小写比大写大 32('a' - 'A' = 32)。
    • 应用: 【例5.15】替换字母、【例5.18】串排序都要用到这个规律。

2. 两种武器:数组 vs string

  • 老式武器 char s[100] 像一排固定的格子,操作快但容易越界(比如 P1098 这种老题)。
  • 新式武器 string s 像橡皮筋,能长能短,自带很多功能(推荐初学者用这个)。

🛠️ 第二课:基本功训练(必会操作)

1. 怎么读入一整行?

孩子最容易踩的坑:cin 遇到空格就停了!

  • 场景: 【例5.16】过滤空格、【例5.19】字符串判等。
  • 神器: getline(cin, s);
    • 它可以读入包含空格的整行文字。
    • 注意: 如果前面用了 cin >> n;,后面接 getline,中间要加一句 getchar(); 吃掉回车键!

2. 怎么知道有多长?

  • s.length()s.size()
  • 应用: 遍历字符串时,循环条件写 i < s.length()

3. 大小写转换魔法

  • 题目: 【例5.15】替换字母、P1138 将字符串中的小写字母转换成大写字母。
  • 代码公式:
    • 变大写:c = c - 32;
    • 变小写:c = c + 32;
    • 判断是不是字母:if (c >= 'a' && c <= 'z')

⚔️ 第三课:实战演练(结合一本通题目)

将题目分为三个等级

🟢 青铜级:单字符操作

目标: 熟悉 ASCII 码和循环遍历。

  1. 【例5.15】替换字母
    • 思路: 遍历每一个字符,如果是 'A' 就改成 'E'。
    • 考点: if(s[i] == 'A') s[i] = 'E';
  2. P1138 将字符串中的小写字母转换成大写字母
    • 思路: 遍历,如果是小写(>= 'a'),就减去 32。
  3. P1146 判断字符串是否为回文
    • 思路: "回文"就是正着读反着读一样(如 abcba)。
    • 技巧: 用两个指针,一个从头 i=0,一个从尾 j=len-1,向中间靠拢比较。

🟡 白银级:子串与查找

目标: 学会"切片"和"搜索"。

  1. 【例5.20】字串包含
    • 问题: 字符串 A 里面有没有字符串 B?
    • 神器函数: s.find("abc")。如果返回值不是 string::npos,说明找到了!
  2. P1140 验证子串
    • 同上: 练习 find 函数的使用。
  3. P1141 删除单词后缀
    • 思路: 看看最后几个字符是不是 "ing", "ly", "er"。如果是,就把它们切掉(s.erase(...)s.substr(...))。
  4. P1142 单词的长度
    • 思路: 找空格!遇到空格说明一个单词结束了,统计长度并重置计数器。

🔴 黄金级:综合应用与逻辑

目标: 结合数学逻辑或复杂规则。

  1. 【例5.18】串排序
    • 难点: 字典序排序(先比第一个字母,一样再比第二个...)。
    • 解法: 直接用 sort(v.begin(), v.end())vector<string> 排序,C++ 默认就是字典序!
  2. P1132 基因相关性
    • 思路: 这是一个统计题。遍历两个字符串,数一数有多少个位置字符相同,算出比例。
  3. P1136 配对碱基链
    • 思路: 映射关系。A-T, G-C。遍历字符串,用 if-else 或者 switch 进行转换输出。
  4. P1145 字符串p型编码
    • 思路: 游程编码(RLE)。比如 aaabbc -> 3a2b1c。需要记录当前字符和它连续出现的次数。

💡 小贴士(避坑指南)

  1. 关于 char 数组的结束符 \0
    • C 风格字符串最后藏着一个看不见的"小尾巴" \0。所以定义数组时,长度要比实际文字多 1。例如存 "Hi" 需要 char s[3]
  2. 关于下标越界:
    • 字符串长度是 len,最后一个字符的下标是 len-1。这是新手最容易报错的地方(Runtime Error)。
  3. 关于调试:
    • 在循环里打印 is[i],看看程序到底在读什么,这比干瞪眼有效得多。

📝 课后作业清单(建议顺序)

  1. P1138 大小写转换(热身)
  2. P1146 回文串判断(经典逻辑)
  3. P1140 验证子串(学习 find)
  4. P1141 删除后缀(学习 substr/erase)
  5. P1132 基因相关性(综合统计)
  6. P1145 p型编码(挑战题)

C++ 字符串教学内容和常见操作方法可归纳为两大体系:C 风格字符数组与标准库 std::string,其中后者是信奥赛和工程实践中的主流选择。建议以 string 为主线,辅以字符数组基础概念

一、注意点

  1. 字符与字符串的本质

    • 字符是单个符号(如 'A''1'),用单引号包裹;字符串是字符序列,用双引号包裹。
    • 计算机中字符本质是数字(ASCII 码),例如 'A' = 65'a' = 97,小写比大写大 32。这是大小写转换、字母排序等题目的底层逻辑。
  2. 两种字符串表示法

    • C 风格字符数组:char s[100] = "Hello";,以 \0 结尾,需手动管理长度和边界,适合理解底层原理。
    • std::stringstring s = "Hello";,自动管理内存,支持动态扩容,内置丰富方法,是竞赛首选。
  3. 输入输出陷阱

    • cin >> s 遇到空格/换行即停止,适用于单单词输入。
    • getline(cin, s) 可读取整行含空格的文本,但若前文有 cin >> n,需加 getchar() 吃掉残留换行符,否则 getline 会读入空行。
  4. 常用操作方法

    • 基础属性s.length()s.size() 获取长度;s.empty() 判断是否为空。
    • 访问与修改s[i]s.at(i) 访问第 i 个字符(从 0 开始);s.push_back('x') 尾部追加字符;s.insert(pos, "abc") 在位置 pos 插入子串。
    • 拼接与替换s1 + s2s1.append(s2) 拼接;s.replace(start, len, "new") 替换从 start 开始、长度为 len 的子串。
    • 查找与截取s.find("abc") 返回子串首次出现位置(未找到返回 string::npos);s.substr(start, len) 提取子串。
    • 比较与清空s1 == s2 直接比较内容;s.clear() 清空字符串。
  5. 高频考点题型

    • 大小写转换 :遍历字符串,若字符在 'a'-'z' 范围,则减去 32 转为大写。
    • 回文判断:首尾双指针向中间逼近,比较对应字符是否相等。
    • 子串匹配 :用 find() 或手动滑动窗口实现。
    • 词频统计 :结合 map<string, int> 统计每个单词出现次数。
    • 加密解密:如凯撒密码,对每个字符按固定偏移量变换。

二、避坑指南

  • 避免过早引入指针 :无需理解 char*,聚焦 string 即可。
  • 警惕越界访问 :强调 s[i] 的 i 必须小于 s.length(),否则行为未定义。
  • 慎用 c_str() :仅在调用 C 风格函数(如 printf)时才需转换,日常操作用 string 原生方法。
  • 注意 find() 返回值 :未找到时返回 string::npos(通常为 -1 或极大值),不可直接与 0 比较。

找我领一份「学生速查表」~

相关推荐
hansang_IR2 小时前
【题解】LC:Z 算法(Z Algorithm)
c++·算法·字符串
Zane19943 小时前
CAS 与原子类:Java 如何实现无锁编程
java·后端
TunerT_TQ3 小时前
【智能体安全治理|专栏第9期】从“一堆规则”到“数字宪法”:智能体治理的下一个阶段
java·开发语言·安全·开源治理·大模型安全·ai基础设施·智能体安全
legendary_bruce3 小时前
RAG知识库进阶-1
java·aigc
必须会一定会3 小时前
大模型手搓文件对比工具(6):差异不用再手选
java·人工智能·ai编程
yio_yin3 小时前
MyBatis
java·前端·mybatis
程序员-Benothing3 小时前
Java ForkJoinPool 详解:从分治思想到高性能并行计算
java·开发语言·后端·面试·职场和发展
上海安当技术4 小时前
单点登录 SSO 怎么选协议?SAML 2.0 / OAuth 2.0 / OIDC / CAS 对比与 ERP、OA、CRM 接入实战
java·开发语言
mifengxing4 小时前
Java集合与泛型
java·算法·复习笔记
不才不才不不才4 小时前
Spring 源码系列(14): JDK 动态代理 vs CGLIB,以及拦截器责任链
java·开发语言·spring