代码随想录 字符串 卡码 替换数字
题目链接:https://kamacoder.com/problempage.php?pid=1064
文章讲解:https://programmercarl.com/kamacoder/0054.替换数字.html
题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为 number。
例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。
对于输入字符串 "a5b",函数应该将其转换为 "anumberb"
输入:一个字符串 s,s 仅包含小写字母和数字字符。
输出:打印一个新的字符串,其中每个数字字符都被替换为了 number
样例输入:a1b2c3
样例输出:anumberbnumbercnumber
数据范围:1 <= s.length < 10000。
思路
首先应该遍历找到所有数字的个数,然后进行数组(字符数组)扩容,扩容多少倍?因为要去掉数字加上'number',所以是加上 5*数字的个数。
扩容完成后,遍历到第一个数字后将'number'替换上然后后面所有的字符向后移动 5 位吗?这样就成了 On2 的时间复杂度了,有没有更好的办法?
其实,对于字符串中的移位操作,使用双指针法是常用的做法。
头指针开始指向字符串中的最后移位,依次向前遍历,查找需要替换的数字元素,尾指针负责填充元素(包括需要替换的数字字符和原字母字符。这样保证了替换后的字符串的正确顺序。
参考代码
cpp
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s;
while (cin >> s)
{
int sleft = s.size() - 1;
int count = 0;
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
count++;
}
}
s.resize(s.size() + count * 5);
int sright = s.size() - 1;
while (sleft >= 0)
{
if (s[sleft] >= '0' && s[sleft] <= '9')
{
s[sright--] = 'r';
s[sright--] = 'e';
s[sright--] = 'b';
s[sright--] = 'm';
s[sright--] = 'u';
s[sright--] = 'n';
} else {
s[sright--] = s[sleft];
}
sleft--;
}
cout << s << endl;
}
}
Tips
- 判断数字字符时,需要使用
s[sleft] >= '0' && s[sleft] <= '9'
,而不是普通数字,即使是关系运算符,也能比较非数字---字符,因为字符的本质是 ASCII 对应的整数,其实比较的是整数。