LeetCode—string练习

news2024/11/24 11:10:32

415.字符串相加

. - 力扣(LeetCode)

错误示范: 

遇到这种我们第一想法就是将字符串转化成整数,但这种解法无法提交通过,只能支持将小数字互相转化,遇到较长的字符串就没法通过。

class Solution {
public:
    string addStrings(string num1, string num2) {
        long long x = stoll(num1);//stoll将字符串转化成long long类型
        long long y = stoll(num2); 
        long long z = x + y; 
        return to_string(z);//将器转化成字符串类型
    }
};

思路: 

解法:对两个大整数模拟「竖式加法」的过程 。

我们定义两个指针 end1 和 end2 分别指向 num 1和 num 2 的末尾,即最低位,同时定义一个变量 pcur 维护当前是否有进位,然后从末尾到开头逐位相加即可。当两个数字位数不同时,这里我们在指针当前下标处于负数的时候返回 0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理!

代码参考: 

class Solution {
public:
    string addStrings(string num1, string num2) {
        string str;
        int pcur = 0;
        int end1 = num1.size()-1,end2 = num2.size()-1;
        while(end1 >= 0 || end2 >= 0)
        { // 位数不同时用0补位
            // 从右向左取数
            int val1 = end1 < 0 ? 0 : num1[end1--] - '0';
            int val2 = end2 < 0 ? 0 : num2[end2--] - '0';
            int sum = val1 + val2 + pcur;
            pcur = sum / 10;//进位
            sum %= 10;
            str += (sum + '0');//加上'0'才是字符串
        }
        if(pcur == 1)//最后多出的进位
        {
            str += '1';
        }
        reverse(str.begin(),str.end());//逆置
        return str;
    }
};

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

字符串最后一个单词的长度_牛客题霸_牛客网

思路: 

调用流插入cin时,流提取遇到' '空格会被自动跳过,直到遇到下一个非空白字符,遇到'\0'结束读取,所以用到 get()函数get() 函数是 istream 类的一个成员函数,用于从输入流中读取字符,get() 函数不会自动跳过任何空白字符,包括空格和制表符。

while循环提取字符串,直到输入流读取到字符串结束符 

代码:

#include <iostream>
using namespace std;

int main() {
    string str;
    while(cin >> str)
    {
        if(cin.get() == '\0')
            break;
    }
    cout << str.size() << endl;
}

125. 验证回文串

 思路:

使用双指针。初始时,左右指针分别指向 s 的两侧,随后我们不断地将这两个指针相向移动,每次移动一步,并判断这两个指针指向的字符是否相同。当这两个指针相遇时,就说明 s 是回文串。

代码: 

class Solution {
public:
    bool isLetterOrNumber(char ch)
    {
        return (ch >= '0' && ch <= '9')
        || (ch >= 'a' && ch <= 'z')
        || (ch >= 'A' && ch <= 'Z');
    }
    bool isPalindrome(string s) {
        int begin = 0,end = s.size() - 1;
        for(auto& ch : s)//加&,在原字符串上修改,现将所有大写转化成小写
        {
            if(ch >= 'A' && ch <= 'Z')
            {
                ch += 32;
            }
        }
        while(begin <= end)
        {
            while(begin < end && !isLetterOrNumber(s[begin]))
            {
                ++begin;
            }
            while(begin < end && !isLetterOrNumber(s[end]))
            {
                --end;
            }
            if(s[begin++] != s[end--])
            {
                return false;
            }
        }
        return true;
    }
};

541. 反转字符串 II

思路:

 我们直接按题意进行模拟:反转每个下标从 2k 的倍数开始的,长度为 k 的子串。若该子串长度不足 k,则反转整个子串。

len < i + k 时,就是剩余子串不足k;

len > i + k 时,是子串个数大于k

—> 剩余字符小于 2k 但大于或等于 k 个 / 在原字符上,字符等于2k;

代码: 

class Solution {
public:
    string reverseStr(string s, int k) {
        int len = s.size();
        for(int i = 0; i < len ;i += 2 * k)
        {//反转每个下标从 2k 的倍数开始的,长度为 k 的子串
            reverse(s.begin() + i,s.begin() + min(i + k ,len));
            //len < i + k 时,就是剩余子串不足k
            //len > i + k 时,是子串个数大于k 
            //——> 剩余字符小于 2k 但大于或等于 k 个 / 在原字符上,字符等于2k 
        }
        return s;
    }
};

