Durante una entrevista para un puesto de desarrollador de Java, me preguntaron lo siguiente:
Escribe una función que tome dos parámetros:
- una cadena que representa un documento de texto y
- un número entero que proporciona la cantidad de artículos a devolver.
Implemente la función de modo que devuelva una lista de cadenas ordenadas por frecuencia de palabra, la palabra que aparece con más frecuencia primero. Su solución debe ejecutarse en tiempo donde n es el número de caracteres en el documento.
Lo siguiente es lo que respondí (en pseudocódigo), no es sino tiempo O ( n log n ) debido al tipo. No puedo entender cómo hacerlo O ( n ) tiempo.
wordFrequencyMap = new HashMap<String, Integer>();
words = inputString.split(' ');
for (String word : words) {
count = wordFrequencyMap.get(word);
count = (count == null) ? 1 : ++count;
wordFrequencyMap.put(word, count);
}
return wordFrequencyMap.sortByValue.keys
¿Alguien sabe o alguien puede darme algunas pistas?
algorithms
sorting
strings
data-mining
usuario2712937
fuente
fuente
Hashtable
es Java heredado o no, es realmente irrelevante para los propósitos de este sitio.Respuestas:
Sugiero una variación del recuento de distribución:
maxWordCound
. -maxWordCount
. El tipo de entrada son listas de cadenas. - , ya que el recuento no puede ser mayor.Probablemente pueda reemplazar el trie por otras estructuras de datos en la primera fase.
fuente
La recopilación de recuentos de ocurrencias es O (n), por lo que el truco es realmente solo encontrar los mejores recuentos de ocurrencias k.
Un montón es una forma común de agregar los valores de k superiores, aunque se pueden usar otros métodos (ver https://en.wikipedia.org/wiki/Partial_sorting ).
Suponiendo que k es el segundo parámetro anterior, y que es una constante en la declaración del problema (parece ser):
Como el tamaño de almacenamiento dinámico es constante, las operaciones de almacenamiento dinámico son O (1), por lo que el paso 3 es O (n).
El montón también podría mantenerse dinámicamente mientras se construye el trie.
fuente
Lo que sigue está mal ; Lo dejo aquí por el momento con fines ilustrativos.
Construya un árbol de sufijos del texto, por ejemplo, con el algoritmo de Ukkonen .
Si la construcción aún no hace esto, agregue el número de hojas alcanzables a cada nodo (interno).
Atraviesa el árbol desde la raíz y corta todas las ramas en el primer espacio (blanco).
Recorre el árbol y ordena la lista de hijos de cada nodo por sus recuentos de hojas.
El rendimiento del árbol (hojas de izquierda a derecha) ahora es una lista de todas las palabras, ordenadas por frecuencia.
En cuanto al tiempo de ejecución:
Se pueden obtener límites más precisos parametrizando el tiempo de ejecución con el número de palabras diferentes; si hay pocos, el árbol es pequeño después de 2.
fuente
HashMap
fuente
Solución basada en hash
La suposición es que el algoritmo de hash es lineal en el tiempo en relación con el número de caracteres.
Solución basada en clasificación Radix
Las primeras palabras más largas en inglés son ridículamente largas , pero luego se puede limitar la longitud de la palabra en un número razonable (como 30 o menos) y truncar las palabras aceptando el margen de error que podría venir con ella.
fuente