字符串OJ

1. LeetCode第415题—字符串相加

在这里插入图片描述

class Solution {
public:
    string addStrings(string num1, string num2) {
        string ret;
        int end1 = num1.size()-1;
        int end2 = num2.size()-1;
        int carry = 0;
        while(end1 >= 0 || end2 >= 0)
        {
            //在end1和end2本身也是应该可以等于字符串下标0那个位置的
            int x1 = end1 >= 0 ? num1[end1]-'0': 0;
            int x2 = end2 >= 0 ? num2[end2]-'0': 0;
            int sum = x1 + x2 + carry;
            ret += to_string(sum % 10);
            carry = sum / 10;
            --end1;
            --end2;
        }
        if(carry ==1)
            ret += to_string(carry);
        reverse(ret.begin(),ret.end());
        return ret;
    }
};

2. LeetCode第43题—字符串相乘

在这里插入图片描述
解题思路:对于字符串相乘来说,两个数相乘的结果不会超过mn的个数其中m表示第一个字符串的字符个数,n表示第二个字符串的个数(换句话说,9999的结果最多就是4位数的结果),此时我们采用的方法是不用直接的上来就进位,而是让所有的数都相加,最后再求这个进位,且我这里采用的是倒着的计算方式。最后一个难点就是要把倒过来的时候作为首位的0去除掉。
在这里插入图片描述

class Solution {
public:
    string multiply(string num1, string num2) {
        vector<int> v1;
        vector<int> v2;
        int m = num1.size();
        int n = num2.size();
        for(int i = m-1;i>=0;--i)
        {
            v1.push_back(num1[i]-'0');
        }
        for(int j = n-1;j>=0;--j)
        {
            v2.push_back(num2[j]-'0');
        }
        //先把两个字符串中的数都按照倒叙的方式一个个存储在数组中,其次我们知道不管如何,两个数相乘
        //都不可能超过他们两者和的位数m+n
        vector<int> ret(m+n,0);
        for(int i = 0;i<m;++i)
        {
            for(int j = 0;j<n;++j)
            {
                ret[i+j] += v1[i] * v2[j];
            }
        }
        //上面的两层for循环就已经可以求出现在所有的每个位置的结果了
        int carry = 0;
        for(int i = 0;i<ret.size();++i)
        {
            carry += ret[i];
            ret[i] = carry % 10;
            carry /= 10; 
        }
        //然后上面的就是结果,但是现在是倒着的
        int k = ret.size()-1;
        //这一步的主要目的就是为了去除整数倒过来以后的0
        //为什么这里不能够k>=0
        //只有这样才能在0*0的时候不出现错误
        //不然的话就直接返回的是空字符串
        while(k > 0 && !ret[k])
            --k;
        string str;
        while(k >= 0)
        {
            str += ret[k--] + '0';
        }
        return str;
    }
};

3. LeetCode第6题—Z字形变换

在这里插入图片描述
解题思路:这道题就有意思了,首先就是他的思想就是触及反弹这么个意思,但是解题的过程中采用了一个标志位的方式,一下子就简化了这道题的复杂程度。但是在min函数内部,是不能够使用s.size()这么个函数的,所以我们采用int的初始化方式,最后再将字符串进行拼接就可以得到我们想要的答案。

class Solution {
public:
    //行数就是numRows,但是多少列呢?
    string convert(string s, int numRows) {
        //这道题的核心关键在于触及反弹这里,比如说当在第一行的时候,他就应该往下走,当到最后一行的时候,就应该往上走
        if(numRows == 1)
            return s;
        //这一句代码是什么意思?需要好好的在理一下
        //你想一下如果s就两个字符,但是你此时要3行,那么也是不和规矩的
        vector<string> v(min(numRows,int(s.size())));
        //此时就相当于字符串拼接一样
        int curRow = 0;
        bool goingDown = false;
        for(char c : s)
        {
            v[curRow] += c;
            //此时我们需要改变curRow
            if(curRow == 0 || curRow == numRows-1)
                goingDown = !goingDown;
            curRow += goingDown? 1:-1;
        }
        string ret;
        for(string& str: v)
        {
            ret += str;
        }
        return ret;
    }
};

