代码随想录_字符串

6.1 反转字符串

采用双指针进行翻转。可以通过字符串下标进行索引,也可以直接使用指针进行索引。

class Solution {
public:
    void reverseString(vector<char>& s) {
        // char*left = &s[0];
        // char*right = &s[s.size()-1];
        // while(right>left){
        //     char tmp = 0;
        //     tmp = *left;
        //     *left = *right;
        //     *right = tmp;
        //     left++;
        //     right--;
        // }
        for(int i=0,j=s.size()-1;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }
};
6.2 反转字符串②

for循环步长确定为 i += (2*k);每次增加2k长度,
题目要求:
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
按照2k步长增加,剩余字符一定是小于,<=2k,因此循环中只需要判断剩余字符大于等于k还是小于k。
if(i+k < s.size()) 与 if(i+k <= s.size())都能通过

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i =0;i<s.size();i+=(2*k)){
            //1.每隔2k个字符的前k个字符反转
            //2.剩余字符小于2k,但大于等于k,则反转前k个
            if(i+k < s.size()){
                reverse(s.begin()+i,s.begin()+i+k);
            }
            else{
                reverse(s.begin()+i,s.end());
            }
        }
        return s;
    }
};

可以自己实现一下 reverse 方法

class Solution {
public:
    void reverse(string &s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=(2*k)){
            //1.每隔2k个字符的前k个字符反转
            //2.剩余字符小于2k,但大于等于k,则反转前k个
            if(i+k <= s.size()){
                reverse(s,i,i+k-1);
                continue;
            }
            reverse(s,i,s.size()-1);
        }
        return s;
    }
};

while循环实现
这个反转字符串,就两个规则,一个是pos一次增加2*k个,将字符串切成一段一段区间。另一个就是判断这个区间内剩余元素是否够k个,够的话就前k个交换,不够的话,区间内所有元素交换。

class Solution {
public:
    string reverseStr(string s, int k) {
        int pos = 0, n = s.size();
        while(pos<n){
            if(pos+k < n){
                reverse(s.begin()+pos,s.begin()+pos+k);
            }
            else(reverse(s.begin()+pos,s.end()));
            pos+=2*k;
        }
        return s;
    }
};
6.3 替换数字

很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
cin用来输入,记录老字符串的长度,然后通过for循环对数字进行计数。
扩充字符串长度,number长度为6,数字本身有一个位置,所以cnt*5即可。
双指针开始后移扩充。

#include <iostream>
using namespace std;
int main(){
    string s;
    while(cin >> s){
        int cnt = 0;
        int soldsize = s.size();
        for(int i = 0;i < s.size();i++){
            if(s[i]>='0'&&s[i]<='9'){
                cnt++;
            }
        }
        s.resize(soldsize+cnt*5);//空格的地方替换成number
        int snewsize = s.size();
        for(int i = soldsize-1,j = snewsize-1;i<j;i--,j--){
            if(s[i]>'9'||s[i]<'0'){
                s[j] = s[i];
            }
            else{
                s[j] = 'r';
                s[j-1] = 'e';
                s[j-2] = 'b';
                s[j-3] = 'm';
                s[j-4] = 'u';
                s[j-5] = 'n';
                j-=5;
            }
        }
        cout << s << endl;
    }
}
6.4.1 翻转字符串里的单词_版本1

首先将所有内容全部翻转,双指针快速交换。
然后去除多余的空格,双指针,fast先遍历字符串前面的空格,直到fast拿到第一个字符
然后开始往slow中传值,slow自加,fast遇到字符串中间的空格时,跳出本次循环开始下次循环。
字符串末尾空格处理。

class Solution {
public:
    void removeExtraSpace(string& s){
    	
    }
    void reverse(string& s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }
    string reverseWords(string s){
        reverse(s,0,s.size()-1);
        removeExtraSpace(s);
        int start = 0;
        for(int i=0;i<=s.size();i++){
            if(i == s.size() || s[i] ==' '){
                reverse(s,start,i-1);
                start = i+1;
            }
        }
        return s;
    }
};
6.4.2 翻转字符串里的单词_版本2

与版本1的不同为:removeSpace写的更加精简,也是双指针,slow必须要赋初值为0。

class Solution {
public:
    void removeExtraSpace(string& s){
        int slow = 0;
        for(int i=0;i<s.size();i++){
            if(s[i] != ' '){
                if(slow != 0) s[slow++] = ' ';
                while(i<s.size() && s[i] != ' '){
                    s[slow++] = s[i++];
                }
            }
        }
        s.resize(slow);
    }
    void reverse(string& s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            swap(s[i],s[j]);
        }
    }
    string reverseWords(string s){
        reverse(s,0,s.size()-1);
        removeExtraSpace(s);
        int start = 0;
        for(int i=0;i<=s.size();i++){
            if(i == s.size() || s[i] ==' '){
                reverse(s,start,i-1);
                start = i+1;
            }
        }
        return s;

    }
};
6.5 右旋字符串

题目要求为:给定字符串s和数字n,将倒数第n个字符到最后一个字符组成的字符串拼接到最前面。
方法:整体翻转+局部翻转
类似的题目:左旋字符串

#include <iostream>
#include<algorithm>
using namespace std;
void reverse(string& s,int start,int end){
    for(int i=start,j=end;i<j;i++,j--){
        swap(s[i],s[j]);
    }
}
int main(){
    int n;
    string s;
    cin >> n;
    cin >> s;
    reverse(s,0,s.size()-1);
    reverse(s,0,n-1);
    reverse(s,n,s.size()-1);
    cout<<s<<endl;  
}
6.6 实现strStr()

当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
这部分确实有点儿难度,先过吧,后面有机会再琢磨。

class Solution {
public:
    void getNext(int* next,const string& s){
        int j = -1;
        next[0] = j;
        for(int i=1;i<s.size();i++){
            while(j>=0 &&s[i] != s[j+1] ){
                j = next[j];//向前回退
            }
            if(s[i] == s[j+1]){
                j++;
            }
            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) {
        if(needle.size() == 0){
            return 0;
        }
        int next[needle.size()];
        getNext(next,needle);
        int j = -1;
        for(int i=0;i<haystack.size();i++){
            while(j>=0 && haystack[i] != needle[j+1]){
                j = next[j];
            }
            if(haystack[i] == needle[j+1]){
                j++;
            }
            if(j == needle.size()-1){
                return (i-needle.size() + 1);
            }
        }
        return -1;

    }
};
6.7 重复的子字符串
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值