【C/C++刷题集】string类(一)

【C/C++刷题集】string类(一)
🫧个人主页:小年糕是糕手

💫个人专栏:《C++》《Linux》《数据结构》《C语言》

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!


目录

一、字符串最后一个单词的长度

二、验证回文串

三、字符串中的第一个唯一字符

四、反转字符串


一、字符串最后一个单词的长度

字符串最后一个单词的长度

这里我们看题目有一个注意点就是我们平常使用cin输入时遇到空格会停下来,在例子中我们可以看到他有A B C D,如果我们使用cin在遇到第一个A之后就会报错,所以这里我们要用到另一种输入方式:getline

他并不是一个成员函数,而是输入流的全局函数 getline(istream&, string&)(定义在 <string> 头文件中),作用是从输入流中读取一整行内容,存入 string 对象

// 基础用法(读整行) getline(输入流对象, string对象); // 扩展用法(读至指定终止符) getline(输入流对象, string对象, 终止字符);

思路:我们要读取最后一个单词的长度,大家肯定会想到我们从第一个字母开始遍历,遇到空格就跳过并且记录一下,直到遍历完整个字符串,然后我们就可以知道了有几个空格,找到最后一个空格所处的位置,然后记录下最后一个单词的长度即可,这确实是个可行的方法,但是过程过于冗余了,我们可以利用string类中重载的一个成员函数rfind:

rfind(' ')从字符串末尾往前找第一个空格的位置;如果找到空格:最后一个单词的长度 = 字符串总长度 - (空格位置 + 1)(因为空格的下一个位置是最后一个单词的开头);如果没找到空格(整个字符串是一个单词):最后一个单词的长度 = 字符串总长度

下面我们写代码前再去简单了解一下rfind成员函数:

string类的rfind从字符串末尾向前查找指定内容的成员函数,返回匹配内容的起始下标(若未找到则返回string::npos),常用于定位最后一次出现的字符 / 子串。参数 1:要查找的子串 / 字符(支持stringchar*char);参数 2:查找的结束位置(默认是string::npos,即从字符串末尾开始找);返回值:匹配内容的起始下标;未找到则返回string::npos(一个代表 “无位置” 的常量)
#include<iostream> #include<string> using namespace std; int main() { string str; //cin >> str; //cin检测到空格或换行就会结束,我们这里要使用getline成员函数 getline(cin, str); size_t pos = str.rfind(' '); //找到最后一个空格所处位置 //这里if里面的条件表示没有没找到 -- 找到了 if (pos != string::npos) { cout << str.size() - (pos + 1) << endl; } else { cout << str.size() << endl; } return 0; } 
string::npos 是 C++ std::string 类里的一个静态常量,核心含义是「无效的位置 / 未找到匹配内容」—— 专门用来标记 find/rfind 等查找函数 “没找到目标” 的返回值。



❌ 错误用法:用 pos == -1 判断(因为 size_t 是无符号类型,-1 会被转换成 npos 的值,但写法不规范,且容易出错);

✅ 正确用法:必须用 pos != string::npos 判断 “是否找到”,pos == string::npos 判断 “没找到”。

二、验证回文串

验证回文串

思路:我们主要就是去处理将大写字母转换成小写字母并且将非字母数字的字符全部过滤掉,然后得到一个串,我们知道string定义的一个串是有下标的,这时候我们就可以利用双指针法去遍历这个串判断是否回文

这其实我们可以使用一些函数来帮助我们实现,但是目前阶段我们还是主要看逻辑所以不用这些函数:

