2010-08-01 10 views
6

Mi profesor me asignó un vocabulario en inglés.Trabajando con enormes archivos de texto en Java

Elija un alfabeto al azar, dicen 'a' Escriba una palabra del alfabeto, por ejemplo 'manzana' Toma la última palabra 'e' Escribir una palabra de correo, por ejemplo elefante ahora de 't' y así sucesivamente .. No se permiten repeticiones

Haga una lista de 500 palabras. Envíe la lista al maestro. :)

Así que en lugar de hacerlo yo mismo, estoy trabajando en un código Java que hará mi tarea por mí. El código parece ser simple.

El núcleo del algoritmo: Elija una palabra aleatoria de un diccionario, que cumpla con los requisitos. seek() con RandomAccessFile. Trate de ponerlo en un conjunto con el pedido (tal vez LinkedHashSet)

Pero el problema es el gran tamaño del diccionario con más de 300 000 enteries. : | Los algoritmos aleatorios de fuerza bruta no funcionan.

¿Cuál podría ser la salida mejor, más rápida y más eficiente?

**** ACTUALIZACIÓN: ** Ahora que he escrito el código y funciona. ¿Cómo puedo hacer que sea eficiente para que elija palabras comunes? Cualquier archivo de texto que contenga una lista de palabras comunes alrededor de ** **

+0

FYI: 1 lakh = 100000 – miku

+0

Bastante consciente de ello. ¡El archivo de texto es de 4MB! –

+1

4MB es bastante pequeño, ¿no? – miku

Respuesta

4

Busque una estructura de datos que le permita mantener un diccionario compactado en la memoria o simplemente darle más memoria a su proceso. Trescientas mil palabras no es mucho.

+0

Y use un contenedor de diccionario java (por ejemplo) hashmap para poner su archivo de diccionario, por supuesto: p (Lo leí como si siempre lo estuviera buscando desde un archivo). – KillianDS

+0

Siempre estoy buscando un archivo hasta ahora. : | –

+2

@Myth, no lo hagas, solo léelo en un HashMap y trabaja con eso. –

0

Creo que una manera de hacer esto podría ser usar TreeSet donde pone todo el diccionario y luego usar el método subSet para recuperar todas las palabras que comienzan por la letra deseada y hacer un azar en el subconjunto.

Pero en mi opinión, la mejor manera de hacerlo, debido a la cantidad de datos, sería utilizar una base de datos con solicitudes SQL en lugar de Java.

-1

El objetivo es aumentar su vocabulario del idioma Inglés - no aumentar vocabulario del idioma Inglés de su ordenador.

Si no comparte este objetivo, ¿por qué usted (o sus padres) pagan la matrícula?

+2

es una asignación de rutina de la universidad. Y estoy bastante seguro de mi inglés. Se puede hacer fácilmente Escribir un código para ello aprenderá algo. :) –

+1

Es una tarea tan estúpida que las trampas no solo están permitidas, sino que también se recomiendan. Devolvería una lista de 500 blasfemias solo para aclarar mi punto. –

+0

Estoy de acuerdo con Myth17, suena como una repetición. –

0

Si hago esto:

class LoadWords { 
    public static void main(String... args) { 
    try { 
     Scanner s = new Scanner(new File("/usr/share/dict/words")); 
     ArrayList<String> ss = new ArrayList<String>(); 
     while (s.hasNextLine()) 
     ss.add(s.nextLine()); 
     System.out.format("Read %d words\n", ss.size()); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(System.err); 
    } 
    } 
} 

puedo correr con java -mx16m LoadWords, lo que limita el tamaño de almacenamiento dinámico de Java a 16 Mb, que no es la cantidad de memoria para Java. Mi archivo /usr/share/dict/words tiene aproximadamente 250,000 palabras, por lo que puede ser un poco más pequeño que el tuyo.

Tendrá que utilizar una estructura de datos diferente a la simple ArrayList<String> que he usado. Tal vez un HashMap de ArrayList<String>, tecleado en la letra inicial de la palabra sería una buena opción para comenzar.

1

espero que esto no estropear su diversión o algo, pero si yo fuera usted me tomaría este enfoque ..

Pseudo java:

abstract class Word { 
    String word; 
    char last(); 
    char first();   
} 

abstract class DynamicDictionary { 
    Map<Character,Set<Word>> first_indexed; 

    Word removeNext(Word word){ 
     Set<Word> candidates = first_indexed.get(word.last()); 
     return removeRandom(candidates); 
    } 

    /** 
    * Remove a random word out from the entire dic. 
    */ 
    Word removeRandom(); 

    /** 
    * Remove and return a random word out from the set provided. 
    */ 
    Word removeRandom(Set<Word> wordset);  
} 

y luego

Word primer = dynamicDictionary.removeRandom(); 
List<Word> list = new ArrayList<Word>(500); 
list.add(primer); 
for(int i=0, Word cur = primer;i<499;i++){ 
    cur = dynamicDictionary.removeNext(cur); 
    list.add(cur); 
} 

NOTA: No está pensado para ser visto como código java real, solo una forma de explicar aproximadamente el enfoque (sin manejo de errores, ni una buena estructura de clases si realmente se usó, ningún cifrado, etc.)

¿Debo encontrar problemas de memoria, tal vez voy a hacer esto:

abstract class Word { 
    int lineNumber; 
    char last(); 
    char first(); 
} 

Si eso no es suficiente, supongo que voy a utilizar una búsqueda binaria en el archivo o ponerlo en una base de datos, etc ..

Cuestiones relacionadas