代码随想录第8天|字符串

344.反转字符串

在这里插入图片描述
补充知识:

  1. swap函数
    • 用于交换两个变量的值
    • 实现原理:
    • 在这里插入图片描述
  2. ^=
    • 如果两个位相同,则结果为0;如果两个位不同,则结果为1
    • 在这里插入图片描述

思路: 双指针

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

参考代码
在这里插入图片描述


541. 反转字符串II

在这里插入图片描述
在这里插入图片描述
补充知识:
1.reverse函数的使用(操作区间是左闭右开)

		//nums.begin() + 1 = 2
        //nums.begin() + 5 = 6
        //操作区间为左闭右开
        //1 [2 3 4 5] 6 7 8 9 实际操作区间
        //1 [5 4 3 2] 6 7 8 9 结果
        std::reverse(nums.begin() + 1, nums.begin() + 5);

状态:
需要重新回看, 实现存在问题
弄清楚遍历的顺序, i , i + k 和 i + 2k 是关键点

思路: 模拟实现的过程, 不涉及具体的算法

参考代码
在这里插入图片描述


卡码网:54.替换数字

在这里插入图片描述
补充知识:

  1. resize函数
	std::vector<int> vec;
    vec.push_back(10);
    vec.push_back(20);
    
    vec.resize(5);	  	//将vec的大小调整为5,[10, 20, 0, 0, 0]
    vec.resize(6, 1);	//将vec的大小调整为6,[10, 20, 0, 0, 0, 1]
    vec.resize(3); 		//将vec的大小调整为3,[10, 20, 0]
  1. 字符串和数组
    • 很多语言对字符串做了特殊的规定
    • 在C语言中,把一个字符串存入一个数组时,也把结束符 '\0’存入数组,并以此作为该字符串是否结束
    • 在C++中,提供一个string类,string类会提供 size接口,可以用来判断string类字符串是否结束,就不用’\0’来判断是否结束
    • 基本操作上没有区别,但是 string提供更多的字符串处理的相关接口

思路:
主要考虑不用额外的辅助空间实现, 需要用到resize函数调整数组的大小

方法1: 使用额外空间

#include<bits/stdc++.h>
using namespace std;

int main(){
    string str;
    string result = "";
    cin >> str;
    for (int i = 0; i < str.length(); i++) {
        if (str[i] >= '0' && str[i] <= '9') {
            result += "number";
        } else {
            result += str[i];
        }
    }
    cout << result << endl;
    return 0;
}

方法2: 双指针法
状态: 需要细看, 实现存在问题
参考链接
步骤:
1.resize函数扩容
2.双指针从后往前遍历(备注: 从前往后为O(n^2)的时间复杂度, 而且需要额外空间存储)

#include<bits/stdc++.h>
using namespace std;
int main() {
	string str;
	cin >> str;

	//1.遍历一次得需要替换的长度
	int count = 0;
	int size = str.length();
	for (int i = 0; i < size; i++)
	{
		if (str[i] >= '0' && str[i] <= '9') {
			count++;
		}
	}
	//注意调整大小,减去原来的数字位
	str.resize(size + count * 6 - count);

	//从后往前遍历,时间复杂度为O(n)
	//若从前往后遍历,时间复杂度为O(n^2)
	int slow = str.length() - 1;
	for (int fast = size - 1; fast >= 0; fast--)
	{
		if (str[fast] >= '0' && str[fast] <= '9')
		{
			str[slow--] = 'r';
			str[slow--] = 'e';
			str[slow--] = 'b';
			str[slow--] = 'm';
			str[slow--] = 'u';
			str[slow--] = 'n';
		}
		else
		{
			str[slow--] = str[fast];
		}
	}
	cout << str << endl;

}

151.翻转字符串里的单词

在这里插入图片描述
在这里插入图片描述
要求: 空间复杂度为O(1)
在这里插入图片描述

难点: 去除多余的空格
需要重复练习

//若fast指向不为' ', 则用while将该单词一次性录入
//slow除了在0时不插入空格外, 当每次进入s[fast] != ' '时,slow都插入空格
void removeExtraspace(string& s) {
	int slow = 0;
	for (int fast = 0; fast < s.size(); fast++) {
		if (s[fast] != ' ') {
			if (slow != 0) {
				s[slow++] = ' ';
			}
			while (fast < s.size() && s[fast] != ' ') {
				s[slow++] = s[fast++];
			}
		}
	}
	s.resize(slow);
}

//易理解版本
void removeExtraSpaces(string& s) {
	int slow = 0, fast = 0;
	while (fast < s.size() && s[fast] == ' ') {
		fast++;
	}
	for (; fast < s.size(); fast++) {
		if (s[fast] == ' ' && s[fast - 1] == s[fast]) {
			continue;
		}
		else {
			s[slow++] = s[fast];
		}
	}
	if (s[slow - 1] == ' ') {
		s.resize(slow - 1);
	}
	else {
		s.resize(slow);
	}
}

完整实现代码

void removeExtraSpaces(string& s) {
	int slow = 0, fast = 0;
	for (; fast < s.size(); fast++) {
		if (s[fast] != ' ') {
			if (slow != 0) {
				s[slow++] = ' ';
			}
			while (s[fast] != ' ' && fast < s.size())
				s[slow++] = s[fast++];
		}
	}
	s.resize(slow);
}


string str;
int main() {
	getline(cin, str);
	removeExtraSpaces(str);

	reverse(str.begin(), str.end());
	int slow = 0;
	int fast = 0;
	for (;fast <= str.size(); fast++) {
		if (fast < str.size() && str[fast] == ' ') {
			reverse(str.begin() + slow, str.begin() + fast);
			slow = fast + 1;
		}
		if (fast == str.size()) {
			reverse(str.begin() + slow, str.end());
		}
	}
	cout << str << endl;
}

卡码网:55.右旋转字符串

在这里插入图片描述

//最烂的写法
#include<bits/stdc++.h>
using namespace std;
int main() {
    
    int k;
    cin >> k;
    cin.ignore();
    string str;
    cin >> str;

    string str2 = "";
    for (int i = str.length() - k; i < str.length(); i++) {
        str2 += str[i];
    }
    for (int i = 0; i < str.length() - k; i++) {
        str2 += str[i];
    }
    cout << str2 << endl;

    return 0;
}

优化方法:
1.翻转
2.对子串再次翻转

#include<bits/stdc++.h>
using namespace std;

int main() {
	int k;
	cin >> k;
	string str;
	cin >> str;

	reverse(str.begin(), str.end());
	reverse(str.begin(), str.begin() + k);	//前k个字串进行反转
	reverse(str.begin() + k, str.end());	//剩余字串进行反转

	cout << str << endl;
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值