You need to enable JavaScript to run this app. JavaScript实现限制字符串字符重复次数的函数及代码修复
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现限制字符串字符重复次数的函数及代码修复

现有代码的核心问题
  • 逻辑设计完全偏离需求:当前实现会把字符串中所有同字符的位置无差别聚合成独立数组,先将原字符串打乱为无重复的字符顺序,再把裁剪后的同字符片段整体拼接到结果末尾。既没有保留原字符串的连续分段顺序,还会把跨分段的同字符合并统计总长度再裁剪,直接丢失本该保留的后置同字符——比如处理"aadaa"时,所有4个a被合并统计,按r=1只留1个a,加上原去重串裁剪后剩下的字符,最终才会得到错误的"ad",而非预期的"ada",更无法匹配"aassaa"输入r=1时输出"asa"的要求。
  • 性能效率极低:每遍历一个字符就对全字符串执行一次filter匹配同字符,整体时间复杂度为O(n²),字符串长度稍大就会出现明显卡顿。
  • 实现存在隐患:el.splice(0, true)这种依赖隐式类型转换传删除参数的写法可读性极差,后续维护成本很高。
正确实现方案

你要的效果本质是顺着原字符串顺序,对每一段连续重复的同字符,最多保留r个字符,不需要做跨分段的字符聚合统计:

  • 先做入参兼容:数组类型入参直接拼接为字符串,非字符串类型直接返回
  • 流式遍历字符串每一个字符,不需要提前把所有同字符聚组
  • 遍历过程中只需记录两个值:当前连续重复段的字符、该段已经保留的字符数量
  • 遇到新的连续字符就重置段记录和保留计数;当前段的保留数量没达到r上限时,就把字符加入最终结果

参考代码

function unique(s, r) {
  // 入参兼容处理
  if (Array.isArray(s)) s = s.join("");
  if (typeof s !== "string") return;

  const result = [];
  let currentSegmentChar = ""; // 记录当前连续段的字符
  let keptCount = 0; // 当前连续段已保留的字符数

  for (const char of s) {
    // 遇到新字符,重置连续段状态
    if (char !== currentSegmentChar) {
      currentSegmentChar = char;
      keptCount = 0;
    }
    // 当前段未达保留上限,就将字符加入结果
    if (keptCount < r) {
      result.push(char);
      keptCount++;
    }
  }

  return result.join("");
}

用例验证

// 匹配核心需求
console.log(unique("aassaa", 1)); // 输出 "asa",符合预期
console.log(unique("aadaa", 1)); // 输出 "ada",解决原有bug
// 其余测试场景
console.log(unique("aaa", 1)); // 输出 "a"
console.log(unique("aaa", 2)); // 输出 "aa"
console.log(unique(["a","a","b","a","a","a"], 2)); // 输出 "aabaa"
console.log(unique(["a","a","b","a","a","a"], 1)); // 输出 "aba"

说明:你之前写的测试用例注释里的输出结果,是原有bug代码的实际运行结果,不是功能预期。参考代码严格按照"aassaa输入r=1输出asa"的规则实现,全程保留原字符串的连续分段顺序,跨分段的同字符不会被合并统计。


内容的提问来源于stack exchange,提问作者Lehmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 07:15:04