代码随想录算法训练营Day08

文章介绍了C++中的字符串基础知识,包括size(),empty(),append()等函数,并对比了vector与string的区别。接着,文章通过力扣题目展示了字符串操作的应用,如反转字符串、替换空格、反转单词等,并提供了相关解题思路和关键点。
摘要由CSDN通过智能技术生成

Day08字符串

一、字符串基础知识

字符串是若干字符组成的有限序列

字符串相关函数

  1. size() 或 length():返回字符串的长度
  2. empty():判断字符串是否为空,返回布尔值
  3. clear():清空字符串
  4. resize(n, c)(n:新字符串的长度,c:填充的字符):改变字符串的长度,c 为字符填充
  5. reserve(n)(n:字符串预留的内存空间):预留字符串存储空间
  6. append(s) 或 operator+=(s)(s:要添加的字符串):在原字符串末尾添加新字符串
  7. insert(pos, s)(pos:插入位置,s:要插入的字符串):在指定位置插入新字符串
  8. erase(pos, n)(pos:起始位置,n:要删除的字符数):删除字符串中指定位置及其后的字符
  9. replace(pos, n, s)(pos:起始位置,n:要替换的字符数,s:用于替换的字符串):替换字符串中指定位置及其后的字符
  10. substr(pos, n)(pos:起始位置,n:要截取的字符数):截取子字符串
  11. find(s, pos)(s:要查找的字符串,pos:查找起始位置):查找指定字符串在字符串中第一次出现的位置
  12. rfind(s, pos)(s:要查找的字符串,pos:查找起始位置):查找指定字符串在字符串中最后一次出现的位置
  13. compare(s)(s:要比较的字符串):比较两个字符串是否相等
  14. c_str()(无):将字符串转换为 C 风格字符数组,即以空字符 ‘\0’ 结尾的 char 数组
  15. data()(无):返回字符串的底层字符数组指针

vector< char > 和 string 的区别

vector是STL中的一种容器,用于存储一组字符。而string也可以用于存储一组字符,但它是C++标准库提供的字符串类型,提供了更多的字符串操作方法。

以下是vector和string的主要区别:

  1. 功能不同:vector只是一个动态数组容器,用于存储一组字符,而string不仅可以存储一组字符,还提供了很多字符串操作方法,如查找子串、替换等。

  2. 存储方式不同:vector使用动态数组的方式存储字符,而string使用字符数组的方式存储字符,还可以使用指针加速访问操作。

  3. 默认初始化值不同:vector中元素默认初始化为空值(即’\0’),而string默认初始化为一个空字符串

  4. 容量管理不同:vector可以通过调用reserve()方法来预留存储空间,避免不必要的扩容操作,而string内部会自动管理其容量,避免了手动调用reserve()的操作。

  5. 可移植性不同:vector的使用在不同编译器、平台上可能存在一定的差异,而string被广泛支持和使用,具有很好的可移植性。

综上所述,vector和string都可以用于存储一组字符,但针对不同的需求和场景,选择使用不同的类型会更加合适。若只需要基本的字符存储,可以考虑使用vector;若需要进行更多字符串操作,应该使用string。

二、力扣相关例题

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 :
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

解题关键:
双指针

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

541. 反转字符串 II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 :
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”

解题关键:
①这道题意思:每隔k个反转k个,末尾不够k个时全部反转
②掌握reverse的实现!(我最开始就写成reverse(s, i, i+k),reverse只穿入两个参数)

class Solution {
public:
    string reverseStr(string s, int k) {
    	//这里的i是2k的增加,当作一个整体
        for (int i = 0; i < s.size(); i += 2*k) {
        	//若剩余字符大于或等于 k 个,则反转前 k 个字符
            if (i + k <= s.size()) {
                reverse(s.begin() + i, s.begin() + i + k);  
                continue;
            }
            //若剩余字符少于 k 个,则将剩余字符全部反转。
            reverse(s.begin() + i, s.end());
        }
        return s;
    }
};

剑指 Offer 05. 替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 :
输入:s = “We are happy.”
输出:“We%20are%20happy.”

解题关键:
①这道题采用双指针解法:旧指针指向旧字符串的末尾,新指针指向新字符串的末尾
②从末尾填充,时间复杂度较短
这里我看代码随想录的动画非常好,容易理解,文章链接

class Solution {
public:
    string replaceSpace(string s) {
    	//定义olesize指向旧字符串的长度
        int oldsize = s.size();
        int count = 0;
        //统计空格的个数
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == ' ') {
                count++;
            }
        }
        //扩大字符串的长度,每有一个空格,则增加两个空格大小
        //resize()函数可以将字符串变长到指定长度,若小于原字符串的长度,则会截断原字符串
        s.resize(s.size() + count * 2);
        //定义newsize指向新字符串的长度
        int newsize = s.size();
        for (int i = oldsize - 1, j = newsize - 1; i < j; i--, j--) {
        	//如果s[oldsize]等于空格,则在s[newsize]插入'%20'
            if (s[i] == ' ') {
                s[j] = '0';
                s[j - 1] = '2';
                s[j - 2] = '%';
                j = j - 2;
            } else {
                s[j] = s[i];
            }
        }
        return s;
    }
};

151. 反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 :
输入:s = “the sky is blue”
输出:“blue is sky the”

解题关键:
如何删除空余空格:双指针(快慢指针)

class Solution {
public:
    void swapstr(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) {
        int fast = 0;
        int slow = 0;
        //删除多余空格,保证前后无空格,中间无空余空格
        for (fast = 0, slow = 0; fast < s.size(); fast++) {
            if (s[fast] != ' ') {
            	//保证每个单词之间有一个空格,并且开头不能有空格
                if (slow != 0) {
                    s[slow++] = ' ';
                }
                //删除中间多余的空格
                while (fast < s.size() && s[fast] != ' ') {
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                }
            }
        }
        //重新调整字符串大小,改为删除多余空格后的大小
        s.resize(slow);
        //句子前后翻转
        swapstr(s, 0, s.size() - 1);
        //每个单词前后翻转
        for (int right = 0, left = 0; right <= s.size(); right++) {
            if (s[right] == ' ' || right == s.size()) {
                if (s[left] == ' '){
                    left++;
                }
                swapstr(s, left, right - 1);
                left = right;
            }
        }
        return s;
    }
};

剑指 Offer 58 - II. 左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 :
输入: s = “abcdefg”, k = 2
输出: “cdefgab”

解题关键:
找规律,理解怎么翻转(局部、全部)才能得到最终结果
在这里插入图片描述

class Solution {
public:
	//构造翻转函数
    void reverse_string(string& s, int start, int end) {
        int right = end;
        int left = start;
        for (; left < right; left++, right--) {
            swap(s[left], s[right]);
        }
    }
    string reverseLeftWords(string s, int n) {
    	//翻转区间为n的子串
        reverse_string(s, 0, n - 1);
        //翻转n到末尾的子串
        reverse_string(s, n, s.size() - 1);
        //整体翻转
        reverse_string(s, 0, s.size() - 1);
        return s;
    }
};

今日较简单,加油加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值