557. 反转字符串中的单词 III

思路:

开辟一个新字符串。然后从头到尾遍历原字符串,直到找到空格为止,此时找到了一个单词,并能得到单词的起止位置。随后,根据单词的起止位置,可以将该单词逆序放到新字符串当中。如此循环多次,直到遍历完原字符串,就能得到翻转后的结果。

代码:

class Solution {
public:
    string reverseWords(string s) {
        string tmp;//开一个新空间
        int len = s.length();
        int i = 0;
        while(i < len)
        {
            int start = i;//刷新单词起始位置
            while(i < len && s[i] != ' ')
            {//记录一个单词的长度
                i++;
            }
           for(int c = i - 1; c >= start ;c--)
            {//倒序尾插
                tmp.push_back(s[c]);
            }
            while(i < len && s[i] == ' ')
            {
                i++;
                tmp.push_back(' ');
            }
        }
        return tmp;
    }
};

LLCR 192. 把字符串转换成整数 (atoi)

 思路1 (用long存储):

​ 

1. 首部空格: 删除之即可;
2. 符号位: 三种情况,即 ''+'' , ''−'' , ''无符号" ;新建一个变量 sign 保存符号位,返回前判断正负即可;
3. 非数字字符: 遇到首个非数字的字符时,应立即返回;
4. 数字字符:
(1)字符转数字: “此数字的 ASCII 码” 与 “ 0 的 ASCII 码” 相减,得到当前数字x;
(2)数字拼接: 若从左向右遍历数字,设当前位字符为 c ,当前位数字为 x ,数字结果为 res ,则数字拼接公式为:
 res = 10 * res + x

5.考虑数据是否溢出:因为res是long类型的整形,所以在每轮数字拼接后,判断 res 在此轮拼接后是否超过 2147483647 ,若超过则加上符号位直接返回

代码1: 

class Solution {
public:
    int myAtoi(string str) {
        int i = 0,sign = 1;//默认符号是+
        long res = 0;
        while(i < str.size() && str[i] == ' ')//1.丢弃无用的前导空格
        {
            ++i;
        }
        //2.考虑正负数
        if(str[i] == '-')
        {
            sign = -1;//更新符号
            ++i;
        }
        else if (str[i] == '+') 
        {
            i ++;
        }
        if(str[i] < '0' || str[i] > '9') 
        // 正常数字第一位不能是0,必须为1~9之间的数字,否则就是非法数字
            return 0;  

        //3.考虑数据是否溢出
        for(;i < str.size() ; i++)
        {
            //注意这句话要放在字符转换前
            if(str[i] < '0' || str[i] > '9')
                break;
                
            res = res * 10 + (str[i] - '0');
            //INT_MAX = 2^32 - 1 = 2147483647
            //大于等于最大值直接返回最大值
            if(res >= INT_MAX && sign == 1)
            {
                return INT_MAX;
            }
            //INT_MIN = -2^32 = -2147483648
            //符号是-,且大于最大值时才能直接返回最小值(不看符号,MIN比MAX大1)
            if(res > INT_MAX && sign == -1)
            {
                return INT_MIN;
            }
        }
        return sign * res;
    }
};

思路2 (不用long):

该思路只有第5点与思路1不同,res此时是int类型的数据,要避免超出int范围,我们用低于int型数据长度一位的数据 border 判断是否超过int型数据的长度。在每轮数字拼接前,判断 res 在此轮拼接后是否超过 2147483647 / 10 ,若超过则加上符号位直接返回 INT_MAX或 INT_MIN 。

代码2:

