首页/新闻资讯/正文详情

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

发布时间:2026/11/4 18:18:36 来源:云帆数科 栏目:资讯中心
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遍历 累积空字段语义字符串题目的共同点是「边界比算法多」。写之前先把输入输出约定列清楚空串怎么处理、是否忽略大小写、是否保留空字段、溢出时返回什么。把这些约定写进注释再动手实现比写完再补边界要可靠得多。

相关推荐

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

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

Ajax技术解析:从原理到现代Web开发实践
Ajax技术解析:从原理到现代Web开发实践

1. 项目概述:Ajax技术在现代Web开发中的核心地位2005年,当Google Suggest和Google Maps首次展示出无需刷新页面就能动态更新内容的能力时,整个Web开发领域迎来了革命性的转折点。作为这场革命的核心技术,Ajax(Asynchro… · 2026/11/4 18:17:35

ARTEMIS:移动端AI操作的OS级范式切换
ARTEMIS:移动端AI操作的OS级范式切换

1. ARTEMIS不是另一个“手机遥控器”,它是AI操作手机的底层范式切换 你有没有试过让AI帮你点开微信、翻到昨天的聊天记录、截图发给同事?市面上大多数方案要么靠录屏回放,要么靠OCR识别文字再模拟点击——结果就是卡顿、错位、一换机型就失效… · 2026/11/4 18:17:35

DeepSeek V4.1 Flash 技术解读:轻量化 AI 模型的高效推理之道
DeepSeek V4.1 Flash 技术解读:轻量化 AI 模型的高效推理之道

1. 先说清楚:这个 V4.1 Flash 到底是什么来头 最近打开技术社区和聊天群,到处都是 DeepSeek V4.1 Flash、Flash Attention、Flash 这个 Flash 那个的讨论。我本来以为又是哪家厂商整了个营销新词,结果蹲了一圈消息源,发现这事比我… · 2026/11/4 21:10:13

MongoDB分片集群性能优化:Zone划分与读写分离实践
MongoDB分片集群性能优化:Zone划分与读写分离实践

1. MongoDB分片集群性能优化概述作为一名长期奋战在数据库运维一线的工程师,我见过太多团队在MongoDB分片集群使用初期表现良好,但随着数据量增长却陷入性能泥潭的案例。分片集群虽然提供了理论上无限的水平扩展能力,但如果不掌握正确的调优方… · 2026/11/4 21:10:13

深入解析STL容器:原理、实现与性能优化
深入解析STL容器:原理、实现与性能优化

1. STL容器概述与设计哲学 STL(Standard Template Library)作为C标准库的核心组成部分,其容器类模板的设计体现了泛型编程的精华。在实际工程中,我们经常直接使用vector、map这些容器,但真正理解它们的底层实现机制&am… · 2026/11/4 21:10:13

多智能体系统通信协议:MCP、A2A与ACP技术解析与应用
多智能体系统通信协议:MCP、A2A与ACP技术解析与应用

1. 多智能体系统协议演进背景在分布式人工智能领域,多智能体系统(MAS)的协同效率直接取决于通信协议的标准化程度。早期智能体间通信存在三大痛点:首先是协议碎片化导致跨平台协作困难,不同研究团队开发的智能体往往采用私有通信格式&#xf… · 2026/11/4 21:10:13

顺序表在通讯录项目中的工程实践与性能优化
顺序表在通讯录项目中的工程实践与性能优化

1. 顺序表基础与通讯录项目背景 顺序表作为数据结构中最基础的线性存储结构,在C语言中通常通过数组实现。我在处理嵌入式设备日志系统时首次深刻体会到它的价值——当需要快速存取固定格式的传感器数据时,顺序表相比链表能减少80%以上的访问时间。通讯录… · 2026/11/4 21:10:13

INCA汽车标定入门:安装、A2L/S19导入与CAN测量实操
INCA汽车标定入门:安装、A2L/S19导入与CAN测量实操

简介:《INCA标定软件使用教程》面向汽车标定初学者及需要熟悉INCA操作的汽车电子工程师,围绕软件安装、许可证配置、实验环境建立、标定工程设计与数据录制等环节展开,帮助读者理解A2L与s19文件导入、CAN设备连接、变量选取和示波器观察等基础… · 2026/11/4 21:09:12

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* 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 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* 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 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* 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 7:02:38

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

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

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

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

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

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

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* 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 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* 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 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* 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 7:02:38

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码