目录
前言
string是C++风格的字符串,而string本质是一个类。char* 是一个指针,string是一个类,类内部封装了char* ,管理这个字符串,是一个char*型的容器
一、字符串函数用法
1.1访问字符串内容
- size(): 返回字符串的长度
- empty(): 判断字符串是否为空
- operator[]: 用于访问某个字符,下标从0开始
- front(): 返回字符串的第一个字符
- back(): 返回字符串的最后一个字符
1.2修改字符串
append(): 将一个字符串添加到另一个字符串的末尾
insert(): 在指定位置插入一个字符串 || 可用push_back平替
s.insert(1,1,'');//在索引1位置,插入1一个元素''
clear(): 删除所有字符
append():将目标字符串插入到当前字符串的末尾 || 直接+=亦可
s.append(aimstr);
1.3查找和比较
- find(str,num):在num的索引位置开始寻找指定字符串 ,存在则返回字符串的第一个字符的位置,不存在则返回-1
- rfind(): 在字符串中查找指定子串,返回子串最后一次出现的位置
- find_first_of(): 在字符串中查找给定字符集的第一个匹配字符的位置
- find_last_of(): 在字符串中查找给定字符集的最后一个匹配字符的位置
- compare(): 比较两个字符串的大小,返回0表示两个字符串相等
1.4 区间翻转
- reverse(str.begin(),str.end()):反转字符串--(左闭右开)
- reverse(vector.begin(),vector.end()) :反转向量
- reverse(a,a+strlen(a)) :反转数组
- reverse():数组全部翻转
1.5 其他
substr(): 返回指定位置开始的指定长度的子串
s.substr(start,singleCount);
swap(): / swap(x1,x2):可以实现交换容器中的元素,当然也可以进行容器间的互换(互换所有元素)
使用vector<char> s也可以实现字符串的效果
resize(x):替换字符串长度为x
二、经典力扣题目
2.1 反转字符串 344
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
class Solution {
public:
void reverseString(vector<char>& s) {
int SizeNum = s.size();
for(int i=0,j=SizeNum-1;i<SizeNum/2;i++,j--){
swap(s[i],s[j]);
}
}
};
题解:
翻转字符串,其实就等于将所有元素的位置互换,即使是奇数,最中间的是不会被影响的存在。
用到了库函数swap,实现O(1)空间复杂度
库函数swap:可以从位置上交换两个元素
2.2 反转字符串II 541
2.2.1 题目和题解
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=(2*k)){
//注意2*k
if(i+k <= s.size()){
//因为在当前状态下,i还没有等于i+2k
reverse(s.begin()+i,s.begin()+i+k);
continue;
}
//说明剩余的字符少于k
reverse(s.begin()+i,s.end());
}
return s;
}
};
题解:
reverse()会将区间[beg,end)内的元素全部逆序;--记住是左闭右开!
在这个示例中,str.begin() + 1
表示字符串中的第二个字符的迭代器。str.end()
表示字符串末尾的迭代器,reverse()
函数将范围从第二个字符开始到末尾的字符进行反转
2.2.2 reverse函数用法
reverse(str.begin(),str.end()) 反转字符串
请注意,reverse()
函数会修改原始字符串,使得指定范围内的字符反转
在C++中,reverse()
是一个算法函数,用于反转指定范围内的元素顺序
2.2.3 迭代器
在C++中,str.begin()
返回一个迭代器,指向std::string
容器的第一个字符。
迭代器:是一种对象,类似于指针,可以用于遍历容器中的元素。
举例:
auto it = str.begin(); // 获取指向第一个字符的迭代器
char first_char = *it; // 通过解引用操作符获取迭代器it指向的元素
(还有2*k注意一下,容易敲着敲着忘了加乘号)
2.3 反转字符串中的单词 151
给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue
" 输出:"blue is sky the
"
class Solution {
public:
string reverseWords(string s) {
//此题是在原来字符串上进行修改,空间复杂度为O(1)
int fast=0;
int slow=0;
reverse(s.begin(),s.end());
//去除空格--规整化
for(;fast<s.size();fast++){
if(s[fast]!=' '){
if(slow!=0){
//第一个元素一定不能为空格
//之后每个单词后加一个空格
s[slow++]=' ';
}
//遍历完一整个单词
while(fast<s.size()&&s[fast] != ' '){
s[slow]=s[fast];
//同时移动同时赋值
fast++;
slow++;
}
}
}
s.resize(slow);
//翻转内部单词
for(fast=0,slow=0;fast<=s.size();++fast){
if(fast == s.size() ||s[fast] == ' '){
//reverse是左闭右开!!大部分的库函数都是这样
reverse(s.begin()+slow,s.begin()+fast);
slow = fast+1;//成为下个单词的开头
}
}
return s;
}
};
题解:
思路是,先用双指针,把多余的空格全部去除(先去除所有空格,然后自己添加空格在每个单词后),标准化字符串。然后再逆序字符串,之后再对每一个单词单独逆序,最后输出输入的字符串。空间复杂度O(1) 。
注:这道题做了一段时间,一直没有反转成功,后来检查了半天才发现,reverse是左闭右开的,就是说fast对应的是空格的时候,s.begin()+fast-1其实对应的正好是单词最后一个字符,但是reverse中不需要再-1了,因为开区间。还有一个没有发现bug的原因,是测试用例一开始都是3、5长度的单词,呃这其实不容易发现上面那个问题的!
resize 函数 是一个替换字符串长度的函数
2.4 重复的子字符串 459
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成
class Solution {
public:
bool repeatedSubstringPattern(string s) {
//拼接字符串,可重复构成的前提是,必有字符串处处相等 abab满足--ababababab,从b开始查
string ss = s+s;
if(ss.find(s,1) != s.size()){
//如果从第一个字符开始查找,返回找到的字符串的第一个真子集的索引
//如果索引恰好等于长度,说明在自身查找了一遍都没有可以和后面连起来的
return true;
}else{
return false;
}
}
};
题解:
如果内部是有子字符串组成的,那么把本身和本身连起来,中间一定存在可以联系起来的字符串,它们可以组成字符串,这题使用的就是这个思想
连接字符串 +
寻找字符串并且返回找到第一个真子集字符串的索引 s.find(str,0)--默认从第0个开始寻找