class Solution {
public:
    int myAtoi(string str) {
        int i = 0,sign = 1;//默认符号是+
        while(i < str.size() && str[i] == ' ')//1.丢弃无用的前导空格
        {
            ++i;
        }

        //2.考虑正负数
        if(str[i] == '-')
        {
            sign = -1;//更新符号
            ++i;
        }
        else if (str[i] == '+') 
        {
            i ++;
        }
        if(str[i] < '0' || str[i] > '9') 
        // 正常数字第一位不能是0,必须为1~9之间的数字,否则就是非法数字
            return 0;  

        int res = 0;//此时res是int类型,要考虑数据溢出
        int border = INT_MAX/10;//用来验证数据是否超出int的范围
        //3.考虑数据是否溢出
        for(;i < str.size() ; i++)
        {
            //注意这句话要放在字符转换前,
            //因为需要验证的位数比实际值的位数要少一位
            if(str[i] < '0' || str[i] > '9')
                break;
            
            //将超过最大值和低于最小值的情况都包括了
            if(res > border || res == border && str[i] - '0' > 7)
            {
            //还没*10就大于INT_MAX/10 或
            //等于INT_MAX/10 并且 当前位数字大于7(INT_MAX最后一位数是7)
                return sign == 1 ? INT_MAX : INT_MIN;
            }
            res = res * 10 + (str[i] - '0');
            
        }
        return sign * res;
    }
};

43. 字符串相乘

思路:

如果 num 1和 num2 之一是 0,则直接将 0 作为结果返回即可。

如果 num 1和 num2 都不是 0,则可以通过模拟「竖式乘法」的方法计算乘积。从右往左遍历乘数,将乘数的每一位与被乘数相乘得到对应的结果,再将每次得到的结果累加。这道题中,被乘数是 num1 乘数是 num2 需要注意的是,num2 除了最低位以外,其余的每一位的运算结果都需要补0(牛逼)。

代码1:

class Solution {
public:
    //字符串相加
    string addStrings(string num1, string num2) {
        string str;
        int pcur = 0;
        int end1 = num1.size()-1,end2 = num2.size()-1;
        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 < 0 ? 0 : num1[end1--] - '0';
            int val2 = end2 < 0 ? 0 : num2[end2--] - '0';
            int sum = val1 + val2 + pcur;
            pcur = sum / 10;//进位
            sum %= 10;
            str += (sum + '0');
        }
        if(pcur == 1)
        {
            str += '1';
        }
        reverse(str.begin(),str.end());
        return str;
    }
    //字符串相乘
    string multiply(string num1, string num2) {
        if(num1 == "0" || num2 == "0")//任意一个是"0"返回结果就是"0"
            return "0";

        string str1;
        int sign = 0;
        for(int i = num1.size() - 1;i >=0 ; i--)
        {
            string str2;
            int add = 0;
            //对每一位的运算结果补0(除最低位外),太吊了,但有风险性
            for (int j = num2.size() - 1;j > i;j--)
            {
                str2.push_back('0');
            }

            int val2 = num2[i] - '0';//拆分num2从右向左乘num1
            for(int k = num1.size()-1;k >= 0;k--)
            {
                int val1 = num1[k] - '0';//获取当前位数字
                int mul = val1 * val2 + add;
                add = mul / 10;//进位
                mul %= 10;//余数尾插
                str2 += ( mul + '0');
            }
        
            if(add != 0)//处理剩余的余数
            {
                str2 += (add % 10 + '0');
                add /= 10;
            }
            //先逆置str2,再进行错位相加
            reverse(str2.begin(),str2.end());
            str1 = addStrings(str1,str2);
        }
        return str1;
    }
};

代码2: (封装函数)

1. 下翻转数据

2. 按位相乘

3. 将乘得的结果进行错位相加,模拟乘法的笔算过程

class Solution
{
public:
    void MulItem(string& tmp, string& num1, char a)
    {
        int i = 0, sign = 0;
        int mul = 0;
        while (i < num1.size())
        {
            mul = (num1[i] - '0') * (a - '0') + sign;
            if (mul >= 10)
            {
                sign = mul / 10;
                mul %= 10;
            }
            else
                sign = 0;
            tmp.push_back(mul + '0');
            i++;
        }
        if (sign > 0)
            tmp.push_back(sign + '0');
    }

    //对应为相加,sign进位采用引用传递
    int AddItem(int a, int b, int& sign)
    {
        int add = a + b + sign;
        if (add >= 10)
        {
            sign = 1;
            add -= 10;
        }
        else
            sign = 0;

        return add;
    }
    
