2012-03-26 5 views
3

Nun, das könnte ein dummes Problem sein.Schnellere Implementierung von mehr als einer Eingabe in einer einzigen Zeile (Java)

Ich möchte nur eine schnellere Implementierung von Problem folgenden

ich drei Integer-Eingang in einer einzigen Zeile zB nehmen will:

10 34 54 

Eine Möglichkeit ist es, eine BufferedReader zu machen und dann readline() verwenden, , die die ganze Zeile als eine Zeichenfolge lesen, dann können wir StringTokenizer verwenden, um drei ganze Zahlen zu trennen. (Langsame Implementation)

Eine andere Möglichkeit ist die Verwendung von 'Scanner' und die Eingabe der nextInt() Methode. (Langsamer als vorhergehende Methode)

Ich möchte eine schnelle Implementierung solche Art von Eingaben zu nehmen, da ich mehr als 2.000.000 Zeilen lesen muss und diese Implementierungen sind sehr langsam.

Meine Implementierung:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 

for(i=0;i<n;i++) { 
    str=br.readLine(); 
    st = new StringTokenizer(str); 
    t1=Integer.parseInt(st.nextElement().toString()); 
    t2=Integer.parseInt(st.nextElement().toString()); 
    z=Long.parseLong(st.nextElement().toString()); 
} 

Dieses wird durchgeschleift für n-mal. (N ist die Anzahl der Einträge) Da ich jede Zeile wissen, dass es nur drei ganze Zahl enthalten ist nicht nötig hasMoreElements()

+1

Wie langsam? Können Sie einen von Ihnen verwendeten Beispielcode sowie Timings posten? –

+0

Sie könnten BufferedReader verwenden und Ihr eigenes Parsing durchführen, das darauf spezialisiert ist, N Zeichen zu sammeln, bis Sie ein Leerzeichen oder das Ende der Zeichenfolge sehen. Dies könnte schneller sein. Beachten Sie, dass Sie in allen Fällen eine bessere Leistung erzielen, wenn Sie BufferedReader mit einem größeren Puffer verwenden (10kB werden schon viel helfen). – TheBlastOne

+0

@SteveMcLeod Ich habe diese Methode auf einer Programmierwebseite verwendet und das Zeitlimit überschritten. Also dachte ich, dass es eine bessere Methode dafür geben würde. – dejavu

Antwort

3

Ich möchte nur eine schnellere Umsetzung des folgenden Problems.

Die Wahrscheinlichkeit ist, dass Sie keine schnellere Implementierung benötigen. Ernst. Nicht einmal mit einer 2 Millionen Zeilen Eingabedatei.

Die Chancen sind, dass:

  • mehr Zeit damit verbracht wird die Verarbeitung der Datei als es zu lesen, und
  • die meisten der „Lesezeit“ ist, Dinge zu tun auf der Betriebssystemebene ausgegeben, oder einfach warten für den nächsten zu lesenden Plattenblock.

Mein Rat ist, nicht die Mühe, diese es sei denn die Anwendung zu optimieren als Ganzes laufen zu lange dauert. Wenn Sie feststellen, dass dies der Fall ist, profilieren Sie die Anwendung und verwenden Sie die Profilstatistiken, um zu erfahren, wo sich die Optimierung lohnt.

(Mein Bauchgefühl ist, dass es nicht viel ist durch die Optimierung dieses Teil Ihrer Anwendung gewonnen werden. Aber verlassen Sie sich nicht darauf. Profil es!)

+0

+1, d. H. "Vorzeitige Optimierung vermeiden" – TheBlastOne

0

zu überprüfen Hier ist ein einfaches Beispiel, das ziemlich schnell sein:

public static void main(String[] args) throws IOException { 
    BufferedReader reader = new BufferedReader(new FileReader("myfile.txt")); 
    String line; 
    while ((line = reader.readLine()) != null) { 
     for (String s : line.split(" ")) { 
      final int i = Integer.parseInt(s); 
      // do something with i... 
     } 
    } 
    reader.close(); 
} 

jedoch Ihre Aufgabe wird im Grunde Zeit brauchen.

Wenn Sie dies auf einer Website tun und eine Zeitüberschreitung erreichen, sollten Sie dies in einem Hintergrundthread berücksichtigen und eine Antwort an den Benutzer senden, der sagt, dass die Daten verarbeitet werden. Wahrscheinlich müssen Sie dem Benutzer eine Möglichkeit hinzufügen, den Fortschritt zu überprüfen.

+0

Werde dieses versuchen. Aber ich denke, es wird die gleiche Zeit wie StringTokenizer bieten. Mit Programming Web meinte ich Programming Competition (ähnlich wie TopCoder). – dejavu

+0

@Android lol ... komm, poste deinen Code und deine Timing-Ergebnisse und wir werden sehen, was wir für dich tun können. Alles andere ist ein Schuss in die Dunkelheit für uns und eine Verschwendung von Zeit. – TheBlastOne

+0

Integer.parseInt wird auch schwer zu ersetzen mit etwas effizienter UND lesbar. Dies könnte ein Fall von "String-to-Number-Conversion-ist-nicht-trivial-and-takes-ziemlich-einige-Zeit" Unterschätzung sein. I.e. Es könnte sein, dass die String-Aufteilung (oder Scanner-Nutzung) hier nicht die größte Leistungslücke ist. – TheBlastOne

0

Hier ist, was ich meine, wenn ich sage " Spezialscanner ".In Abhängigkeit von der Parser (oder Split) Effizienz, dies könnte etwas schneller sein (es ist wahrscheinlich nicht):

BufferedReader br=new BufferedReader(...); 
for(i=0;i<n;i++) 
{  
    String str=br.readLine(); 
    long[] resultLongs = {-1,-1,-1}; 
    int startPos=0; 
    int nextLongIndex=0; 
    for (int p=0;p<str.length();p++) 
    { 
     if (str.charAt(p)== ' ') 
     { 
      String intAsStr=str.substring(startPos, p-1); 
      resultLongs[nextLongIndex++]=Integer.parseInt(intAsStr); 
      startpos=p+1; 
     } 
    } 
    // t1, t2 and z are in resultLongs[0] through resultLongs[2]  
    } 

HTHS.

Und natürlich versagt dies kläglich, wenn die Eingabedatei Müll enthält, d. H. Alles andere als lange, getrennt durch Leerzeichen.

Und zusätzlich, um die "Roundtrips" zum Betriebssystem zu minimieren, ist es eine gute Idee, den gepufferten Leser mit einem nicht standardmäßigen (größer als Standard) Puffer zu versorgen. Der andere Hinweis, den ich in dem Kommentar gegeben habe, wurde präzisiert: Wenn man eine so große Textdatei mehr als einmal lesen muss, dh mehr als einmal nach der Aktualisierung, könnte man alle Longs in eine Datenstruktur schreiben (vielleicht a Liste der Elemente, die drei Longs enthalten) und streamen diese in eine "Cache" -Datei. Das nächste Mal vergleichen Sie den Zeitstempel der Textdatei mit der "Cache" -Datei. Wenn es älter ist, lesen Sie die Cache-Datei. Da Stream I/O Longs nicht in seine String-Darstellung serialisiert, werden Sie viel, viel bessere Lesezeiten sehen.

EDIT: Verpasste die StartPos Neuzuweisung. EDIT2: Die Erklärung der Cache-Idee hinzugefügt.

Verwandte Themen