题干
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
对于输入字符串 "a5b",函数应该将其转换为 "anumberb"
输入:一个字符串 s,s 仅包含小写字母和数字字符。
输出:打印一个新的字符串,其中每个数字字符都被替换为了number
样例输入:a1b2c3
样例输出:anumberbnumbercnumber
解题思路
本题和删除元素的思路有点相似都是要在原有空间的基础上修改,所以我们也想要覆盖建立新的字符串。依旧是双指针的思想。
快指针去探查军情,慢指针安营扎寨。
两个指针先指向首元素,快指针发现是字符,慢指针前进一个。
快指针前进一个,发现是数字,在慢指针索引插入number,但是没有足够放下number的空间,如果想要创造空间就需要将数组整体往后移,很麻烦而且时间复杂度高
本题很巧妙的思路是把所需要的空间扩充好后,从后面重新开始倒序建立字符串,这样空间就足够了,不可谓不妙。
思路还是相似的,快指针指向旧数组末端,探查军情,慢指针指向新数组末端。如果快指针指到字母,就把字母传给慢指针的位置,如果快指针指到数字,慢指针就移动将number输入到字符串。
完整代码如下
while(cin >> s) 为大循环,可以不断输入字符串得到结果
#include <iostream>
using namespace std;
int main() {
string s;
while (cin >> s) {
//让快指针指向旧字符串的后端
int fast = s.size() - 1;
//计算字符串中数字的大小
int count = 0;
for(int i = 0; i < s.size(); i++){
//遇到数字,count加一
if(s[i] >= '0' && s[i] <= '9'){
count++;
}
}
//填充所需的空间,因为数字的位置会被取代,所以为6-1=5
s.resize(s.size() + count * 5);
//建立快指针
int slow = s.size() - 1;
//建立新数组,直到快指针左越界
while(fast >= 0){
//如果快指针指向的是数字
if(s[fast] >= '0' && s[fast] <= '9'){
//倒序填充number
s[slow--] = 'r';
s[slow--] = 'e';
s[slow--] = 'b';
s[slow--] = 'm';
s[slow--] = 'u';
s[slow--] = 'n';
}
//如果是字母,把字母填在慢指针的位置上
else{
s[slow--] = s[fast];
}
fast--;
}
cout << s << endl;
}
}