C++中String类常见题目分享

发布时间:2026/11/4 18:18:33

C++中String类常见题目分享 前言std::string相关的题目是笔试和面试的高频题型反转单词、判断回文、找第一个不重复字符、字符串转整数、去除空白、按分隔符切分。这些题单个看都不难但每个都有边界条件写错一处就会在隐藏用例上失败。常见的共性问题有三个。第一用std::string::npos时直接和int比较或者把npos当成 -1 用npos是size_type的最大值和int比较会发生符号转换。第二处理字符分类函数std::isalnum、std::isdigit、std::tolower时直接传char遇到负值就是未定义行为undefined behavior, UB。第三字符串转整数时没有处理溢出和前导空白或者把、-的位置判断错。本文挑五类常见题目每类给出一个 C17 的实现和边界说明。代码都只用标准库不依赖特定平台。一、反转字符串与反转单词最简单的「反转字符串」是原地交换首尾字符// 适用于 C17#include string#include utilityvoid reverseString(std::string s) {std::size_t i 0;std::size_t j s.size();while (i j) {--j;if (i j) break;std::swap(s[i], s[j]);i;}}j初始为size()先--j再交换避免访问s[size()]那个位置是末尾空字符虽然可读但不应该被交换。i j的判断处理了长度为偶数和奇数两种情况。「反转单词」要求把the sky is blue变成blue is sky the并且把多个连续空格压缩成一个。用std::istringstream按空白切分最省事// 适用于 C17#include sstream#include string#include vectorstd::string reverseWords(const std::string s) {std::istringstream iss(s);std::vectorstd::string words;std::string w;while (iss w) {words.push_back(w);}std::string result;for (auto it words.rbegin(); it ! words.rend(); it) {if (!result.empty()) result ;result *it;}return result;}iss w会跳过前导空白、在下一个空白处停止所以连续多个空格不会产生空单词。返回的字符串没有前导或尾随空格。时间 O(n)空间 O(n)。如果要求原地反转O(1) 额外空间做法是「先整体反转再逐个单词反转」同时处理多余空格。那种写法边界较多本文从略面试时要先问清楚是否允许额外空间。二、回文判断判断一个字符串是否为回文可以用双指针从两端向中间比较。如果忽略大小写和非字母数字字符需要先跳过它们// 适用于 C17#include cctype#include stringbool isPalindrome(const std::string s) {std::size_t i 0;std::size_t j s.size();while (i j) {while (i j std::isalnum(static_castunsigned char(s[i])) 0) {i;}while (i j std::isalnum(static_castunsigned char(s[j - 1])) 0) {--j;}if (i j) {const unsigned char a static_castunsigned char(s[i]);const unsigned char b static_castunsigned char(s[j - 1]);if (std::tolower(a) ! std::tolower(b)) return false;i;--j;}}return true;}关键点std::isalnum和std::tolower的参数必须是unsigned char提升后的值或EOF。直接传char如果char有符号且字符值大于 127会变成负数行为未定义。j从size()开始比较s[j-1]这样不会越界。跳过非字母数字后要重新判断i j否则可能已经把两个指针走到交叉。空字符串和只含非字母数字的字符串都返回true这符合「忽略这些字符后是回文」的语义如果题目要求空串返回false需要单独处理。三、第一个只出现一次的字符统计每个字符出现的次数再按原顺序找第一个计数为 1 的字符。字符集是char时用 256 个桶的数组即可// 适用于 C17#include array#include cstddef#include stringint firstUniqChar(const std::string s) {std::arrayint, 256 count{};for (char c : s) {count[static_castunsigned char(c)];}for (std::size_t i 0; i s.size(); i) {if (count[static_castunsigned char(s[i])] 1) {return static_castint(i);}}return -1;}std::arrayint, 256 count{};的值初始化会把所有元素置 0。下标用unsigned char转换保证落在 0 到 255。如果字符集是 Unicodechar的 256 个桶就不够了应该按 UTF-8 字节序列或码点处理通常需要额外的库。本文只讨论单字节字符集。如果要求「第一个不重复的字符」而不是下标把返回值改成char找不到时返回\0或抛异常并在文档里写清楚。四、字符串转整数实现一个类似std::stoi的函数要求跳过前导空白。可选的正负号。读取连续数字遇到非数字停止。超出int范围时返回INT_MAX或INT_MIN。没有数字时返回 0。// 适用于 C17#include cctype#include climits#include stringint myAtoi(const std::string s) {std::size_t i 0;while (i s.size() s[i] ) i;int sign 1;if (i s.size() (s[i] || s[i] -)) {if (s[i] -) sign -1;i;}long long value 0;while (i s.size() std::isdigit(static_castunsigned char(s[i])) ! 0) {const int digit s[i] - 0;value value * 10 digit;if (value 2147483648LL) {value 2147483648LL;break;}i;}if (sign 1 value 2147483647LL) return INT_MAX;if (sign -1 value 2147483648LL) return INT_MIN;return static_castint(sign * value);}边界说明只跳过空格 不跳过制表符和换行题目如果要求所有空白改用std::isspace。2147483648LL是INT_MAX 1用long long表示避免int溢出。一旦value超过2147483648就截断并跳出循环防止value * 10在超长输入上溢出long long。正数上限是2147483647负数下限是-2147483648两者不对称所以判断条件分开写。没有数字时value为 0返回 0符合常见约定。std::stoi的行为不同它在无法转换时抛std::invalid_argument越界时抛std::out_of_range。如果只是解析已知合法的输入用std::stoi更省事如果要实现题目要求的「饱和转换」就自己写。五、去除首尾空白与按分隔符切分去空白可以用find_first_not_of和find_last_not_of// 适用于 C17#include stringstd::string trim(const std::string s) {const std::string whitespace \t\n\r\f\v;const std::size_t begin s.find_first_not_of(whitespace);if (begin std::string::npos) return ;const std::size_t end s.find_last_not_of(whitespace);return s.substr(begin, end - begin 1);}find_first_not_of返回第一个不是空白字符的下标如果全是空白返回npos此时直接返回空串。find_last_not_of返回最后一个非空白字符的下标substr的长度是end - begin 1。按单个分隔符切分// 适用于 C17#include string#include vectorstd::vectorstd::string split(const std::string s, char delim) {std::vectorstd::string parts;std::string current;for (char c : s) {if (c delim) {parts.push_back(current);current.clear();} else {current c;}}parts.push_back(current);return parts;}这个实现会保留空字段a,,b切成{a, , b}a,切成{a, }。这通常是 CSV 解析想要的语义如果不想要空字段在push_back前判断!current.empty()但要注意这样会改变「连续分隔符」的含义。split每次current c可能导致多次重新分配。对长字符串可以先reserve或者在确定分隔符位置后用substr。对一般规模现代std::string的扩容策略已经足够。六、完整示例// 适用于 C17#include iostream#include string#include vectorstd::string trim(const std::string s) {const std::string whitespace \t\n\r\f\v;const std::size_t begin s.find_first_not_of(whitespace);if (begin std::string::npos) return ;const std::size_t end s.find_last_not_of(whitespace);return s.substr(begin, end - begin 1);}std::vectorstd::string split(const std::string s, char delim) {std::vectorstd::string parts;std::string current;for (char c : s) {if (c delim) {parts.push_back(current);current.clear();} else {current c;}}parts.push_back(current);return parts;}int main() {std::cout [ trim( hello world ) ]\n;std::cout [ trim( ) ]\n;for (const auto part : split(a,b,,c, ,)) {std::cout [ part ] ;}std::cout \n;return 0;}按标准语义trim( hello world )得到[hello world]trim( )得到[]split(a,b,,c, ,)得到[a] [b] [] [c]。常见坑点1. 字符分类函数直接传 char❌std::isalnum(s[i])当char有符号且字符值大于 127 时是 UB。✅std::isalnum(static_castunsigned char(s[i]))。2. 把 npos 当成 -1❌int pos s.find(x); if (pos -1) ...npos转成int可能是 -1也可能是其他值行为依赖实现。✅ 用std::string::npos比较类型用std::string::size_type或auto。3. 回文双指针越界❌std::size_t j s.size() - 1;对空串下溢成最大值。✅j s.size()访问s[j - 1]或先判断空串。4. 反转单词时保留多余空格❌ 直接按空格切分后拼接多个空格产生空单词结果里出现连续空格。✅ 用istringstream 自动跳过空白或手动压缩空格。5. 字符串转整数溢出❌int value value * 10 digit;超长输入时溢出UB。✅ 用long long累加超过INT_MAX 1就截断。6. 忘记处理正负号❌ 只判断-把当成非数字返回 0。✅ 同时接受和-并确保符号后至少有一位数字。7. split 对空字符串返回空 vector❌split(, ,)返回{}调用方按「至少一个字段」处理时越界。✅ 本文实现返回{}明确文档语义或按需过滤。8. 在 range-for 中修改字符串❌for (char c : s) { if (c ) s.erase(...); }迭代器失效。✅ 用下标 erase的正确循环或 erase-remove 惯用法。总结题目核心方法关键边界反转字符串双指针交换奇偶长度、空串反转单词按空白切分后逆序拼接多余空格回文判断双指针 跳过非字母数字unsigned char、指针交叉第一个唯一字符计数数组字符集大小、返回值约定字符串转整数逐位累加 饱和溢出、符号、前导空白trimfind_first/last_not_of全空白split遍历 累积空字段语义字符串题目的共同点是「边界比算法多」。写之前先把输入输出约定列清楚空串怎么处理、是否忽略大小写、是否保留空字段、溢出时返回什么。把这些约定写进注释再动手实现比写完再补边界要可靠得多。
延伸阅读

