专题:字符串(已完结)

1.反转字符串

class Solution {
public:
    void reverseString(vector<char>& s) {
        int i =0;
        int j= s.size()-1;
        while(i<j){
            char tmpc = s[i];
            s[i]=s[j];
            s[j]=tmpc;
            i++;
            j--;
        }
    }
};

2.反转字符串II
方法一:双指针法 每次都遍历j 每次遍历的时候 j++,j如果是k的倍数 在看m m是决定是否反转
方法一:双指针法 每次都遍历j=j+2k,每次操作(j,j+k-1)进行翻转 当然如果超过数据长度 剩余的进行翻转即可

方法一:

class Solution {
    void reverseStr(string &s,int i,int j){
        while(i<j){
         char temp = s[i];
         s[i]=s[j];
         s[j]=temp;
         i++;
         j--;
        }
    }
public:
    string reverseStr(string s, int k) {
        int i=0;
        int m =0;
        for(int  j=0;j<s.size();j++){
          if((j+1)%k==0){
            if(m%2==0){
               // 需要将前k个进行交换
               reverseStr(s,i,j);
               cout<<"   i"<<i<<"  j"<<j<<endl;
            }else{
                // 不需要交换前k个
            }
            m++;
            i=j+1;
          }else if(j==s.size()-1&&m%2==0){
            // 发现不足k个 并且需要反转
            reverseStr(s,i,j);
          }
        }
        return s;
    }
};

方法二:

class Solution {
    void reverseStr(string &s,int i,int j){
        while(i<j){
         char temp = s[i];
         s[i]=s[j];
         s[j]=temp;
         i++;
         j--;
        }
    }
public:
    string reverseStr(string s, int k) {
        int i=0;
        int m =0;
        for(int  j=0;j<s.size();j=j+2*k){
            if(j+k-1>=s.size()){
                reverseStr(s,j,s.size()-1);
            }else{
                reverseStr(s,j,j+k-1);
            }
        }
        return s;
    }
};

移除元素(为下面的翻转字符串里的单词做铺垫 双指针移除多余空格)

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left =0;
        for(int right =0;right<nums.size();right++){
            if(nums[right]!=val){
                nums[left]=nums[right];
                left++;
            }
        }
        return left;
        
    }
};

3.翻转字符串里的单词
主要思路 :
1.先去除所有多余空格(先去首空格 然后 中间空格以及尾部保留一个即可,尾空格再次判断一下即可 最后通用resize从新改变字符串的长度)
2.遍历翻转 遇见空格就翻转 但是最后单词是没有翻转的机会的 直接判断一下即可
完整代码如下:

class Solution {
public:
    void removeExtraSpaces(string& s) {
        int slow =0;
        bool needspace =false;
        for(int fast =0;fast<s.size();fast++){
            if(s[fast]!=' '){
                s[slow++]=s[fast];
                needspace = true;
            }else if(s[fast]==' '&&needspace==true){
                s[slow++]=' ';
                needspace = false;
            }
        }
        // 最后一个位置 可能是空的
        if(s[slow-1]==' '){
            s.resize(slow-1);
        }else{
             s.resize(slow);
        }
    }

    string reverseWords(string s) {
        removeExtraSpaces(s); //去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。
        reverse(s.begin(),s.end());
        int slow = 0;
        for(int fast =0;fast<s.size();fast++){
            if(s[fast]==' '){
                reverse(s.begin()+slow,s.begin()+fast);
                slow=fast+1;
            }
            // 明显还剩最后一个单词
            if(fast==s.size()-1){
                 reverse(s.begin()+slow,s.end());
            }
        }
        return s;
    }
};

4.实现strStr()
见kmp算法章节
5.重复的子字符串
见kmp算法章节

补充字符串题目:
两个大数相加

class Solution {
public:
    string addStrings(string num1, string num2) {
        int len1 = num1.size();
        int len2 = num2.size();

        if(len1>len2){
            int gab = len1-len2;
            while(gab--){
                num2="0"+num2;
            }
        }else if(len1<len2){
            int gab = len2-len1;
            while(gab--){
                num1="0"+num1;
            }
        }
        cout<<num1<<"  "<<num2<<endl;
        string ret="";
        int ok=0;
        for(int i=num1.size()-1;i>=0;i--){
            int temp= num1[i]-'0'+num2[i]-'0'+ok;
            if(temp>9){
                temp=temp%10;
                ret=to_string(temp)+ret;
                ok=1;
            }else{
              ok=0;
              ret=to_string(temp)+ret;
            }

        }
        if(ok==1){
            ret="1"+ret;
        }
        return ret;
        
    }
};

两个字符串的16进制加法

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include<string>
#include <cassert>

using namespace std;
class Solution {
    int getIntFomChar(char c) {
        if (c>='0'&& c <= '9') {
            return c - '0';

        }
        else if (c >= 'a' && c <= 'z') {
            return c - 'a' + 10;

        }
        cout << "异常数据" << endl;
        return -1;

    }
    
public:
    string addStrings(string num1, string num2) {
        string symbol = "0123456789abcdefghijklmnopqrstuvwxyz";
        cout << symbol.size() << endl;
        int len1 = num1.size();
        int len2 = num2.size();

        if (len1 > len2) {
            int gab = len1 - len2;
            while (gab--) {
                num2 = "0" + num2;
            }
        }
        else if (len1 < len2) {
            int gab = len2 - len1;
            while (gab--) {
                num1 = "0" + num1;
            }
        }
        cout << num1 << "  " << num2 << endl;
        string ret = "";
        int ok = 0;
        for (int i = num1.size() - 1; i >= 0; i--) {
            int temp = getIntFomChar(num1[i])  + getIntFomChar(num2[i]) + ok;
            if (temp > 35) {
                temp = temp % 36;

                ret = symbol[temp] + ret;
                ok = 1;
            }
            else {
                ok = 0;
                ret = symbol[temp] + ret;
            }

        }
        if (ok == 1) {
            ret = "1" + ret;
        }
        return ret;

    }
};

int main() {
    string num1 = "109z";
    string num2 = "11";
    Solution s;
    auto ret = s.addStrings(num1, num2);
    cout << ret << endl;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值