c++:string相关的oj题(415. 字符串相加、125. 验证回文串、541. 反转字符串 II、557. 反转字符串中的单词 III)

简介: c++:string相关的oj题(415. 字符串相加、125. 验证回文串、541. 反转字符串 II、557. 反转字符串中的单词 III)

1. 415. 字符串相加


题目详情

代码1


class Solution {
public:
    string addStrings(string num1, string num2) {
        int index1=num1.size()-1,index2=num2.size()-1;//找到最后一位
        int next=0;//进位
        string retStr;
        while(index1>=0||index2>=0)//还有一个没完就要进来:有可能一直进位
        {
            int val1=0,val2=0; 
            if(index1>=0)
            {
                val1=num1[index1--]-'0';
            }
            if(index2>=0)
            {
                val2=num2[index2--]-'0';
            }
            int ret=next+val1+val2;//两者相加后加上进位数
            next=ret/10;//需要进位就是1了,不需要就是0
            ret%=10;
            retStr.insert(0,1,'0'+ret);//头插到新string
        }
        //最后有可能有1+9的情况,现在只会有0
        if(next==1)
        {
            retStr.insert(0,1,'1');
        }
        return retStr;
    }
};


思路1


首先,定义两个指针 index1 和 index2 分别指向两个输入字符串的最后一位,用来从后往前遍历字符串。

然后定义一个变量 next 用来表示进位,初始化为 0。

接下来使用一个循环来遍历两个字符串,直到 index1 和 index2 都小于 0。在循环中,每次取出 index1 和 index2 对应位置的数字,并将它们与进位相加,得到一个临时的结果 ret。

然后更新进位 next 为 ret/10,并将 ret%10 插入到需要返回的字符串 retStr 的开头。

循环结束后,还需要检查最后是否有进位,如果有,需要将进位插入到结果字符串的开头。

但此时还是有一个问题的,那就是效率低(因为头插时间复杂度O(N^2));


代码2


class Solution {
public:
    string addStrings(string num1, string num2) {
        int index1=num1.size()-1,index2=num2.size()-1;//找到最后一位
        int next=0;//进位
        string retStr;
        while(index1>=0||index2>=0)//还有一个没完就要进来:有可能一直进位
        {
            int val1=0,val2=0; 
            if(index1>=0)
            {
                val1=num1[index1--]-'0';
            }
            if(index2>=0)
            {
                val2=num2[index2--]-'0';
            }
            int ret=next+val1+val2;//两者相加后加上进位数
            next=ret/10;//需要进位就是1了,不需要就是0
            ret%=10;
            //使用尾插效率更好,尾插有append,这里我们使用+=
            retStr+='0'+ret;
        }
        //最后有可能有1+9的情况,现在只会有0
        if(next==1)
        {
            retStr+='1';
        }
        reverse(retStr.begin(),retStr.end());//尾插后,最后翻转一下
        return retStr;
    }
};


思路2


整体思路都是一样的,只不过有头插换成了尾插+翻转


2. 125. 验证回文串


题目详情

代码1(按照要求修改后放到新string里)