更多相关文章

2026/11/4 18:18:33

Kotlin协程与结构化并发在Android开发中的实践指南

1. 项目概述 作为一名在移动端开发领域深耕多年的工程师,我至今记得第一次接触异步编程时的痛苦经历。回调地狱、线程泄漏、状态同步等问题让本该简单的业务逻辑变得支离破碎。直到Kotlin协程的出现,才真正改变了这一局面。今天我们就来深入探讨这个让An…

2026/11/4 18:13:31

Oracle APEX 4.x 实战:从安装配置到 EBS 集成避坑指南

简介:面向Oracle数据库开发者与低代码平台学习者的APEX实战指南,帮助读者从零搭建环境并逐步掌握企业级Web应用开发。内容以一份doc文档承载,压缩包约8.11MB,围绕系统探究与开发两条主线展开:涵盖APEX简介、环境搭建、…

2026/11/4 18:13:31

RetroArch音频优化指南:驱动、采样率与延迟缓冲实战

1. 为什么RetroArch的音频总感觉“差口气”折腾RetroArch也有好几年了,从最早在树莓派上跑复古模拟,到后来在PC、手机、电视盒子上各种倒腾,我发现一个特别普遍的现象:很多人把画面滤镜调得贼精细,扫描线、CRT着色器一…

