在字符串中计算重复字母的数量

6
我遇到了以下问题:我需要找到字符串中的重复字符。基本上,我想要一个正则表达式,可以实现这样的匹配。
hello - ["ll"];
here  - ["ee"];
happiness   -  ["pp","ss"];
pupil  -  ["pp"];

我有一个匹配连续重复字符的代码。
  /([a-z])\1+/g

还有一个可以匹配重复字符以及它们之间所有内容的正则表达式,就像这个例子。

   /([a-z])(?:.*)\1+/g

但是无法确定正确的一个。

1
所以从这些例子中,您想要计算字符并返回出现超过一次的任何字符?只需简单迭代和一个对象即可完成。 - adeneo
1
hellloo 的输出应该是什么? - karthik manchala
2
不是正则表达式,但这是我会做的 -> http://jsfiddle.net/adeneo/8czwdq5j/ - adeneo
1
是否可以有超过2次重复,例如“assassin”?如果是,那么应该输出什么? - anubhava
1
一个好的测试(类似于“刺客”)可以是“香蕉”,它应该返回“aaa”和“nn”。到目前为止,大多数解决方案都返回“anana”或只返回“aa”。 - SpenserJ
显示剩余4条评论
8个回答

7

您可以使用

([a-zA-Z]).*(\1)

演示正则表达式


既然您已经明确表示要处理字符串中除双字母外的其他内容,那么您应该使用非正则表达式方法,例如:

构建一个关联数组,其中包含字符串中每个字符的计数:

var obj={}
var repeats=[];
str='banana'

for(x = 0, length = str.length; x < length; x++) {
    var l = str.charAt(x)
    obj[l] = (isNaN(obj[l]) ? 1 : obj[l] + 1);
}

console.log(obj)

打印

{ b: 1, a: 3, n: 2 }

接下来按照您的规格构建一个数组:

for (var key in obj) {
    if (obj.hasOwnProperty(key) && obj[key]>1) {
        repeats.push(new Array( obj[key]+ 1 ).join( key ));
    }
}
console.log(repeats)

输出:

[ 'aaa', 'nn' ]

它对于“assassin”返回["assa", "ss"],对于“banana”返回["anana"]。但我期望分别返回["aa","ssss"]和["aaa","nn"]。 - Olena Horal
我假设仅使用正则表达式无法解决这个问题,对吗? - Olena Horal
对于你的例子单词,你可以使用正则表达式。对于像“banana”和“assassin”这样有多个字母重复的单词,必须将正则表达式与代码结合使用。如果你要使用代码,最好使用字符串关联数组,这也是你在正则表达式中使用的内容。 - dawg
这是一份面试答案。 - ArifMustafa

4
这种方法也很有效!
let myString = 'abababc';
let result = {};
for (let str of myString) {
  result[str] = result.hasOwnProperty(str) ? result[str] + 1 : 1;
}
console.log(result);

结果将会是这样的{a: 3, b: 3, c: 1}

2

对于您的情况,第二个解决方案似乎更好。您可以通过其他捕获组获取第二个字母。

正则表达式应该是(这是带有另一个捕获组的第二个正则表达式):

/([a-z])(?:.*)(\1)+/g

var re = /([a-z])(?:.*)(\1)+/g; 
var str = ['hello', 'here', 'happiness', 'pupil'];
var m;
var result = new Array();

for(var i = 0; i < str.length; i++) {
  result[i] = str[i] + "->";
  while ((m = re.exec(str[i])) !== null) {
      if (m.index === re.lastIndex) {
          re.lastIndex++;
      }
      // View your result using the m-variable.
      // eg m[0] etc.
    result[i] += m[1];
    result[i] += m[2] + ",";
  }
}

document.getElementById("results").innerHTML = result.join("</br>");
<div id="results"></div>


1
比正则表达式解决方案更加复杂,但可以正确处理bananaassassin,其中存在两个重叠的字符组。
这确实使用了array.maparray.filterarray.reduce,这意味着这个精确的解决方案不支持<=IE8,但可以很容易地进行填充。

function findDuplicateCharacters(input) {
  // Split the string and count the occurrences of each character
  var count = input.split('').reduce(function(countMap, word) {
    countMap[word] = ++countMap[word] || 1;
    return countMap;
  }, {});

  // Get the letters that were found, and filter out any that only appear once.
  var matches = Object.keys(count)
    .filter(function (key) { return (count[key] > 1); })
    // Then map it and create a string with the correct length, filled with that letter.
    .map(function (key) {
      return new Array(count[key] + 1).join(key);
    });

  return matches;
}

var results = ['hello', 'here', 'happiness', 'pupil', 'banana'].map(findDuplicateCharacters);

document.getElementById("results").innerHTML = results.join('<br />');
<div id="results"></div>


1

var re = /([a-z])(?:.*)(\1)+/g; 
var str = ['aaaccbcdd'];
var m;
var result = new Array();

for(var i = 0; i < str.length; i++) {
  result[i] = str[i] + "->";
  while ((m = re.exec(str[i])) !== null) {
      if (m.index === re.lastIndex) {
          re.lastIndex++;
      }
      // View your result using the m-variable.
      // eg m[0] etc.
    result[i] += m[1];
    result[i] += m[2] + ",";
  }
}

document.getElementById("results").innerHTML = result.join("</br>");
<div id="results"></div>


1
var obj = {};
var str = "this is my string";
for (var i = 97; i < 97 + 26; i++) 
  obj[String.fromCharCode(i)] = 0;
for (var i = 0; i < str.length; i++) {
  obj[str.charAt(i).toLowerCase()]++;
}

从这里,您可以使用obj["a"]来获取任何特定字母出现的次数。


0
//Try this method

const countRepeatChar = (str) => {
  let obj = {};

  if (str) {
    for (let i = 0; i < str.length; i++) {
      if (obj[str[i]]) {
        obj[str[i]] += obj[str[i]];
      } else {
        obj[str[i]] = 1;
      }
    }
    console.log(obj);
  }
};
countRepeatChar("aabcddeee");

0
function charCount(str){
    let arr = str.split('');
    return arr.reduce((a,p)=>{
        a[p] = a[p] ? (a[p]+1) : 1;
        return a;
    },{});
};

2
你应该在代码中描述并解释一些内容。 - Aliqua

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接