4. LeetCode第4题—寻找两个正序数组的中位数

在这里插入图片描述

5. LeetCode第3题—整数反转

在这里插入图片描述
解题思路:这道题最难的点在于,要考虑到你在反转叠加的过程中是有可能大数溢出的,所以要提前的进行判断。

class Solution {
public:
    int reverse(int x) {
        int ret = 0;
        while(x != 0)
        {
            //为什么这里使用的是ret > INT_MAX/10,而不是使用ret*10 < INT_MAX主要的原因就是,如果大数溢出了,那么直接就会崩掉了
            if(ret< INT_MIN / 10 || ret > INT_MAX / 10)
            {
                return 0;
            }
            //因为你这一步ret*10的操作本身就有可能会大数溢出,所以这里要做好判断
            ret = ret*10 + x % 10;
            x /= 10;
        }
        return ret;
    }
};

6. LeetCode第394题—字符串解码(重点)

在这里插入图片描述
在遇见‘[’的时候,把前面的数字和字符串都添加到栈里面

class Solution {
public:
    string decodeString(string s) {
        //借助双栈的思想,这道题还是很考验思路的有必要在做一次
        //"aaa2[bc]"这里展开
        //我们应该尽力首先把两个括号中间的给展开,然后在展开最外面的
        //是不是可以借助栈的思想
        stack<int> nums;
        stack<string>  strs;
        int num = 0;
        string res; //因为最终返回的也是一个字符串
        for(int i = 0;i<s.size();++i)
        {
            if(s[i] >= '0' && s[i] <= '9')
            {
                num = num*10 + s[i]-'0';
            }
            else if((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'))
            {
                res += s[i];
            }
            else if(s[i] == '[')
            {
                //此时就应该彻底的展开了
                nums.push(num);
                num = 0;
                strs.push(res);
                res = "";
            }
            else
            {
                //此时就是‘]’,既然是收括号了,那么就要有不一样的操作了
                int times = nums.top();
                nums.pop();
                for(int i = 0;i<times;++i)
                //这里我发现我始终有点不是很理解
                //这一步相当于先处理里面括号
                //这里的strs.pop()是"",循环上来一次就变为"a"
                    strs.top() += res;
                res = strs.top(); // 什么意思
                strs.pop();
            }
        }
        return res;
    }
};
要实现一个截取字符串的函数,可以借鉴引用和引用中提到的两种方法。下面是一个可能的实现: 方法一:使用substr函数(引用) 可以使用字符串的substr函数来截取字符串。substr函数有两个参数,第一个参数是起始位置,第二个参数是截取的长度。例如,如果要从字符串s的下标为2的位置开始截取到末尾,即s.substr(2),则可以得到结果"34"。如果要从字符串s的下标为0的位置开始截取长度为2的字符串,即s.substr(0,2),则可以得到结果"12"。 方法二:按字节截取字符串(引用) 为了保证汉字不被截半个,可以编写一个按字节截取的字符串函数。具体实现步骤如下: 1. 遍历字符串的每一个字符,记录当前位置的字节数,初始值为0。 2. 判断当前字符是否为中文字符。如果是,则字节数加2;如果不是,则字节数加1。 3. 判断当前位置的字节数是否超过了给定的限制。如果超过了,则截取当前位置之前的字符串,即可得到按字节截取的结果。 方法三:使用字符数组(引用) 另一种实现方式是使用字符数组来截取字符串。可以使用C语言中的strncpy函数来实现。strncpy函数有三个参数,第一个参数是目标字符数组,第二个参数是源字符串,第三个参数是截取的长度。例如,可以使用strncpy(s2, s1, n)来将字符串s1中的前n个字符赋值给s2。 根据你的需求,你可以选择其中一种方法来实现截取字符串的函数。希望以上信息对你有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值