【代码随想录】day8|字符串part1

一级目录

二级目录

三级目录

复习用tip

344.反转字符串

题目链接

class Solution {
public:
    void reverseString(vector<char>& s) {
        // reverse(s.begin(),s.end());
        for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
            swap(s[i],s[j]);
        }

    }
};

541. 反转字符串II

题目链接
谨慎用s[i]作终止条件

    void my_reverse(string& s,int begin,int end) {//index     
        for (int i = begin, 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)){
            if(i+k-1<s.size()-1){
                my_reverse(s,i,i+k-1);
            }else{
                my_reverse(s,i,s.size()-1);
            }            
        }
        return s;

    }

卡码网:54.替换数字

题目链接
关键思路是注意重新申请空间,且替换数字时从后往前

#include<iostream>
#include<string>
using namespace std;
int main(){
    string s;
    while(cin>>s){
        int count{0},oldsize=s.size();//数字数量,原长度
        for(int i=s.size()-1;i>=0;i--){
            if(s[i]<='9'&&s[i]>='0'){
                count++;
            }
        }
        s.resize(s.size()+count*5);
        int newsize=s.size();
        for (int i = newsize - 1, j = oldsize - 1; j < i; i--, j--){
            if(s[j]<='9'&&s[j]>='0'){
                s[i]='r';
                s[i-1]='e';
                s[i-2]='b';
                s[i-3]='m';
                s[i-4]='u';
                s[i-5]='n';
                i-=5;
            }else{
                s[i]=s[j];
            }
            
        }
        cout<<s;
    }
    
    
}

151.翻转字符串里的单词

题目链接

    void removeSpace(string& s) {
        string ret = "";
        int i = 0;
        while (s[i] == ' ')
            i++; // 去除前导空格
        for (; s[i]; i++) {
            while (i > 0 && s[i] == s[i - 1] && s[i - 1] == ' ' && s[i + 1]) { // 去除单词间的空格
                i++;
            }
            if (s[i])
                ret += s[i];
        }
        while (ret[ret.size() - 1] == ' ') {
            ret[ret.size() - 1] = 0;
            ret.resize(ret.size() - 1);
        }
        s = ret;
    }
    // 反转字符串s中左闭右闭的区间[start, end]
    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) {        
        removeSpace(s);// 先去除多余空格
        reverse(s,0,s.size()-1);//全部反转
        // cout<<s<<endl;
        int start=0;
        for(int i=0;i<=s.size();i++){//局部反转
            if(s[i]==' '||s[i]==0){
                reverse(s,start,i-1);
                // cout<<s<<endl;
                start=i+1;
            }            
        }
        return s;
    }

优化:代码随想录的双指针法去重复空格:

//版本一 
void removeExtraSpaces(string& s) {
    int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
    // 去掉字符串前面的空格
    while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
        fastIndex++;//fast先找到第一个非空格位
    }
    for (; fastIndex < s.size(); fastIndex++) {
        // 去掉字符串中间部分的冗余空格
        if (fastIndex - 1 > 0
                && s[fastIndex - 1] == s[fastIndex]
                && s[fastIndex] == ' ') {
            continue;
        } else {
            s[slowIndex++] = s[fastIndex];
        }
    }
    if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') { // 去掉字符串末尾的空格
        s.resize(slowIndex - 1);
    } else {
        s.resize(slowIndex); // 重新设置字符串大小
    }
}
// 版本二 
void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间添加空格, 快慢指针。
    int slow = 0;   //整体思想参考https://programmercarl.com/0027.移除元素.html
    for (int i = 0; i < s.size(); ++i) { //
        if (s[i] != ' ') { //遇到非空格就处理,即删除所有空格。
            if (slow != 0) s[slow++] = ' '; //手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。
            while (i < s.size() && s[i] != ' ') { //补上该单词,遇到空格说明单词结束。
                s[slow++] = s[i++];
            }
        }
    }
    s.resize(slow); //slow的大小即为去除多余空格后的大小。
}

卡码网:右旋字符串

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
    int n;
    string s;
    cin >> n;
    cin >> s;
    int len = s.size(); //获取长度
    reverse(s.begin(), s.end()); // 整体反转
    reverse(s.begin(), s.begin() + n); // 先反转前一段,长度n
    reverse(s.begin() + n, s.end()); // 再反转后一段
    cout << s << endl;

} 
// 版本二 
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
    int n;
    string s;
    cin >> n;
    cin >> s;
    int len = s.size(); //获取长度
    reverse(s.begin(), s.begin() + len - n); // 先反转前一段,长度len-n ,注意这里是和版本一的区别
    reverse(s.begin() + len - n, s.end()); // 再反转后一段
    reverse(s.begin(), s.end()); // 整体反转
    cout << s << endl;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值