【问题标题】:Letter Count I JavaScript Challenge on CoderbyteCoderbyte 上的字母计数 I JavaScript 挑战
【发布时间】:2016-03-11 20:44:56
【问题描述】:

我已经解决这个问题几个小时了,我已经尽我所能,尽我所能来解决这个挑战,但我就是不知道到底出了什么问题。我不断收到“意外令牌非法”:http://jsfiddle.net/6n8apjze/14/

和“TypeError:无法读取 null 的属性 'length'”:http://goo.gl/LIz89F

我认为问题在于 howManyRepeat 变量。我不明白为什么当很明显 word 是 str 中的一个词时,我无法读取 null 的长度...

我想到了:

word.toLowerCase().split("").sort().join("").match(/([.])\1+/g).length

...这里:Get duplicate characters count in a string

挑战:
使用 JavaScript 语言,让函数 LetterCountI(str) 获取 str 参数被传递并返回第一个字数最多 重复的字母。例如:“今天,是有史以来最伟大的一天!”应该返回 最好的,因为它有 2 个 e(和 2 个 t),而且它比以往任何时候都更早 有2个e。如果没有重复字母的单词返回-1。话会 用空格隔开。

function LetterCountI(str){
  var wordsAndAmount={};
  var mostRepeatLetters="-1";
  var words=str.split(" ");

     words.forEach(function(word){
       // returns value of how many repeated letters in word.
       var howManyRepeat=word.toLowerCase().split("").sort().join("").match(/([.])\1+/g).length;       
        // if there are repeats(at least one value).
        if(howManyRepeat !== null || howManyRepeat !== 0){ 
          wordsAndAmount[word] = howManyRepeat;
        }else{
         // if no words have repeats will return -1 after for in loop.
         wordsAndAmount[word] = -1; 
         }
     });

     // word is the key, wordsAndAmount[word] is the value of word.
     for(var word in wordsAndAmount){ 
        // if two words have same # of repeats pick the one before it.
        if(wordsAndAmount[word]===mostRepeatLetters){ 
          mostRepeatLetters=mostRepeatLetters;
        }else if(wordsAndAmount[word]<mostRepeatLetters){ 
          mostRepeatLetters=mostRepeatLetters;
        }else if(wordsAndAmount[word]>mostRepeatLetters){
          mostRepeatLetters=word;
        }
      } 

  return mostRepeatLetters;
}

// TESTS
console.log("-----");   
console.log(LetterCountI("Today, is the greatest day ever!"));   
console.log(LetterCountI("Hello apple pie"));    
console.log(LetterCountI("No words"));    

非常感谢任何指导。谢谢!! ^____^

【问题讨论】:

  • [.] 匹配文字点符号,不是任何字母而是换行符。
  • 哦,关于正则表达式。是的,我还在学习这些。因此,如果我想匹配单词是否有任何重复的字母,我可以做 /([a-z])\1+/g 吗?我想我试过了,大约一个小时前出现了错误。
  • this code 是否按预期工作? jsfiddle.net/v3czs6zm。它输出-----, greatest, apple, -1
  • 哦,你是对的,它现在几乎可以工作了!我没有得到你得到的。我得到了----最好的苹果-1。我看到你改变了(。)它和我的真的不同。我应该得到 --- 最棒的 Hello 和 -1...我想我需要在我的 for in 循环中改变一些东西。不...不是这样...
  • (.) 与 [.] 有何不同?

标签: javascript regex function loops object


【解决方案1】:

这里是工作代码sn-p:

/*
Using the JavaScript language, 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. 

console.log(LetterCountI("Today, is the greatest day ever!") === "greatest");
console.log(LetterCountI("Hello apple pie") === "Hello");
console.log(LetterCountI("No words") === -1);

Tips: 
This is an interesting problem. What we can do is turn the string to lower case using String.toLowerCase, and then split on "", so we get an array of characters.

We will then sort it with Array.sort. After it has been sorted, we will join it using Array.join. We can then make use of the regex /(.)\1+/g which essentially means match a letter and subsequent letters if it's the same.

When we use String.match with the stated regex, we will get an Array, whose length is the answer. Also used some try...catch to return 0 in case match returns null and results in TypeError.

/(.)\1+/g with the match method will return a value of letters that appear one after the other. Without sort(), this wouldn't work.
*/

function LetterCountI(str){
  var wordsAndAmount={};
	var mostRepeatLetters="";
  var words=str.split(" ");
  
  words.forEach(function(word){
    
      var howManyRepeat=word.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
      
			if(howManyRepeat !== null && howManyRepeat !== 0){ // if there are repeats(at least one value)..
    	 	 	 wordsAndAmount[word] = howManyRepeat;
			  } else{
           wordsAndAmount[word] = -1; // if no words have repeats will return -1 after for in loop.
        }
  });
  
//  console.log(wordsAndAmount);
	for(var word in wordsAndAmount){ // word is the key, wordsAndAmount[word] is the value of word.
   // console.log("Key = " + word);
   // console.log("val = " + wordsAndAmount[word]);
    	if(wordsAndAmount[word].length>mostRepeatLetters.length){ //if two words have same # of repeats pick the one before it.
        mostRepeatLetters=word; 
  		}
  }	
  return mostRepeatLetters ? mostRepeatLetters :  -1;
}

