No. 06 替换空格
问题描述: 请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
示例:
输入:s = "We are happy." 输出:"We%20are%20happy."
思路1:运用replace函数,其中.find()函数如果没有查询到结果会返回-1,关于repalce的具体用法见C++ replace() 函数用法详解_用心倾听的博客-CSDN博客_c++ replace函数本文主要针对c++中常用replace函数用法给出样例程序[cpp] view plain copy/*用法一: *用str替换指定字符串从起始位置pos开始长度为len的字符 *string& replace (size_t pos, size_t len, const string& str); */ int mahttps://blog.csdn.net/jiary5201314/article/details/52502516/
代码:
class Solution {
public:
string replaceSpace(string s) {
// for(int i=0;i<s.size();i++){
// if(s[i]==' '){
// s[i]='%20';
// }
while(s.find(' ')!=-1){
s=s.replace(s.find(' '),1,"%20");
}
return s;
}
};
思路2:原地修改, string 被设计成「可变」的类型(参考资料),因此可以在不新建字符串的情况下实现原地修改。
由于需要将空格替换为 "%20" ,字符串的总字符数增加,因此需要扩展原字符串 s 的长度,计算公式为:新字符串长度 = 原字符串长度 + 2 * 空格个数
算法流程:
1. 初始化:空格数量 count ,字符串 s 的长度 len ;
2. 统计空格数量:遍历 s ,遇空格则 count++ ;
3. 修改 s 长度:添加完 "%20" 后的字符串长度应为 len + 2 * count ;
4. 倒序遍历修改:i 指向原字符串尾部元素, j 指向新字符串尾部元素;当 i = j 时跳出(代表左方 已没有空格,无需继续遍历);
当 s[i] 不为空格时:执行 s[j] = s[i] ;
当 s[i] 为空格时:将字符串闭区间 [j-2, j] 的元素修改为 "%20" ;由于修改了 3 个元素, 因此 需要 j -= 2 ;
5. 返回值:已修改的字符串 s ;
代码:
class Solution {
public:
string replaceSpace(string s) {
int count = 0, len = s.size();
// 统计空格数量
for (char c : s) {
if (c == ' ') count++;
}
// 修改 s 长度
s.resize(len + 2 * count);
// 倒序遍历修改
for(int i = len - 1, j = s.size() - 1; i < j; i--, j--) {
if (s[i] != ' ')
s[j] = s[i];
else {
s[j - 2] = '%';
s[j - 1] = '2';
s[j] = '0';
j -= 2;
}
}
return s;
}
};
No. 07 左旋转字符串
问题描述:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例:
输入: s = "abcdefg", k = 2 输出: "cdefgab"
出现的问题:如下编写代码后出现下标过界的问题,但是erase方法应当不会改变容器大小啊,问什么会过界嘞。
class Solution {
public:
string reverseLeftWords(string s, int n) {
string a;
for(int i=0;i<n;i++){
a[i]=s[i];
}
for(int i=0;i<s.size()-n;i++){
s[i]=s[i+n];
}
string::iterator it=s.begin();
for(int i=0;i<s.size()-n;i++){
it++;
}
for(int i=0;i<n;i++){
s.erase(it);
}
for(int i=0;i<n;i++){
s[s.size()+i]=a[i];
}
return s;
}
};
官方答案:
方法一:利用substr函数进行字符串的切分与拼接
代码:
class Solution {
public:
string reverseLeftWords(string str,int n){
if(str.size()==0) return str;
string s = str.substr(0,n);
string res = str.substr(n,str.size()-n) + s;
return res;
}
};
备注:substr(int a,int b) 从第a个位置截取b个元素(注:当a等于0或1时,都是从第一位开始截取)
方法二:局部翻转+整体翻转
解题思路:首先翻转str[:n]子串,其次翻转str[n:]子串,最后翻转str.
主要思路:
反转区间为前n的子串
反转区间为n到末尾的子串
反转整个字符串
代码:
class Solution {
public:
string reverseLeftWords(string s, int n) {
/* 反转n前面的字符串 */
reverse(s.begin(), s.begin() + n);
/* 反转n后面的字符串 */
reverse(s.begin() + n, s.end());
/* 反转整个字符串 */
reverse(s.begin(), s.end());
return s;
}
};