《牛刀小试!C++ string类核心接口实战编程题集》


🔥个人主页: K 旺仔小馒头

🍉学习方向:C/C++方向学习者

📖个人专栏:《C语言》《数据结构与算法》《C++知识分享》《C语言实战编程》

⭐️人生格言:‌"何时葡萄先熟透,你要静候再静候"



前言:

C++字符串处理是编程入门与进阶的关键环节,常涉及多种算法思维。本文聚焦4道经典字符串题,用双指针、哈希表等实用方法解题,搭配注释清晰的代码,助力你吃透字符串操作逻辑,提升算法应用能力。


一. 仅仅反转字母【难度:简单】

描述:

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s

知识点:

以后交换不需要自己写了,库里面直接写了一个函数模板,直接用,任何类型都可以交换

cpp 复制代码
class Solution {
public:
    bool isLetter(char ch)
    {
        if(ch >= 'a' && ch <= 'z')
            return true;
        if(ch >= 'A' && ch <= 'Z')
            return true;

        return false;
    }
    string reverseOnlyLetters(string s) {
        size_t begin = 0,end = s.size()-1;
        while(begin < end)
        { 
            while(begin < end && !isLetter(s[begin]))
            {
                ++begin;
            }
            while(begin < end && !isLetter(s[end]))
            {
                --end;
            }

            swap(s[begin],s[end]);
            ++begin;
            --end;
        }
        return s;
    }
};

二. 字符串中的第一个唯一字符【难度:简单】

描述:

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1

知识点:

string这个部分,真要遍历,要么用下标+[],要么用范围for,很少用迭代器

cpp 复制代码
class Solution {
public:
    int firstUniqChar(string s) {
        int count[26] = {0};
        //统计出字符出现的次数
        for(auto ch : s)
        {
            count[ch - 'a']++;
        }

        for(size_t i = 0; i < s.size(); i++)
        {
            if(count[s[i] - 'a'] == 1)
                return i;
        }

        return -1;
    }
};

三. 字符串最后一个单词的长度【难度:简单】

描述

对于给定的若干个单词组成的句子,每个单词均由大小写字母混合构成,单词间使用单个空格分隔。输出最后一个单词的长度。

输入描述:

在一行上输入若干个字符串,每个字符串代表一个单词,组成给定的句子。

除此之外,保证每个单词非空,由大小写字母混合构成,且总字符长度不超过 10^3 。

输出描述:

在一行上输出一个整数,代表最后一个单词的长度。

这个题目它是一个标准的IO型(输入、输出)
知识点:

  1. rfind -> 倒着找

  1. 长度计算,算区间时有一个技巧:

) -\> 相减之后是个数 eg:\[0,10) 10-0=10 \[\] -\> 相减之后少1个 eg:\[0,9\] 9-0=9 *** ** * ** *** 3. 比如你想输入一个字符串,这里面包含空格,这个空格cin/scanf是拿不进来的 为了解决这个问题: C++引入一个getline(获取一行) ![](https://i-blog.csdnimg.cn/direct/1a3107e0b0a5486182d5fba03cddaa3e.png) getline它不会用空格作为终止,它会用换行作为终止 ```cpp getline(cin, str); //getline(cin, str, '#');//也可以自定义以什么为终止,这行代码是遇到#才结束 ```

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int main() 
{
    string str;
    //cin >> str;
    getline(cin,str);

    size_t pos = str.rfind(' ');
    if(pos != str.size())
    {   
        cout << str.size() - (pos + 1) << endl;
    }
    else {
        cout << str.size() << endl;
    }
}

四. 字符串相加【难度:简单】

描述:

给定两个字符串形式的非负整数 num1num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

cpp 复制代码
class Solution {
public:
    string addStrings(string num1, string num2) {
        int end1 = num1.size() - 1,end2 = num2.size() - 1;
        int carry = 0;
        string retStr;

        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret = ret % 10;

            //头插
            retStr.insert(0,1,'0'+ret);
        }
        
        //最后还有一个进位要头插
        if(carry)
            retStr.insert(0,1,'1');

        return retStr;
    }
};

这段代码的时间复杂度:O(N^2)

因为头插每次要挪动数据

1+2+3+...+N-1

上述代码可以优化,从O(N^2)(头插)-> O(N)(尾插+逆置)

优化:

现在逆置(reverse)不需要自己写了,算法库里面有

cpp 复制代码
class Solution {
public:
    string addStrings(string num1, string num2) {
        int end1 = num1.size() - 1,end2 = num2.size() - 1;
        int carry = 0;
        string retStr;
        retStr.reserve(max(num1.size(),num2.size())+1);//算法库里面也有max的函数

        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret = ret % 10;

            //尾插
            retStr += ('0'+ret);
        }
        
        //最后还有一个进位要尾插
        if(carry)
            retStr += '1';

        reverse(retStr.begin(),retStr.end());//逆置

        return retStr;
    }
};

结尾:

往期精选:

《别再重复写代码!C++模板初阶:一个模板适配多种数据类型》

《STL与字符编码:打好C++开发基石,避坑进阶两不误》

《C++ string类深度解析:核心接口全方位精讲与掌握》

结语:4道字符串题的解析,覆盖了C++字符串处理的常见场景与核心技巧。从优化反转效率到精准统计字符,从定位关键信息到模拟运算过程,每道题的思路都可复用。希望这些题解能帮你梳理知识、强化思维,在后续编程中更从容地应对字符串相关问题。

相关推荐
2401_8920709820 小时前
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
linux·c++·日志系统·日志滚动
yuzhuanhei20 小时前
Visual Studio 配置C++opencv
c++·学习·visual studio
小O的算法实验室20 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
不爱吃炸鸡柳21 小时前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
十五年专注C++开发21 小时前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
‎ദ്ദിᵔ.˛.ᵔ₎21 小时前
STL 栈 队列
开发语言·c++
2401_8920709821 小时前
【Linux C++ 日志系统实战】高性能文件写入 AppendFile 核心方法解析
linux·c++·日志系统·文件写对象
郭涤生21 小时前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿1 天前
vector
c语言·开发语言·数据结构·c++·算法
cccyi71 天前
【C++ 脚手架】etcd 的介绍与使用
c++·服务发现·etcd·服务注册