class Solution {
public:
    bool isPalindrome(string s) {
        string re;
        for(auto e:s)//按照要求修改好
        {
            if((e>='A'&&e<='Z')||(e>='a'&&e<='z')||(e>='0'&&e<='9'))
            {
               if(e>='A'&&e<='Z')
                {
                    re+=(e+32);
                }
                else
                {
                    re+=e;
                }
            }
        }
        string modified(re);
        reverse(re.begin(),re.end());       
        //看看是否相同
        for(int i=0;i<modified.size();i++)
        {
            if(re[i]!=modified[i])
            {
                return false;
            }
        }
        return true;
    }

思路1

遍历输入字符串 s 中的每个字符 e。

如果字符 e 是字母或数字,则根据题目要求将大写字母转换为小写字母,并将其添加到新的字符串 re 中。


创建一个新的字符串 modified,它是字符串 re 的一个副本。


反转字符串 re。


比较反转后的字符串 re 和副本字符串 modified,如果它们不相等,则返回 false,表示不是回文字符串;如果它们相等,则返回 true,表示是回文字符串

代码2(利用双指针/索引)

bool isLetterOrNumber(char ch)
{
    return (ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9');
}
class Solution {
public:
    bool isPalindrome(string s) {
        for(auto& e:s)//大的变小的
        {
            if(e>='A'&&e<='Z')
            {
                e+=32;
            }
        }
        int begin=0;
        int end=s.size()-1;
        while(begin<end)
        {
            while(begin<end&&!isLetterOrNumber(s[begin]))
            {
                begin++;
            }
            while(begin<end&&!isLetterOrNumber(s[end]))
            {
                --end;
            }
            if(s[begin]!=s[end])
            {
                return false;
            }
            else
            {
                ++begin;
                --end;
            }
        }
        return true;
    }
};

思路2

创建一个辅助函数 isLetterOrNumber,用于判断一个字符是否是字母或数字。

遍历输入字符串 s 中的每个字符 e,将大写字母转换为小写字母。

初始化两个指针 begin 和 end,分别指向字符串的开头和结尾。

在一个 while 循环中,不断移动指针 begin 和 end,直到两个指针相遇。

在移动指针的过程中,跳过非字母和数字的字符。

在二者都是数字或者字母后,比较指针指向的字符,如果不相等,则返回 false,表示不是回文字符串;如果相等,则继续移动指针。

如果循环结束后都没有返回 false,则说明是回文字符串,返回 true。


3. 541. 反转字符串 II


题目详情

代码1

class Solution {
public:
    string reverseStr(string s, int k) {
        int len=s.size();
        for(int i=0;i<len;i+=2*k)
        {
            if(i+k<=len)//剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
                      //同时前面的2k区域不用管,直接满足,只有最后那个不够2k的区间才讨论
            {
                reverse(s.begin()+i,s.begin()+i+k);
            }
            else{
                reverse(s.begin()+i,s.begin()+len);
            }
        }
        return s;
    }
};


思路1

利用每次要跳2k来处理:就直接i+=2k,这样每次直接跳到下一个区间,前面够2k的不用管,直接满足i+k<=len,只有那最后一个不够2k的需要讨论(毕竟s.begin()+len是最后元素的下个位置)


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


题目详情

代码1(利用find)

class Solution {
public:
    string reverseWords(string s) {
        size_t pos=0;
        int i=0;
        while(i<s.size())
        {
            pos=s.find(' ',i);
            if(pos==string::npos)//只有一个单词了
            {
                reverse(s.begin()+i,s.end());
                break;
            }
            reverse(s.begin()+i,s.begin()+pos);
            i=(pos+1);
        }
        return s;
    }
};

思路1

总体思路是找到单词的左和右索引,在这个区间内进行翻转


利用一个i 对字符串进行遍历,pos来储存找到的' '的下标

那么从i到pos就是一个单词加上’ ',正好满足reserve()函数左闭右开的性质

然后i=pos+1(跳到空格后)

如果没找到空格,就说明只剩下一个,或者只有一个单词。 就直接i到end()进行翻转了


代码2(利用双指针)

class Solution {
public:
    string reverseWords(string s) {
       int i=0;
       while(i<s.size())//直接进循环
       {
           int left=i;//存一下起始位置
           while(i<s.size()&&s[i]!=' ')//找空格
           {
               i++;
           }
           //现在要么找到了,要么到size处了
           int right=i-1;
           while(left<right)//开始换
           {
               swap(s[left],s[right]);
               left++;
               right--;
           }
           if(s[i]==' ')
           {
               i++;
           }
       }
       return s;
    }
};

思路2

总体思路是一样的,不过自己找,没有利用find


今天就到这里啦!

目录
相关文章
|
3月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
2月前
|
数据处理
鸿蒙开发:ArkTs字符串string
字符串类型是开发中非常重要的一个数据类型,除了上述的方法概述之外,还有String对象,正则等其他的用处,我们放到以后得篇章中讲述。
117 19
|
2月前
|
IDE 编译器 项目管理
Dev-C++保姆级安装教程:Win10/Win11环境配置+避坑指南(附下载验证)
Dev-C++ 是一款专为 Windows 系统设计的轻量级 C/C++ 集成开发环境(IDE),内置 MinGW 编译器与调试器,支持代码高亮、项目管理等功能。4.9.9 版本作为经典稳定版,适合初学者和教学使用。本文详细介绍其安装流程、配置方法、功能验证及常见问题解决,同时提供进阶技巧和扩展学习资源,帮助用户快速上手并高效开发。
|
3月前
|
C++
模拟实现c++中的string
模拟实现c++中的string
|
3月前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
92 16
|
2月前
|
Java 程序员
课时16:String字符串
课时16介绍了Java中的String字符串。在Java中,字符串使用`String`类表示,并用双引号定义。例如:`String str = &quot;Hello world!&quot;;`。字符串支持使用“+”进行连接操作,如`str += &quot;world&quot;;`。需要注意的是,当“+”用于字符串与其他数据类型时,其他类型会先转换为字符串再进行连接。此外,字符串中可以使用转义字符(如`\t`、`\n`)进行特殊字符的处理。掌握这些基本概念对Java编程至关重要。
|
6月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
290 5
|
6月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
177 2
|
6月前
|
索引 Python
String(字符串)
String(字符串)。
132 3
|
7月前
|
NoSQL Redis
Redis 字符串(String)
10月更文挑战第16天
87 4

热门文章

最新文章