2026/11/4 20:09:03

PyCharm安装避坑指南:版本选择、路径规划与解释器绑定

简介:这份资源是一份面向 Python 初学者与刚接触 JetBrains 开发环境的用户的 PyCharm 安装配置文档,重点解决从官网下载安装包、选择安装目录与勾选组件,到完成软件激活的完整流程问题,适合零基础入门或需要重装环境的学习者参考…

2026/11/4 20:09:03

RBCADS 5.0:轴承参数化设计与工况驱动决策系统

简介:本资源为RBCADS 5.0滚动轴承计算机辅助设计系统官方技术文档,面向机械设计工程师、轴承研发人员及高校机电类专业师生,解决传统轴承设计周期长、参数优化难、图纸绘制繁琐等核心痛点。文档全面介绍该行业标杆级CAD软件的功能架构与工程价…

2026/11/4 20:09:03

SolidWorks Routing中文界面英文面板排查

简介:这份 docx 文档面向使用 SolidWorks Routing 进行管道与管路设计、却因界面显示英文而影响操作效率的工程师与自学者,聚焦 Routing 模块中英文界面切换这一常见问题,整理出可对照排查的解决思路。压缩包内仅含 1 个 docx 文件&#xff0…

2026/11/4 20:09:02

红酒数据集数据分析大作业:相关性、回归与KNN分类全流程

简介:围绕红酒数据集展开的数据分析大作业文档,面向统计学、数据科学课程学习者及需要完成课程设计的本科生,聚焦红酒评分影响因素与分类标准的建模分析。压缩包内共1个docx文件,约202KB,以实验报告形式组织&#xff0…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