// TESTS
console.log("-----");
console.log(LetterCountI("Today, is the greatest day ever!"));
console.log(LetterCountI("Hello apple pie"));
console.log(LetterCountI("No words"));

/*
split into words

var wordsAndAmount={};
var mostRepeatLetters=0;
  
  
loop through words
	Check if words has repeated letters, if so
  	Push amount into object
    Like wordsAndAmount[word[i]]= a number
  If no repeated letters...no else.
  
Loop through objects
  Compare new words amount of repeated letters with mostRepeatLetters replacing whoever has more.
  In the end return the result of the word having most repeated letters
  If all words have no repeated letters return -1, ie. 
*/

所做的更改:

  • [.] 变成 . 因为 [.] 匹配文字句点符号,不是任何字符而是换行符
  • 在代码末尾添加关闭*/(最后一个注释块未关闭导致UNEXPECTED TOKEN ILLEGAL
  • if(howManyRepeat !== null || howManyRepeat !== 0) 应替换为 if(howManyRepeat !== null &amp;&amp; howManyRepeat !== 0),否则 null 将测试与 0 是否相等并导致 TypeError: Cannot read property 'length' of null" 问题。注意.match(/(.)\1+/g).length不能使用,因为匹配的结果可以为null,这也会导致TypeError出现。
  • 获取第一个重复次数最多的条目的算法是错误的,因为第一个 if 块允许将后续条目作为正确结果输出(不是第一个,而是输出具有相同重复次数的最后一个条目实际上)
  • 如果mostRepeatLetters 为空,则可以返回-1

【讨论】:

  • 天哪,谢谢!!你非常美!!我有最后一个问题:我注意到你在 for in 循环中增加了长度。 /(.)\1+/g 是否返回字母而不是数字?
  • 正则表达式仅适用于字符串。如果您将String#match 与全局正则表达式一起使用,它将返回一个字符串数组。或为空。
  • 但是 word 不是数组中的字符串吗?那么为什么它不起作用呢?如果变量是在函数内部声明的,为什么还要说全局?
  • 我不明白你,对不起。 “全局”正则表达式表示带有 /g 修饰符的正则表达式,这意味着它将在更大的字符串中查找所有匹配的子字符串。
  • 哦,好的。我以为你的意思是全球范围。好的,我知道了。但我看到你还是用 /g 了?那怎么不返回null呢?
【解决方案2】:

希望你不介意我重写这段代码。我的代码可能没有那么高效。 这是一个sn-p

function findGreatest() {
   // ipField is input field
    var getString = document.getElementById('ipField').value.toLowerCase();
    var finalArray = [];
    var strArray = [];
    var tempArray = [];
    strArray = (getString.split(" "));
    // Take only those words which has repeated letter
    for (var i = 0, j = strArray.length; i < j; i++) {
        if ((/([a-zA-Z]).*?\1/).test(strArray[i])) {
            tempArray.push(strArray[i]);
        }
    }
    if (tempArray.length == 0) {       // If no word with repeated Character
        console.log('No such Word');
        return -1;
    } else {                 // If array has words with repeated character
        for (var x = 0, y = tempArray.length; x < y; x++) {
            var m = findRepWord(tempArray[x]);  // Find number of repeated character in it
            finalArray.push({
                name: tempArray[x], 
                repeat: m
            })
        }
      // Sort this array to get word with largest repeated chars
        finalArray.sort(function(z, a) {
            return a.repeat - z.repeat
        })
        document.getElementById('repWord').textContent=finalArray[0].name;
    }
}

// Function to find the word which as highest repeated character(s)
    function findRepWord(str) {
        try {
            return str.match(/(.)\1+/g).length;
        } catch (e) {
            return 0;
        } // if TypeError
    }

这里是DEMO

【讨论】:

    【解决方案3】:

    function LetterCountI(str) { 
    
    var word_arr = str.split(" ");
      var x = word_arr.slice();
      
      for(var i = 0; i < x.length; i ++){
        var sum = 0;
        for(var y = 0; y < x[i].length; y++){
          var amount = x[i].split("").filter(function(a){return a == x[i][y]}).length;
          if (amount > 1){
            sum += amount
          }
          
        }
        x[i] = sum;
      }
       var max = Math.max.apply(Math,x);
      if(max == 0)
        return -1;
      var index = x.indexOf(max);
      return(word_arr[index]);
    };

    这里还有另一个版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      相关资源
      最近更新 更多