Estoy tomando el desafío LeetCode 819. Palabra más común :
Dado un
paragraphde cadena y una matriz de cadenas de palabrasbanned, devuelve la palabra más frecuente que no está prohibida . Se garantiza que hay al menos una palabra que no está prohibida y que la respuesta es única .Las palabras en el
paragraphno distinguen entre mayúsculas y minúsculas y la respuesta debe devolverse en minúsculas .Ejemplo 1
Entrada:
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit.",banned = ["hit"]
Salida:"ball"
Este es mi código:
var mostCommonWord = function(paragraph, banned) { let words = paragraph.toLowerCase().split(" "); let unbannedwords = words.filter((word)=> word !== banned[0] ); let map = {}; console.log(unbannedwords) for (let i = 0; i < unbannedwords.length; i++) { count = 0; for (let j = i + 1; j < unbannedwords.length; j++) { if (unbannedwords[i] === unbannedwords[j]) { count++; map[unbannedwords[i]] = count; } } } console.log(map) let obj = Object.values(map) let max = Math.max(...obj); function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); } return getKeyByValue(map, max); }; Salida console.log :
[ 'bob', 'a', 'ball', 'the', 'ball', 'flew', 'far', 'after', 'it', 'was' ] { } No sé por qué las propiedades no provienen del bucle en el objeto del map .
El problema es que la llamada split(" ") dejará la puntuación, por lo que tendrá tanto "pelota" como "pelota" en la matriz resultante. Obviamente, esto hará que su código pierda algunas igualdades.
Para resolver esto, cambie esta línea:
let words = paragraph.toLowerCase().split(" ");a:
let words = paragraph.toLowerCase().match(/\w+/g); Se produce un segundo problema con la forma en que establece los valores del map . Actualmente, está reiniciando el conteo cuando se encuentra una palabra por segunda vez en el ciclo externo. Entonces el primer encuentro ya no jugará un papel. Además, el map solo registrará palabras cuando ocurran al menos 2 veces (una vez en el bucle externo, una vez en el bucle interno).
Debe asegurarse de configurar map[unbannedwords[i]] incluso cuando no haya una próxima ocurrencia. La ventaja del mapa debería ser que no necesita el segundo bucle, sino que el primer bucle encontrará la entrada en el mapa y simplemente la incrementará con una si ya existe.
Todavía tendrá otras cosas que hacer, ya que actualmente su código solo tiene en cuenta la primera palabra prohibida, es decir, banned[0] . En un comentario, propone usar replaceAll(banned, "") , pero no es así como funciona replaceAll . Espera que su primer argumento sea una cadena o una expresión regular. Dado que le pasa una matriz, la matriz se convierte en una sola cadena unida por comas, que es poco probable que coincida con nada.
Aquí hay una solución de spoiler:
var mostCommonWord = function(paragraph, banned) { const words = paragraph.toLowerCase() .match(/\w+/g) .filter(word => !banned.includes(word)) const count = {}; for (const word of words) count[word] = (count[word] ?? 0) + 1; const maxCount = Math.max(...Object.values(count)); return Object.keys(count).find(word => count[word] == maxCount); };