Mi programa tarda mucho para contar cadenas repetidas

De nuevo yo, estoy haciendo un programa que:
1.- Leea un archivo .log linea por linea y lo guarde en un array list, cada linea tiene un formato parecido a este:
$GPGSV, 3,2,12,07,37,335,47,03,36,052,43,27,42*79

2.-  crear un token, con un delimitador -> StringTokenizer st = new StringTokenizer( linea,", " );
3.- Ir guardando cada uno de los tokens en un nuevo arrayList2

2.- recorrer el ArrayList2   y verifica  que cada linea comienze con algun elemeto de un arreglo:{"$GPGGA","$GPRMC","$GPGSV","$GPGSA","$GPVTG","$GPGLL","$GPIOP","$GPGSM","$GPAREA",};
3.- Y por ultimo para contar cuantas veces se presento cada uno de los elementos del arreglo, utilice :
for (int l = 0 ; l {
int h = 1;
for (int m = l + 1 ; m{
if ( lineas2.get(l)!=null && lineas2.get(m)!=null && lineas2.get(l).equals(lineas2.get(m)) )
{
h++;
lineas2.set(m,null); }}
if ( lineas2.get(l)!= null)
{
System.out.println ( lineas2.get(l)+ " " + h + " VECES");
}}

Y si cuenta cuantos elementos se presentaron en el archivo, el problema es que tarda al rededor de 7.30 min, no se si es por que el archivo contiene al rededor de 279414 lineas aproximadamente .
Aunque no creo que se ese el problema, ya existen distintos tipos de lineas, y para las demás hace rapido el conteno, pues ya hice las demás funciones que cuenten cada tipo y funciona en menos de 10 segundos.
el codigo es:
import java.util.ArrayList;
import java.util.*;
import java.io.*;
import javax.swing.*;
class funcion1
{
public static void main(String [] arg) {
File archivo = null;
FileReader fr = null;
String linea;
String b;
ArrayList lineas = new ArrayList();
ArrayList lineas2=new ArrayList();
String p[]={ "$GPGGA","$GPRMC","$GPGSV","$GPGSA","$GPVTG","$GPGLL","$GPIOP","$GPGSM","$GPAREA",};
try {
archivo = new File ("C:/IGOT700002_9FEB2008.log");
fr = new FileReader (archivo);
BufferedReader br = new BufferedReader(fr);
while((linea=br.readLine())!=null){
lineas.add(linea); } //fin while
for (int j = 0 ; j < lineas.size() ; j++){
linea = (String)lineas.get(j);
StringTokenizer st = new StringTokenizer( linea,", " );
while(st.hasMoreTokens()){ //inicio while2
b= st.nextToken();
for (int c = 0; c< p.length; c++ )
if(b.startsWith(p[c]))
lineas2.add(b); }//fin while2
} //fin for
for (int k = 0 ; k < lineas2.size() ; k++){
b=(String)lineas2.get(k);}
//conteo
System.out.println ("OCURRENCIA DE PROTOCOLOS"+ "\n");
for (int l = 0 ; l <lineas2.size() ; l++)
{
int h = 1;
for (int m = l + 1 ; m<lineas2.size(); m++)
{
if ( lineas2.get(l)!=null && lineas2.get(m)!=null && lineas2.get(l).equals(lineas2.get(m)) )
{
h++;
lineas2.set(m,null); }}
if ( lineas2.get(l)!= null)
{
System.out.println ( lineas2.get(l)+ " " + h + " VECES");
}}
}//FIN DEL TRY
catch(IOException e){
System.out.println(e);
}
finally{
try{ //el bloque finally se ejecuta siempre, por eso, si se cierra el fichero
if( fr != null){ //al final del primer try, y ha dado un error antes, pasaría
fr.close(); //al 1er catch y luego saldría, dejándolo abierto. Es conveniente
} //cerrarlo aquí, comprobando que no sea -por un error anterior, como
}catch (IOException e){ // no tener permisos de lectura o que no exista - de valor null.
}
}
System.exit(0);}
}

1 respuesta

Respuesta
1
Si al final lo único que te interesa es tener una serie de contadores para ver el número de veces que el archivo contiene determinados comienzos de línea, creo que te estas liando demasiado. Te propongo el siguiente método, bastante más sencillo:
public static void main(String [] arg) {
    File archivo = null;
    FileReader fr = null;
    String linea;
    String p[]={ "$GPGGA","$GPRMC","$GPGSV","$GPGSA","$GPVTG","$GPGLL","$GPIOP","$GPGSM","$GPAREA",};
    int[] ocurrencias_p = new int[p.length];
    for (int i=0; i<ocurrencias_p.length; i++){
        ocurrencias_p
(i) = 0;
    }
    try {
       archivo = new File ("C:/IGOT700002_9FEB2008.log");
       fr = new FileReader (archivo);
      BufferedReader br = new BufferedReader(fr);
      while((linea=br.readLine())!=null){
          for (int i=0; i<p.length; i++){
              if (linea.startsWith(p)){
                  ocurrencias_p(i)++;
                  break;
              }
          } //fin for
      }// fin while
      for (int k = 0 ; k < p.length ; k++){
           System.out.println ("OCURRENCIA DEL PROTOCOLO '"+ p(k) + "' = " +               ocurrencias_p[k]);
      }
    }//FIN DEL TRY
    catch(IOException e){
        System.out.println(e);
    }
    finally{
       try{ //el bloque finally se ejecuta siempre, por eso, si se cierra el fichero
            if( fr != null){ //al final del primer try, y ha dado un error antes, pasaría
                  fr.close(); //al 1er catch y luego saldría, dejándolo abierto. Es conveniente
            } //cerrarlo aquí, comprobando que no sea -por un error anterior, como
       }catch (IOException e){ // no tener permisos de lectura o que no exista - de valor null.
       }
    }
    System.exit(0);
}

NOTA: en los bucles para recorrer los arrays, sustituye los paréntesis por corchetes. He puesto paréntesis para que el c... n del editor no me borre los corchetes, que luego no se entiende un pijo del código...
Espero que te solucione el problema. Seguro que es muchísimo más rápido que tu anterior método.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas