前言
字符串篇,继续。
记录 二十二【替换数字】(非力扣网题目)
一、题目阅读
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
输入:一个字符串 s,s 仅包含小写字母和数字字符。
输出:打印一个新的字符串,其中每个数字字符都被替换为了number
示例一:
输入 :"a1b2c3";
输出: "anumberbnumbercnumber"。
示例二:
输入:"a5b"
输出: "anumberb"
示例三:
输入:"a189bc256"
输出:"anumbernumbernumberbcnumbernumbernumber"
提示:
数据范围:1 <= s.length < 10000。
二、尝试实现
(1)发现替换成number后,字符串长度发生变化,所以如果正向检查并替换,还得移动后面的字符,比较麻烦。
(2)所以想用一个新的string,重新填充,返回这个新string。
(3)判断是字母还是数字?
- 注意:每个数字字符都替换成number,初始误以为数字替换成number。
- 错误认为示例三:输入:"a189bc256";输出:"anumberbcnumber"。把189和256当成一个数字。而不是每个数字字符。
代码实现
cpp
#include <iostream>
#include <string>
using namespace std;
string numberSwap(string s){
int num = 0;
string result;
for(int i = 0;i < s.size();i++){
if(s[i] - 'a' >= 0){ //判断这个位置是字母
result.push_back(s[i]);
}else{
result.insert(result.size(),"number");
}
}
return result;
}
int main(){
string s;//获取输入的字符串
cin>>s;
string s_swap = numberSwap(s);
cout<<s_swap;//输出转换过的字符串
return 0;
}
总结:用额外的string数组空间来处理。如果想原地处理呢?
三、新思路学习
原地操作string,在原来的基础上操作string。(双指针法------针对数组。string也是字符数组。)
(1)上面说"正向检查并替换,还得移动后面的字符,比较麻烦"。那就先扩容,找出string中所有的数字字符,先增加数组长度,能容纳替换成number之后的string。
(2)正向不行,倒着检查并移动替换。
- 如果是字母,直接移动后面;
- 如果是数字,后面指针向前覆盖填充number。
代码实现
按照新思路实现
cpp
#include <string>
#include <iostream>
using namespace std;
void numberSwap(string& s){
int size = s.size();
int count = 0;//计数数字有几个
for(int i = 0;i < size;i++){
if(s[i] >= '0' && s[i] <='9'){
count++;
}
}
s.resize(size+count*5);//覆盖填充,所以原本的数字的位置也可以用
//双指针开始
for(int i = s.size()-1,j = size-1;j >= 0 ; i--,j--){ //i是新数组的末尾,j是原来数组的末尾
if(s[j] >= '0' && s[j] <='9' ){ //数字
s[i--] = 'r'; //先赋值再--
s[i--] = 'e';
s[i--] = 'b';
s[i--] = 'm';
s[i--] = 'u';
s[i] = 'n';
}else{ //字母
s[i] = s[j];
}
}
}
int main(){
string s;
cin>>s;
numberSwap(s);
cout<<s;
return 0;
}
总结
替换填充、覆盖操作。先扩容再倒着先前完成。
(欢迎指正,转载表明出处)