2

This is a question from coderbyte’s easy set. Many people asked about it already, but I’m really curious about what’s wrong with my particular solution (I know it’s a pretty dumb and inefficient one..)

Original question:

Have the function LetterCountI(str) take the str parameter being passed and return the first word with the greatest number of repeated letters. For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces.

My solution works most of the time. But if it seems the last word of the input isn’t valued by my code. For example, for “a bb ccc”, “bb” will be returned instead of “ccc”. But the funny thing here is if the string only contains one word, the result is correct. For example, “ccc” returns “ccc”.

Please tell me where I was wrong. Thank you in advance!

function LetterCountI(str) { 

  str.toLowerCase();

  var arr = str.split(" ");

  var count = 0;
  var word = "-1";

  for (var i = 0; i < arr.length; i++) {
   for (var a = 0; a < arr[i].length; a++) {
     var countNew = 0;
     for (var b = a + 1; b < arr[i].length; b++) {
       if(arr[i][a] === arr[i][b])
          countNew += 1;
     }
     if (countNew > count) {
       count = countNew;
       word = arr[i];
     }
   }
   return word;
  }


}       
  • You've got your `return word;` line in the wrong place. It's currently inside your **outer** loop, when it needs to be outside – jasonscript Jul 20 '15 at 05:26
  • 3
    Have you tried using your browser's debugger to step through the code and see where it's going wrong? Or even as a learning exercise "run" your code manually using pencil and paper and see what it does. – nnnnnn Jul 20 '15 at 05:29
  • Here is the regex solution: http://stackoverflow.com/questions/29524330/letter-count-return-the-first-word-with-the-greatest-number-of-repeated-letters/29525795#29525795 – WhatisSober Jul 20 '15 at 05:40
  • @WhatisSober Here is a golfed solution I just made: http://jsfiddle.net/DerekL/d1v5tzze/ – Derek 朕會功夫 Jul 20 '15 at 05:56

6 Answers6

2

Please find below the workable version of your code:

function LetterCountI(str) {
    str = str.toLowerCase();
    var arr = str.split(" ");
    var count = 0;
    var word = "-1";
    for (var i = 0; i < arr.length; i++) {
        for (var a = 0; a < arr[i].length; a++) {
            var countNew = 0;
            for (var b = a + 1; b < arr[i].length; b++) {
                if (arr[i][a] === arr[i][b])
                    countNew += 1;
            }
            if (countNew > count) {
                count = countNew;
                word = arr[i];
            }
        }
    }
    return word;
}
marianc
  • 439
  • 1
  • 4
  • 13
1

You need to move the return word; statement outside of the loop to fix your version.

I also put together another take on the algorithm that relies on a few built in javascript methods like Array.map and Math.max, just for reference. I ran a few tests and it seems to be a few milliseconds faster, but not by much.

function LetterCountI(str) {
    var maxCount = 0;
    var word = '-1';

    //split string into words based on spaces and count repeated characters
    str.toLowerCase().split(" ").forEach(function(currentWord){
        var hash = {};

        //split word into characters and increment a hash map for repeated values
        currentWord.split('').forEach(function(letter){
            if (hash.hasOwnProperty(letter)) {
                hash[letter]++;
            } else {
                hash[letter] = 1;
            }           
        });

        //covert the hash map to an array of character counts
        var characterCounts = Object.keys(hash).map(function(key){ return hash[key]; });

        //find the maximum value in the squashed array
        var currentMaxRepeatedCount = Math.max.apply(null, characterCounts);

        //if the current word has a higher repeat count than previous max, replace it
        if (currentMaxRepeatedCount > maxCount) {
            maxCount = currentMaxRepeatedCount;
            word = currentWord;
        }
    });

    return word;
}
Travis
  • 5,021
  • 2
  • 28
  • 37
  • Hello [Travis](http://stackoverflow.com/users/55954/travis) I have a quick question for you, your example is more or less what I am looking for, but I wanted to return all instances of a word with repeated characters, so if I have "aaaa" and "bbbb" in a sentence, they will both return. I tried to do some changes to the example, but couldn't hack it.... How can I return more than one instance of a repeated character word, if that word has the same amount of repeated characters? – Lucky500 Feb 11 '16 at 15:33
  • Does something like this work for you? https://gist.github.com/tjboudreaux/8f64a743778f60266a03 – Travis Feb 16 '16 at 18:09
1

Here is the Java code soln for your problem.

You have returned your answer incorrectly. You should have returned word/Answer/res out of "for loops". Check my chode here.

public static String StringChallenge( String str) { 

  String[] arr = str.split(" ");
  int count = 0; String res = "-1";

  for (int i = 0; i < arr.length ; i++) {
   for (int j = 0; j < arr[i].length() ; j++) {
     int counter = 0;
     for (int k = j + 1; k < arr[i].length() ; k++) {
       if(arr[i].charAt(j) === arr[i].charAt(k) )
          counter ++;
     }
     if (counter > count) {
       count = counter;   res = arr[i];
     }
   }
   return res;
  }
} 
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 14 '22 at 08:05
0

I think the problem is that you're placing the return statement inside your outermost loop. It should be inside your inner loop.

So you have to place the return statement within the inner loop.

Correct use of return

     if (countNew > count) {
       count = countNew; 
       word = arr[i];
     }
     return word;
    }
  }
} 
Abraar Arique Diganto
  • 1,215
  • 16
  • 24
0

Yet another solution in a more functional programming style:

JavaScript

function LetterCountI(str) {
  return ((str = str.split(' ').map(function(word) {
    var letters = word.split('').reduce(function(map, letter) {
          map[letter] = map.hasOwnProperty(letter) ? map[letter] + 1 : 1;
          return map;
        }, {}); // map of letters to number of occurrences in the word

    return {
      word: word,
      count: Object.keys(letters).filter(function(letter) {
        return letters[letter] > 1;
      }).length // number of repeated letters
    };
  }).sort(function(a, b) { // Sort words by number of repeated letters
    return b.count - a.count;
  }).shift()) && str.count && str.word) || -1; // return first word with maximum repeated letters or -1
}

console.log(LetterCountI('Today, is the greatest day ever!')); // => greatest

Plunker

http://plnkr.co/edit/BRywasUkQ3KYdhRpBfU2?p=preview

Vadim
  • 8,701
  • 4
  • 43
  • 50
0

I recommend use regular expression: /a+/g to find a list of letter with a key word a.

My example :

var str = aa yyyyy bb cccc cc dd bbb;

Fist, find a list of different word :

>>> ["a", "y", "b", "c", "d"]

Use regular expression for each word in list of different word :

var word = lstDiffWord[1];
             var
wordcount = str.match(new RegExp(word+'+','g')); 
console.log(wordcount);

>>>>["yyyyy"]

Here is full example: http://jsfiddle.net/sxro0sLq/4/

Giau Huynh
  • 300
  • 3
  • 15