【问题标题】:JavaScript - Dynamic RegExp for Duplicate CharactersJavaScript - 重复字符的动态正则表达式
【发布时间】:2021-01-04 22:06:29
【问题描述】:

我对编程非常陌生,我正在尝试解决一个练习,您可以根据组成字符是否​​出现两次或更多次来对字符串(在本例中为单个单词)进行编码。只出现一次的字符编码为“■”,编码两次或更多的字符编码为“X”。

示例:输入 = “竞技场” :: output = “■■XXX■■X■■”

我设法使用嵌套循环和存储character:occurrenceskey:value 对象以非常复杂的方式解决它,但我正在尝试使用动态创建的正则表达式重构解决方案以提高效率,但我认为我' m 不懂正则表达式。

function encodeDupes(word) {
  let encoded = "";
  for (let char of word) {
    let regex = new RegExp(char + "{2,}","ig"); // create a regex to see if "char" occurs 2 or more times
    regex.test(word) ? encoded += "X" : encoded += "■"; // check this char against rest of word, push appropriately
  }
  return encoded;
}

它适用于像char < "m" ? do X : do Y 这样更简单的门,我想我理解这个答案here{n,} = 至少出现n),但我还不够新,所以我还没有确定是我的正则表达式还是我的逻辑。

谢谢!

【问题讨论】:

  • 空格、数字和符号呢?
  • @Cuong Le Ngoc 我相信这个练习只涉及单个单词,因为所有其他测试示例(此处未给出)都是无空格的,但我认为它应该适用于 any 输入字符串中的字符。
  • 更新:@CuongLeNgoc 你的问题其实很有先见之明 =)

标签: javascript regex


【解决方案1】:

我对编程很陌生,...,我正在尝试使用动态创建的 RegExp 重构解决方案以提高效率...

这有点像第 22 条问题,因为正则表达式为了方便而牺牲效率。为了使正则表达式“引擎”运行,必须建立语法,并且词法分析器、解析器和求值器将基于字符串的输入表达式转换为程序输出。使用正则表达式实现特定程序(有时)很方便,但几乎不可能击败没有被正则表达式引擎拖慢的基本算法。

我设法以一种非常复杂的方式使用嵌套循环和一个存储character:occurrenceskey:value 对象来解决它...

确实令人费解,但遗憾的是,即使是“专家”程序员也会做这样的事情。当我们意识到不需要计算每个字母时,就会出现一种有效的算法。相反,我们只需要知道一个字母是否出现不止一次。使用两个Set 对象oncemore,我们可以确定答案,而无需每个字母分配计数器内存!由于 O(1) 恒定时间查找,集合速度快如闪电 -

function encodeDupes(word)
{ const once = new Set
  const more = new Set
  
  for (const c of word)
    if (more.has(c))
      continue
    else if (once.has(c))
      (once.delete(c), more.add(c))
    else
      once.add(c)
      
  return Array
    .from(word, c => more.has(c) ? "X" : "■")
    .join("")
}

console.log(encodeDupes("hippodrome"))

输出

■■XXX■■X■■

【讨论】:

  • 虽然给出的示例只是/\w/的输入字符串,但针对我的原始函数的实际测试电池也生成了包含/\W/的随机输入字符串,包括$^!(等正则表达式控制字符。这使得调整我的正则表达式变得越来越站不住脚。这个解决方案除了更有效地回避控制字符问题之外,还帮助我几乎立即解决了两个额外的问题,基于 Sets 的操作方式。所以谢谢你,谢谢你^.^
  • 您现在看到了正则表达式这把双刃剑。我喜欢事情如你所描述的那样顺利。很高兴为您提供帮助。顺便说一句,有趣的问题^_^
【解决方案2】:

RegExp 通常用于比较整个单词或短语。

每当使用{n,} 时,它都会连续搜索两个或多个字符。这是一个例子:

n{2,}
nn     # match
anna   # match
nan    # does not match

以下正则表达式并不完美,但应该足够了,将 n 替换为您选择的字符

(.*n{2,}.*)|(.*n.*n.*)+

(.*n{2,}.*) —— for consecutive ‘n’s 
|  —— or
(.*n.*n.*)+ —— ‘n’s with anything in between

告诉我进展如何。

【讨论】:

  • 从技术上讲,这回答了我最初的问题,特别是关于正则表达式的使用,我没有意识到 n{2,} 指的是 only 连续出现。它与我认为基于给出的示例的测试参数完美配合(输入字符串仅为/\w/)。后来我发现这些参数是……不正确的假设和/或不完整的例子。无论如何,您的回答非常有帮助,即使问题最终被重新定义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-13
  • 2017-01-12
  • 1970-01-01
  • 2020-08-23
  • 2018-01-15
  • 1970-01-01
相关资源
最近更新 更多