2013-03-05 3 views
5

Es ist ein Microsoft Interview Frage.Wie liest man die letzten n Zeilen aus einer Datei in C

lesen letzten n Zeilen der Datei C mit (genau)

Nun könnte es so viele Möglichkeiten, dies zu erreichen, einige von ihnen sein könnte:

-> Einfachstes von alle, im ersten Durchlauf, zählen die Anzahl der Zeilen in der Datei und im zweiten Durchlauf die letzten n Zeilen.

-> Oder Sie können eine doppelt verknüpfte Liste für jede Zeile pflegen und die letzten n Zeilen anzeigen, indem Sie die verknüpfte Liste bis zum letzten Knoten durchlaufen.

-> Implementieren Sie etwas Art tail -n fname

-> Um es zu optimieren mehr wir Doppel Zeiger mit Länge als n und jeder Zeile gespeichert dynamisch in einer Round-Robin-Mode haben können, bis wir das Ende erreichen der Datei.

zum Beispiel, wenn 10 Zeilen in der Datei sind und die letzten 3 Zeilen gelesen werden sollen. Dann könnten wir ein Puffer-Array als buf [3] [] erstellen und zur Laufzeit den Mall-Speicher weitermachen und den Puffer auf zirkuläre Weise freigeben, bis wir die letzte Zeile erreichen und einen Zähler behalten, um den aktuellen Index des Arrays zu kennen.

Kann mir bitte jemand mit einer optimierten Lösung helfen oder mich zumindest leiten, wenn einer der oben genannten Ansätze mir helfen kann, die richtige Antwort oder einen anderen gängigen Ansatz/Methode für solche Fragen zu bekommen.

+0

letzter scheint optimiert zu sein. –

+0

Werfen Sie einen Blick auf die Schwanz-Implementierung? http: // Stapelüberlauf.com/questions/10164597/how-wo-du-du-implementieren-tail-effizient – StarPinkER

+1

Für zusätzliche Punkte, geben Sie einen Fehler zurück, wenn die Datei weniger als n Zeilen hat. –

Antwort

8

Sie können eine Warteschlange verwenden und die letzten n Zeilen in dieser Warteschlange speichern. Wenn Sie den eof sehen, drucken Sie einfach die Warteschlange aus.

Eine andere Möglichkeit ist das Lesen eines Blocks von 1024 Bytes vom Ende der Datei zum Anfang hin. Stoppen Sie, wenn Sie n\n Zeichen finden und drucken Sie die letzten n Zeilen aus.

+0

+1 Elegante Lösung :) –

+2

Was ist, wenn die Zeilen jeweils 500 Bytes sind, wird es ein großer Zeitschmerz bei der Verwaltung der Pufferverbindungen sein. – Anshul

+1

@ansh, right, in diesem Fall kann der Rückwärtsstart sinnvoll sein, da Sie möglicherweise Gigabytes an Daten bis zu den letzten n Zeilen verwerfen und die Daten nicht puffern wollen, sondern einfach den Offset – perreal

4

Sie können zwei Dateizeiger haben, die anfänglich auf den Anfang der Datei zeigen.

Inkrementieren Sie den ersten Zeiger, bis das Zeichen '\ n' gefunden wird. Außerdem wird die Instanz des Dateizeigers gespeichert, wenn '\ n' gefunden wird.

Sobald Sie (n + 1) th '\ n' gefunden haben, weisen Sie die zuerst gespeicherte Dateizeigerdatei, die wir zuvor gespeichert hatten, dem zweiten Dateizeiger zu. Führen Sie dasselbe bis EOF durch.

Wenn also der erste Dateizeiger auf EOF steht, ist der zweite auf n '\ n' zurück. Dann werden alle Zeichen aus dem zweiten Dateizeiger auf EOF gedruckt.

So ist diese Lösung, die letzte n Zeilen in Datei in einem Durchgang drucken kann.

1

Wie wäre es mit Memory-Mapped-Datei und scannen Sie die Datei von rückwärts? Dies eliminiert die harte Arbeit des Aktualisierens des Pufferfensters jedes Mal jedes Mal, wenn die Zeilen zufällig länger waren als Ihr Pufferspeicher. Wenn Sie dann eine \n gefunden haben, drücken Sie die Position in einen Stapel. Dies funktioniert in O(L), wobei L die Anzahl der auszugebenden Zeichen ist. Also gibt es nichts wirklich besseres als das ist es?

Verwandte Themen