    //错位相加
    void MoveAdd(string& result, string& tmp, int k)
    {
        int i, j;
        i = k;
        j = 0;
        int sign = 0;
        while (i < result.size() && j < tmp.size())
        {
            result[i] = AddItem(result[i] - '0', tmp[j] - '0', sign) + '0';
            i++;
            j++;
        }
        while (i < result.size() && sign)
        {
            result[i] = AddItem(result[i] - '0', 0, sign) + '0';
            i++;
        }
        while (j < tmp.size())
        {
            int v = AddItem(0, tmp[j] - '0', sign);
            result.push_back(v + '0');
            j++;
        }
        if (sign)
            result.push_back(sign + '0');
    }

    string multiply(string num1, string num2)
    {
        //先翻转数据,方便进位处理
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());

        string tmp, result;
        for (int i = 0; i < num2.size(); ++i)
        {
            //使用num2的每一个数据乘以num1
            MulItem(tmp, num1, num2[i]);
            //将乘得的结果进行错位相加
            MoveAdd(result, tmp, i);
            tmp.clear();
        }

        while (result.size() != 1 && result.back() == '0')
            result.pop_back();

        //翻转数据,恢复数据
        reverse(result.begin(), result.end());
        return result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2101139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32项目设计】STM32F411健康助手--三脚--波轮开关--外部中断输入(3)

硬件设计 软件设计 key.c 波轮按键默认为低电平&#xff0c;需要配置为下拉输入&#xff0c;如果浮空的话电压会在1.8v上下波动&#xff0c;单片机检测会出现异常。波动时为高电平&#xff0c;设置为高电平触发。 key0是一个普通按键&#xff0c;忽略即可&#xff0c;key1~3为…

批量剪辑+批量发布的短视频矩阵系统,你真的需要吗?

矩阵的概念&#xff0c;可以简单理解成一种放大和复制的策略。就像你经营一家某宝店铺&#xff0c;如果每天能赚100元&#xff0c;那么通过开设更多的店铺&#xff0c;比如50家&#xff0c;你的日收入就能达到5000元。这就是所谓的“矩阵店铺”&#xff0c;它的核心在于通过增加…

uniapp使用uni-popup做底部弹出选项(vue3)

效果图 页面代码 <!-- 发票筛选弹出框 --><uni-popup ref"popupRef" type"bottom" border-radius"10px 10px 0 0" background-color"#fff"><h4 style"text-align: center;margin-bottom: 20px;">发票筛…

微服务配置管理

小编目前大一&#xff0c;刚开始着手学习微服务的相关知识&#xff0c;小编会把它们整理成知识点发布出来。我认为同为初学者&#xff0c;我把我对知识点的理解以这种代码加观点的方式分享出来不仅加深了我的理解&#xff0c;或许在某个时候对你也有所帮助&#xff0c;同时也欢…

计算机毕业设计选题推荐-企业人事管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Mysql(一) - 数据库操作, 表操作, CRUD

目录 一.数据库操作 1.增加数据库 2.展示数据库 3.删除数据库 4.选定数据库 二.表操作 1.增加选定数据库中的表 2.展示选定数据库中的表 3.删除选定数据库中表 4.查看选定表的字段信息 三.增加和查找 1.增加 2.查找 a.where的使用 b.分页查询 四.更新和删除 1.…

Spring及Springboot事件机制详解

程序设计的所有原则和方法论都是追求一件事——简单——功能简单、依赖简单、修改简单、理解简单。因为只有简单才好用&#xff0c;简单才好维护。因此&#xff0c;不应该以评论艺术品的眼光来评价程序设计是否优秀&#xff0c;程序设计的艺术不在于有多复杂多深沉&#xff0c;…

中资优配:“迪王”,拔得头筹!

Wind数据闪现&#xff0c;现在已有逾越190家上市公司入围券商9月“金股”组合。从举荐频次看&#xff0c;“迪王”比亚迪拔得头筹&#xff0c;阳光电源、我国移动等标的获券商密布举荐&#xff0c;医药生物等工作含“金”量高。 展望9月商场&#xff0c;券商判别&#xff0c;其…

真实:关于源代码防泄漏工作一些经验分享

互联网的飞速发展&#xff0c;各行各业都在往数字化转型&#xff0c;很多传统的业务数据都需要逐渐录入到电脑中&#xff0c;不仅节省了空间&#xff0c;还节约了成本。而这些数据都需要通过各类型的应用程序&#xff0c;进行分类&#xff0c;统计&#xff0c;展示&#xff0c;…

远程桌面连接出现身份验证错误解决方法

远程桌面身份验证错误的原因是什么&#xff1f; 在尝试远程连接到其他设备时&#xff0c;您可能会遇到身份验证错误&#xff0c;通常会弹出提示“出现身份验证错误&#xff0c;要求的函数不受支持”。这种身份验证错误通常是因为您输入的凭据与受控设备上设置的安全帐户信息不…

B端系统门门清之:CRM-客户管理系统,客户是一切的源头。

公司最宝贵的是什么&#xff0c;有人说是人才、有人说品牌、还有人说是技术&#xff0c;错&#xff0c;大错特错了&#xff0c;最宝贵的永远是客户&#xff0c;没有了客户&#xff0c;人才、品牌、技术都无从谈起。 今天分享最常见的B端系统CRM&#xff0c;那么是什么是CRM呢&…

大模型技术开发与应用

大模型技术开发与应用 LLM背景知识介绍: 大语言模型是一种人工智能模型,旨在理解和生成人类语言.大语言模型可以处理多种自然语言任务,如文本分类,问答,翻译,对话等等. 通常,大语言模型(LLM)是指包含数千亿(或更多)参数的语言模型(目前定义参数数量超过10B的模型为大语言模…

UI自动化测试 —— web端元素获取元素等待实践!

前言 Web UI自动化测试是一种软件测试方法&#xff0c;通过模拟用户行为&#xff0c;自动执行Web界面的各种操作&#xff0c;并验证操作结果是否符合预期&#xff0c;从而提高测试效率和准确性。 目的&#xff1a; 确保Web应用程序的界面在不同环境(如不同浏览器、操作系统)下…

注册登陆(最新版)

整体概述 本项目中&#xff0c;使用数据库连接池实现服务器访问数据库的功能&#xff0c;使用POST请求完成注册和登录的校验工作。 本文内容 本篇将介绍同步实现注册登录功能&#xff0c;具体的涉及到流程图&#xff0c;载入数据库表&#xff0c;提取用户名和密码&#xff0…

AquaCrop模型数据制备、优化方法、敏感性与气候变化影响分析及源码解析

AquaCrop是由世界粮食及农业组织&#xff08;FAO&#xff09;开发的一个先进模型&#xff0c;旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理&#xff0c;特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…

PySide6复杂C/S系统开发

PySide6复杂C/S系统开发 目录 0.了解 1.前提 2.实际代码&#xff08;继承QGraphicsview修改&#xff09; 0.了解 之前写了一篇“PySimpleGUI复杂C/S系统开发”博客&#xff08;由于pysimplegui更改了协议&#xff0c;因此不再推荐&#xff0c;用了pyside6后yyds&#xff09…

Transiting from CUDA to HIP (二)

一、Identifying Architecture Features 1. HIP_ARCH Defines 在 CUDA 编程中&#xff0c;__CUDA_ARCH__ 是一个预定义的宏&#xff0c;用于指示当前编译的代码所针对的 NVIDIA GPU 的计算能力&#xff08;Compute Capability&#xff09;。开发者可以使用这个宏来编写条件代…

Xinstall助力App推广:全方位支持,精准数据分析,你值得拥有

在如今的移动互联网时代&#xff0c;App推广已成为每个应用开发者必须面对的重要课题。然而&#xff0c;推广过程中往往伴随着诸多痛点&#xff0c;如数据混乱、投放盲目、决策滞后以及作弊困扰等。这些问题不仅影响了推广效果&#xff0c;还可能导致资源的浪费和投入产出不均衡…

数据安全认证来了解一下

随着数据安全法及个人信息保护法的实施&#xff0c;数据安全相关岗位在安全行业变得极为热门。 根据数据安全法第二十条&#xff0c;国家鼓励教育、科研机构和企业等开展数据开发利用技术和数据安全相关的教育和培训&#xff0c;采用多种途径培育专业人才&#xff0c;促进人才…

【Linux】使用Linux实现小程序 - 进度条

目录 一、缓冲区二、回车换行的概念三、进度条的设计3.1 版本1&#xff08;没有配合场景&#xff09;3.2 版本2&#xff08;配合场景&#xff09;3.3 版本3&#xff08;美化进度条&#xff09; 结尾 一、缓冲区 C/C语言&#xff0c;会针对标准输出&#xff0c;给我们提供默认的…