# Find the word in a string that has the most repeated characters

The problem: I want to find the word in a string that has the most repeats of a single letter, each letter is independent. Does not need to be consecutive.

Currently I am jumping each character and checking, which doesn't seem very efficient. Do you have any ideas that might improve the number of processes that are required to find which word has the most repeats?

function LetterCountI(str) {

var repeatCountList = [];
var wordList = str.split(/\W/); //regular expression \W for non word characters split at.
var wordCount = wordList.length; // count the number of words
for (var i=0; i< wordCount ; i++)
{ var mostRepeat = 1;                 // set the default number of repeats to 1
var curWord = wordList[i];             // set the current word to the ith word from the list

for(var ii=0; ii<curWord.length ; ii++)
{ var repeatCount = 1;                   // set default repeat count to 1
var curChar = curWord[ii];               //set the current character to the iith
for (var iii=0; iii<curWord.length; iii++)  //judge if it is the same as the iiith
{var against = curWord[iii];
if (iii!=ii)                               // if it is Not the same referenced postion
{if(curChar==against)                      // see if the string values match
{repeatCount=repeatCount+1}}}               // increase counter if match against
if (repeatCount>=mostRepeat)              // record repeat for the highest only
{mostRepeat=repeatCount}

}
repeatCountList = repeatCountList.concat(mostRepeat)    // take the highest from each word
}

mostRepeat = 0;                     // set the repeats value to -
for (j=0;j<wordCount; j++)            // go through the repeats count list
{ if(repeatCountList[j]>mostRepeat)       // if it has more repeats than the highest So FAR
{ mostRepeat = repeatCountList[j];        // record if higher than last
var x = j;}}                      // record the index of the most repeat that is the new high
var ans = [];
if (mostRepeat == 1)              // check if there are no repeats at all.
{ans=-1}                // question want to return -1 if there are no repeats
else
{ans=wordList[x]}          // display the word from the list with the most repeat characters

// code goes here
return ans;

}


Any help is appreciated.

• I posted and answer but then I tested your code and didn't get the same output so I deleted it. What word should win between "helllo" and "aabbcc"? The first one has 2 repeated characters but the second one has 3. What's the rule? Most repeated in a row? – elclanrs Jan 25 '14 at 8:52
• the letters only need to be repeated in the word, not consecutive. – Reverend_Dude Jan 26 '14 at 0:57
• So aabbcc wins over helllo? – elclanrs Jan 26 '14 at 0:59
• no "helllo" wins with "l" repeated three (3) times. "aabbcc" has three letters that are repeated but only twice (2) each. Sorry I will calirfy – Reverend_Dude Jan 26 '14 at 1:38
• @Buddha The formatting of the code is an aspect that is subject to review in an answer, not to be silently fixed by editing the question. (Fixing the indentation when someone botched a copy-and-paste job into the website would be OK, but that's not the case here.) I've rolled back Rev 5 → 4. – 200_success Jan 26 '14 at 7:46

I liked that you split the string into words using a regular expression. That helps a lot.

Your code formatting (indentation and braces) is haphazard. It shouldn't be that hard to follow the standard conventions for code formatting, and it will make things easier for yourself if you do.

I think your function tries to do too much. It would help to break down the problem. I've extracted part of the problem into a self-contained task:

Given a word, how many times does the most frequent character appear?

For that, you can write a function, and test it (e.g. mostFrequentCount('hello') should return 2).

/**
* Given an array (or a string), returns the number of times the most frequent
* element (or character) appears.
*/
function mostFrequentCount(elements) {
var bins = {};
for (var i = 0; i < elements.length; i++) {
bins[elements[i]] = (bins[elements[i]] || 0) + 1;
}
var max = 0;
for (var c in bins) {
max = Math.max(max, bins[c]);
}
return max;
}


That should simplify the main code. Rather than commenting each line (in effect writing everything once for the computer and once for other programmers), I've tried to make the code read like English by using very human-friendly variable names.

function wordsWithMaxRepeatedCharacters(string) {
var maxRepeatedCharacters = 0, wordsWithMaxRepeatedCharacters = [];

var words = string.split(/\W/);
for (var w = 0; w < words.length; w++) {
var word = words[w];
var numRepeatedCharacters = mostFrequentCount(word);

if (maxRepeatedCharacters < numRepeatedCharacters) {
maxRepeatedCharacters = numRepeatedCharacters;
wordsWithMaxRepeatedCharacters = [word];
} else if (maxRepeatedCharacters == numRepeatedCharacters) {
wordsWithMaxRepeatedCharacters.push(word);
}
}
return wordsWithMaxRepeatedCharacters;
}

• Thank you a lot for your help! Sorry about the format. still learning. is there an MLA style guide equivalent for code? – Reverend_Dude Jan 26 '14 at 1:00
• @Reverend_Dude I liked the famous book titled Code Complete – ChrisW Jan 26 '14 at 1:43
• @Reverend_Dude And, here is a guide to indentation (whitespace) in JavaScript: google-styleguide.googlecode.com/svn/trunk/… – ChrisW Jan 26 '14 at 2:16

Shorter versions of the same functions using a regular expression instead of an object for the first function and array methods for the second

var mostFrequentCount = function(s) {
var max = 0;
s = s.split('').sort().join('');
s.replace(/(.)\1+/g,function(a){
if (max < a.length) {max = a.length;}});
return max;
};
var wordsWithMaxRepeatedCharacters = function(s) {
var n,v;
s = s.split(/\W/);
n = s.map(function(n) {return mostFrequentCount(n);});
v = Math.max.apply(null,n);
return s.filter(function(a,b) {return (n[b]===v);});
};