class Solution { public: bool isPalindrome(string s) { // 步骤1:过滤+转换(纯ASCII判断,无库函数) string blank_string;//定义了一个空串 for (auto ch : s) { // 判断是否是大写字母 if (ch >= 'A' && ch <= 'Z') { // 大写转小写(ASCII+32) blank_string += ch + 32; } // 判断是否是小写字母 else if (ch >= 'a' && ch <= 'z') { blank_string += ch; } // 判断是否是数字字符 else if (ch >= '0' && ch <= '9') { blank_string += ch; } // 非字母/数字:自动跳过(不加入blank_string) } // 步骤2:双指针验证回文(无库函数依赖) int left = 0; int right = blank_string.size() - 1; while (left < right) { if (blank_string[left] != blank_string[right]) { return false; } left++; right--; } return true; } };

三、字符串中的第一个唯一字符

字符串中的第一个唯一字符

思路:我们要找的是一个字符串,且他告诉我们了这个串只有小写字母,那我们不妨定义一个数组,首先全部初始化为0,然后使用范围for遍历字符串,将每个字母对应存在数组中,统计次数,然后我们就可以通过遍历数组找到数组中第一个出现次数为1的字符并且返回且索引,没有就返回-1

class Solution { public: int firstUniqChar(string s) { //步骤1:统计每个小写字母的出现次数(数组索引对应字符,值对应次数) int count[26] = {0}; // 初始化为0(26个字母) for (char ch : s) { count[ch - 'a']++; // 'a'对应索引0,'b'对应1,以此类推 } // 步骤2:遍历原字符串,找第一个出现次数为1的字符 for (int i = 0; i < s.size(); i++) { if (count[s[i] - 'a'] == 1) { return i; // 返回索引 } } // 步骤3:无唯一字符,返回-1 return -1; } };

四、反转字符串

反转字符串

思路:这其实是这几个题目中最简单的一个,但是题中出现了vector我怕大家不认识就放到了最后,大家先不关注,就当他也是string使用就好了,后续的博客会为大家细致讲解,这题其实不看这个很简单,我们只需要找到最后一个字符位置,和头字符位置互换即可,然后一个++,一个--即可解决问题,这里我们唯一需要注意的就是我们交换的时候可以使用string类中我们说过的swap成员函数:

class Solution { public: void reverseString(vector<char>& s) { if (s.empty()) return; int start = 0; int end = s.size() - 1; while (start < end) { swap(s[start], s[end]); start++; end--; } } };

Read more

季节-趋势分解(STL)方法详解

季节-趋势分解(STL)方法详解

季节-趋势分解(STL)方法详解 在分析时间序列数据时,我们经常需要理解数据中隐藏的规律。比如零售商想知道销售额的增长是真实的业务增长还是仅仅是季节性因素,气候学家需要从温度数据中分离出长期变暖趋势和正常的季节变化,这些都需要一种强大的分解方法。STL(Seasonal and Trend decomposition using Loess)正是为此而生的统计方法,它能够将复杂的时间序列数据优雅地分解为三个易于理解的组成部分:趋势、季节性和余项。 数学原理与核心思想 STL的核心思想非常直观:任何时间序列都可以表示为三个加法组成部分的和。用数学公式表达就是: Yν=Tν+Sν+RνY_\nu = T_\nu + S_\nu + R_\nuYν =Tν +Sν +Rν 其中YνY_\nuYν 代表在时间ν\nuν的观测值,TνT_\nuTν 是趋势分量,SνS_\nuSν 是季节分量,RνR_\nuRν 是余项分量。

By Ne0inhk
C++ 继承入门(上):从基础概念定义到默认成员函数,吃透类复用的核心逻辑

C++ 继承入门(上):从基础概念定义到默认成员函数,吃透类复用的核心逻辑

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》 《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心 ✨未择之路,不须回头 已择之路,纵是荆棘遍野,亦作花海遨游 目录 前言 一. 继承的概念与定义   1、继承的核心概念   2、继承的定义格式   3、继承方式与成员访问权限 二. 基类与派生类的转换:子类对象能当父类用吗? 三. 继承中的作用域:同名成员会冲突吗?   1、变量隐藏   2、函数隐藏 四、派生类的默认成员函数:构造、拷贝、析构怎么写?   1、构造函数:先调用父类构造,再初始化子类成员   2、拷贝构造:先拷贝父类,再拷贝子类   3、 赋值重载:

By Ne0inhk
JavaScript 事件循环(Event Loop)

JavaScript 事件循环(Event Loop)

JavaScript 事件循环(Event Loop) * 什么是事件循环? * 核心概念 * 1. 调用栈(Call Stack) * 2. 任务队列(Task Queue) * 3. 执行顺序 * 初等难度练习题 * 解题顺序 * 中等难度练习题 * 题目要求 * 答案解析 * 详细执行过程 * 关键点总结 * 实际应用场景 * 1. 优化性能 * 2. 确保执行顺序 * 3. 避免阻塞 * 常见面试问题 * 参考资源 什么是事件循环? 事件循环是JavaScript实现异步编程的核心机制。JavaScript是单线程语言,通过事件循环来处理异步操作,避免阻塞主线程。 详解: JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事。 为什么要这么设计,跟JavaScript的应用场景有关 JavaScript 初期作为一门浏览器脚本语言,通常用于操作 DOM ,如果是多线程,

By Ne0inhk

在 Windows 上实现多 JDK 快速切换方案

在 Windows 系统中管理多个 JDK 版本时,手动修改环境变量效率较低。本文介绍一种通过 .bat批处理脚本结合 JAVA_HOME 变量联动机制实现一键切换 JDK 的高效方法。觉得文章冗余,不利于快速解决问题,可将本文提供给AI总结处理,快速且高效 该方案的核心思想是:利用系统环境变量 %JAVA_HOME% 的动态指向,配合批处理脚本自动修改其值,从而快速切换不同版本的 JDK。 第一步:调整环境变量顺序(关键) 为了确保 %JAVA_HOME% 能正确生效并被优先识别,必须将其路径设置为环境变量中的第一个条目。 操作步骤: 1. 打开“环境变量编辑窗口”(可通过“此电脑 → 属性 → 高级系统设置 → 环境变量”进入)。 2. 在“系统变量”区域找到 Path 变量,点击“

By Ne0inhk