替换数字 卡码54

0 阅读3分钟

卡码 54 替换数字

题目描述

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

输入示例

a1b2c3

输出示例

anumberbnumbercnumber

提示信息

数据范围:
1 <= s.length < 10000


新建字符串法

通过新建结果字符串,逐个遍历原字符,字母直接追加,数字追加"number"

✅新建字符串法的完整代码:

#include <iostream>
#include <string>
using namespace std;
int main() {
  string s;
  cin >> s;
  string res;
  for (char c : s) {
    if (isdigit(c)) {
      res += "number";
    } else {
      res += c;
    }
  }
  cout << res << endl;
  return 0;
}

核心思路

  • 新建结果字符串 res ,用于不断存储替换后的结果
  • for 循环遍历原字符串,逐个判断各字符
  • 如果当前字符为数字,res 追加 number,其中数字判断通过 isdigit 函数
  • 如果当前字符为小写字母,则 res 追加原字符
  • 最后输出 res 结果字符串

关于代码中的 for(char c : s)

这种写法是C++11的写法,实际上与普通for循环是等效的,只是更为简洁,如下:

// 普通for循环写法
for(int i = 0;i < s.size();i++){
	char c = s[i];
}

// C++11标准下for循环写法
for(char c : s){}

新建字符串法的优点在于简洁易懂,代码更容易,但缺点开辟了新字符串内存


双指针法

要想原地实现替换,就需要使用双指针法

核心思路是先扩充数组,然后利用双指针,一前一后分别从后向前遍历数组并不断按要求完成替换,原理如下:

替换数字  54 (卡码)_20260802_111837.png

✅双指针法的完整代码:

#include <iostream>
using namespace std;
int main() {
    string s;
    while (cin >> s) {
        int sOldIndex = 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 sNewIndex = s.size() - 1;
        while (sOldIndex >= 0) {
            if (s[sOldIndex] >= '0' && s[sOldIndex] <= '9') {
                s[sNewIndex--] = 'r';
                s[sNewIndex--] = 'e';
                s[sNewIndex--] = 'b';
                s[sNewIndex--] = 'm';
                s[sNewIndex--] = 'u';
                s[sNewIndex--] = 'n';
            } else {
                s[sNewIndex--] = s[sOldIndex];
            }
            sOldIndex--;
        }
        cout << s << endl;      
    }
}

为什么是从后往前填充而不是从前往后?

核心原因在于从前向后填充就是 O(n2)O(n^2) 的算法了,因为每次添加元素都要将添加元素之后的所有元素整体向后移动

这样利用双指针法有两个好处

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。