在 javascript 中使用嵌套的 for 循环返回单词字符串中重复最多的字母

Return most repeated letter in a string of words using nested for loops in javascript

本文关键字:字符串 单词 循环 javascript 嵌套 for 返回      更新时间:2023-09-26
有几个

类似的问题,但是,我不想搜索特定的字符或字母,也不是要找到带有重复字母的第一个单词。另外,我想在直接的javascript中做到这一点。

我正在尝试构建一个函数,该函数将字符串作为输入,循环访问字符串中的每个单词并返回具有最多重复字母的单词。如果有多个单词具有相同数量的重复字母(无论是 1 个还是更多(,我想返回多个单词。

这是我到目前为止所拥有的,但它返回字符串中的所有单词,而不仅仅是重复字母最多的单词。我无法弄清楚如何仅返回重复次数最高的单词:

function repeatedLetterCounter(str) {
  str = str.toLowerCase();
  var wordArray = str.split(" ");
  var results = [];
  for (var i = 0; i < wordArray.length; i++) {
    var countNew = 0;
    var count = 0;
    var word = wordArray[i];
    for (var a = 0; a < word.length; a++) {
      var letter = word[a];
      for (var b = a + 1; b < word.length; b++) {
        var nextLetter = word[b];
        if (letter === nextLetter) {
          countNew += 1; 
        }
      }
    }
        if (countNew > count) {
          count = countNew;
          results.push(wordArray[i]);
        } else if (countNew === count) {
          results.push(wordArray[i]);
        }
  }
  return results;
}
console.log(repeatedLetterCounter("No, Bob ran across the Mississippi."));

这是我的小提琴。

我不会从头开始生成新代码,而是采用您的代码并显示问题所在:

1. 为什么你的代码返回所有单词

看看这段代码,我隐藏了一些部分:

  for (var i = 0; i < wordArray.length; i++) {
    var count = 0;
    // two nested loops open and close here //
    // ...
    if (countNew > count) {
      count = countNew;
      results.push(wordArray[i]);
      // ...
    }
  }

此代码显示,在每次迭代中,您将计数重置为零,因此末尾的if将始终为 true。因此,您会得到结果中的所有单词。

2. 计数器太高

当您增加 countNew 时,即使您已经在检查下一个字符,您也会继续增加它,因此最终它将不加区分地汇总您正在查看的单词中所有字母重复的数量。

3. 计数水平

您目前使用 2 个计数变量,但实际上需要 3 个:

  • 计数:表示在任何单词中找到的最大重复次数
  • countThisWordsBestLetter:当前单词中发现的最高重复次数
  • countLetter:当前单词中当前字母的重复计数

4. 更正代码

function repeatedLetterCounter(str) {
    str = str.toLowerCase();
    var wordArray = str.split(" ");
    var results = [];
    var count = 0;
    for (var i = 0; i < wordArray.length; i++) {
        var word = wordArray[i];
        var countThisWordsBestLetter = 0;
        for (var a = 0; a < word.length; a++) {
            var countLetter = 0;
            var letter = word[a];
            for (var b = a + 1; b < word.length; b++) {
                var nextLetter = word[b];
                if (letter === nextLetter) {
                    countLetter += 1; 
                }
            }
            if (countLetter > countThisWordsBestLetter) {
                countThisWordsBestLetter = countLetter;
            }
        }
        if (countThisWordsBestLetter > count) {
            // forget any words we gathered before:
            results = [];
        }
        if (countThisWordsBestLetter >= count) {
            count = countThisWordsBestLetter;
            results.push(wordArray[i]);
        }
    }
    return results;
}
console.log(repeatedLetterCounter("No, Bob ran across the Mississippi."));
// for this snippet only:
document.write( JSON.stringify(repeatedLetterCounter("No, Bob ran across the Mississippi.")));

首先,我们可以将此代码分解为一组小而有用的函数。此外,对于此任务,您不需要嵌套循环,请参阅下面的代码:

function getCountedLetters (letters) {
    var h = {};
    for (var i = 0, len = letters.length; i < len; ++i) {
        var letter = letters[i];
        h[letter] = h[letter] || 0;
        ++h[letter];
    }
    return h;
}
function getMaxCount (h) {
    var count = 0;
    for (var i in h) {
        if (h[i] > count) {
            count = h[i];
        }
    }
    return count;
}
function getMaxLetterCount (letters) {
    var h = getCountedLetters(letters);
    return getMaxCount(h); 
}
function repeatedLetterCounter (str) {
    var words = str.split(' ');
    var maxCount = 0;
    var result = [];
    var len = words.length;
    for (var i = 0; i < len; ++i) {
        var word = words[i];
        var currentCount = getMaxLetterCount(word);
        if (currentCount > maxCount) {
            maxCount = currentCount;
        }
    }
    for (var i = 0; i < len; ++i) {
        var word = words[i];
        var currentCount = getMaxLetterCount(word);
        if (currentCount >= maxCount) {
            result.push(word);
        }
    }
    if (result.length == 1) {
        return result[0];
    }
    return result;
}
我知道

这个问题已经有一个公认的答案,但我发现这是一个有趣的挑战。下面是我根据要求工作制作的脚本。

function repeatedLetterCounter(str) {
  var wrd = str.split(' ');
  var ltr = 'abcdefghijklmnopqrstuvwxyz'.split('');
  var words = [], holder = [], actual = [];
  var highest = 0;
  for (var i = 0; i < wrd.length; i++) {
    holder[i] = 0;
    words[i] = wrd[i];
    for (var c = 0; c < ltr.length; c++) {
      var count = (wrd[i].match(new RegExp(ltr[c],'ig')) || []).length;
      if (count > 1) {holder[i] += count;}
    }
    if (holder[i] > highest) {highest = holder[i];}  
  }
  for (var i = 0; i < holder.length; i++) {
    if (holder[i] >= highest) {actual.push(words[i]);}
  }
  return actual;
}
var str = 'No, Bob ran across the Mississippi.';
var words = repeatedLetterCounter(str);
console.log(words);

它在这里工作:https://jsfiddle.net/xsd3q6aa/

检查这个小提琴,我已经模块化了代码:)

function getMaxFrequency(string) 
{
    var freq = {};
    var maxFrequency = 0;
    for (var i=0; i<string.length;i++) 
    {
        var character = string.charAt(i);
        if (freq[character]) 
        {
           freq[character]++;
        }
        else 
        {
           freq[character] = 1;
        }
        if ( freq[character] > maxFrequency )
        {
          maxFrequency = freq[character];
        }
    }
    return maxFrequency;
};
function repeatedLetterCounter(str)
{
  var output = [];
  var arr = str.split( " " );
  var freq = [];
  var maxFrequency = 0;
  console.log(arr);
  arr.forEach( function(value, index){
     var frequency = getMaxFrequency(value);
     freq.push([index, getMaxFrequency(value)] );
     if ( frequency > maxFrequency  )
     {
       maxFrequency = frequency;
     }
  } );
  console.log(freq);
  console.log(maxFrequency);
  freq.forEach( function(value){
     console.log( value );
     if ( value[1] == maxFrequency )
     {
        output.push( arr[value[0]] )
     }
  } );
  console.log(output);
  return output;
}

console.log(repeatedLetterCounter("No, Bob ran across the Mississippi."));
使用

一些高阶方法:

function repeatedLetterCounter(str) {
  str = str.toLowerCase();
  var wordArray = str.split(" ");
  var mapped = wordArray.reduce(function(ac, x) {
    var res = x.split('').reduce(function(acc, a) {
      if (!acc[a])
        acc[a] = 0;
      
      acc[a] ++;
      return acc;
    }, {})
    ac.push(res);
    return ac;
  }, [])
  //mapped will map each word as an object with the char as the key and count as value
  wordChar = mapped.map(function(x, index) {
      var letter = [];
      var count = 0;
      for (var i in x) {
        if (count > x[i])
          continue;
        if (count === x[i])
          letter.push(i);
        if (count < x[i]) {
          letter = [];
          letter.push(i);
          count = x[i];
        }
      }
      return {
        letter: letter,
        count: count,
        word: wordArray[index]
      }
    })
    //now you can sort by the count property
  var result = wordChar.sort((a, b) => {
    return b.count - a.count
  });
  return result[0];
//this returns an object with all the info you should need
}
console.log(repeatedLetterCounter("No, Bob ran across the Mississippppi."));