【C++】string典型oj题


请添加图片描述

前言

  上一节我们已经仔细讲解了关于string的各种重要接口的使用:【C++】string的使用。下面我们来使用这些接口写几道OJ题。

字符串相加

415.字符串相加-力扣
在这里插入图片描述
  这道题目的意思也很简单,就是想让我们模拟实现加法的过程。我们要搞清楚字符串如何相加,如何进位等一些问题即可。
  我们做加法都是从个位开始依次相加,因此我们可以通过下标+[]的形式取出每个字符数,再减去’0’,既是对应的数字。

如"123",想要取出个位数就是num[2]-‘0’,即可得到数字3。

然后就可以开始计算了。

  • 首先定义一个串,我们知道加法的结果最多只会比位数多的再多一位,因此我们就知道需要开多少空间。
  • 结束标志:只有当两个串的所有数字都加完后才结束
  • 进位计算。
  • 得到数字后进行头插(效率较低)
class Solution {
public:
    string addStrings(string num1, string num2) {
        string str;
        //开空间
        str.reserve(max(num1.size(), num2.size()) + 1);
        //知道两个串分别有多少位数
        int end1 = num1.size() - 1;
        int end2 = num2.size() - 1;
        int next = 0;//进位
        while(end1 >= 0 || end2 >= 0)//只有当两个串的所有数字都加完后才结束
        {
        	//如果end1或者end2不大于0,证明它已经加完了,此时用0来填充
            int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;
            int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;
            int x = x1 + x2 + next;
            next = x/10;
            x = x%10;
            str.insert(str.begin(), x +'0');//头插,要加上'0'才是字符才能插入
        }
//例如9+1,它的x是0,已经插入了,但是进位next还没有加上,因此还要判断是否有多的进位没加上,如果有直接头插'1'即可。
        if(next == 1)
        {
            str.insert(str.begin(), '1');
        }
        return str;
    }
};

  我们知道头插的效率很低,上面代码的时间复杂度是O(n2),因此我们建议尾插,然后逆置即可。

	{
	//前面代码不变
	//...
	x = x%10;
	str += (x + '0');
	}
	if(next == 1)
    {
         str += '1';
    }
    reverse(str.begin(), str.end());//库里面已经提供好了的,在平时使用时要加上头文件#include<algorithm>
    return str;

字符串相乘

43.字符串相乘-力扣
在这里插入图片描述
  这道题和上一道字符串相加有着异曲同工之处。

  • 如果 num1和num2之一是 0,则直接将 0 作为结果返回即可。
  • 如果 num1和num 2都不是 0,则可以通过模拟「竖式乘法」的方法计算乘积。从右往左遍历乘数,将乘数的每一位与被乘数相乘得到对应的结果,再将每次得到的结果累加。这道题中,被乘数是 num 1,乘数是num2 。

需要注意的是,num2除了最低位以外,其余的每一位的运算结果都需要补 0。
在这里插入图片描述
然后对每次得到的结果(串)进行累加,就可以使用上一题字符串相加的方法。

class Solution {
public:
    string addStrings(string num1, string num2) {
        string str;
        str.reserve(max(num1.size(), num2.size()) + 1);
        int end1 = num1.size() - 1;
        int end2 = num2.size() - 1;
        int next = 0;
        while(end1 >= 0 || end2 >= 0)
        {
            int x1 = end1 >= 0 ? num1[end1--] - '0' : 0;
            int x2 = end2 >= 0 ? num2[end2--] - '0' : 0;

            int x = x1 + x2 + next;

            next = x/10;
            x = x%10;

            //str.insert(str.begin(), x +'0');
            str += (x + '0');
        }

        if(next == 1)
        {
            //str.insert(str.begin(), '1');
            str += '1';
        }
        reverse(str.begin(), str.end());
        return str;
    }
    string multiply(string num1, string num2) {
        if(num1 == "0" || num2 == "0")
            return "0";
        string ans = "0";
        int m = num1.size();
        int n = num2.size();
        for(int i = n - 1; i >= 0; i--)
        {
            string cur;
            for(int j = n-1; j > i; j--)
                cur += '0';
            int next = 0;//进位
            int y = num2.at(i) - '0';
            for(int j = m-1; j >= 0; j--)
            {
                int x = num1[j]-'0';
                int product = x *y + next;
                next = product / 10;
                product = product % 10;
                cur += (product + '0');
            }
            if(next != 0)
            {
                cur += (next + '0');
            }
            reverse(cur.begin(), cur.end());
            ans = addStrings(ans,cur);
        }
        return ans;
    }
};

字符串转换整数

8.字符串转换整数(atoi)-力扣
在这里插入图片描述

函数 myAtoi(string s) 的算法如下:
空格:读入字符串并丢弃无用的前导空格(" ")
符号:检查下一个字符(假设还未到字符末尾)为 ‘-’ 还是 ‘+’。如果两者都不存在,则假定结果为正。
转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
舍入:如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。
返回整数作为最终结果。

我们对题目要求依次求解即可:

  1. 对于空格,只需要用while条件判断删除即可。
  2. 对于符号,给定一个变量flag,初始化为1,判断如果有'-',就将其置为-1,有’+‘或者没有就还是为1,有’+‘或’-'加加跳过即可。
  3. 判断是否为数字字符,如果是才能进入循环,不是则直接退出。
  4. 数字字符 - ‘0’ = 数字,数字拼接:res = res *10 +flag*(c - '0');即可得到最终数字。
  5. 数字越界处理:在每轮数字拼接前判断res在此轮拼接后是否超过/小于 INT_MAX/INT_MIN ,若超过则直接返回INT_MAX/INT_MIN。

在这里插入图片描述

class Solution {
public:
    bool isdigital(char c)
    {//判断是否是数字字符
        if(c >= '0' && c <= '9')
            return true;
        return false;
    }
    int myAtoi(string s) {
        int i = 0;
        int flag = 1;
        int res = 0;
        while(s[i]==' ')
        {//去掉空格
            ++i;
        }
        if(s[i]=='-')
            flag = -1;//记录负号
        if(s[i] == '-' || s[i] == '+')
            i++;
        int j = i;
        while(isdigital(s[j]) && j < s.size())//是数字字符再进循环
        {
            char c = s[j];//取出当前字符
            //判断越界
            if(res > INT_MAX /10 || (res == INT_MAX / 10 && (c-'0') > INT_MAX % 10))
                return INT_MAX;
            if(res < INT_MIN /10 || (res == INT_MIN / 10 && (c-'0') > -(INT_MIN % 10)))
                return INT_MIN;
            res = res *10 +flag*(c - '0');//拼接数字
            j++;
        }
        return res;
            
    }
};

感谢大家观看,如果大家喜欢,希望大家一键三连支持一下,如有表述不正确,也欢迎大家批评指正。
请添加图片描述

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值