2013-03-05 17 views
5

これはMicrosoftのインタビューの質問です。Cのファイルから最後のn行を読み込む方法

C(正確に)

を使用してファイルの

読む最後のn行これを達成するために非常に多くの方法があるかもしれませんまあ、それらのいくつかは次のようになります。

- の>最も簡単な最初のパスではすべてファイル内の行数をカウントし、2回目のパスでは最後のn行を表示します。

- >または、各行に2重リンクリストを維持し、n番目の最後のノードまでリンクリストを逆行して最後のn行を表示することができます。

- > fnameは-nソート尾のようなものを実装

- 私たちが最後に到達するまで>より多くのそれを最適化するために、我々は、nと、ラウンドロビン方式で動的に保存されたすべての行と長さの二重のポインタを持つことができますファイルの

たとえば、ファイルに10行あり、最後の3行を読み込みたい場合。バッファの配列をbuf [3] []として作成することができ、実行時に最後の行に到達するまでmallocを続けてバッファを循環的に解放し、配列の現在のインデックスを知るためのカウンタを保持します。

上記の方法のいずれかが私に正しい答えや他の一般的なアプローチ/方法を得るのに役立つ場合は誰でも私にもっと最適化されたソリューションまたはatleastガイドを教えてください。

+0

最後の方が最適化されているようです。 –

+0

テールの実装を見てみましょうか? http:// stackoverflow。com/questions/10164597/how-would-you-implement-tail-efficient – StarPinkER

+1

余分な点については、ファイルの行数がn行未満の場合はエラーを返します。 –

答えて

8

キューを使用して、このキューに表示されている最後のn行を格納できます。 eofがキューを表示するだけです。

もう1つの方法は、ファイルの終わりから先頭に向かって1024バイトのブロックを読み取ることです。 n\n文字を見つけたら停止し、最後のn行を出力してください。

+0

+1エレガントな解決策:) –

+2

行がそれぞれ500バイトであれば、バッファ結合を管理するのは非常に時間がかかるでしょう。 – Anshul

+1

@ansh、right、その場合は、最後のn行までのギガバイトのデータを破棄してデータをバッファリングせずにオフセットを見つけることができますので、逆順で開始することも意味があります。 – perreal

4

最初にファイルの先頭を指す2つのファイルポインタを持つことができます。

'\ n'が見つかるまで、最初のポインタをインクリメントし続けると、 '\ n'が見つかるとファイルポインタのインスタンスも格納されます。

(n + 1)番目の '\ n'を見つけたら、先に保存したファイルポインタの最初のインスタンスを2番目のファイルポインタに割り当てます。EOFまで同じ操作を行います。

最初のファイルポインタがEOFのとき、2番目はn '\ n'になります。次に、2番目のファイルポインタからすべての文字をEOFに出力します。

これは、シングルパスで最後のn行をファイルに出力できる解決策です。

1

メモリマッピングされたファイルを使用してファイルを後方からスキャンするのはどうですか?これにより、バッファーのスペースよりも長いラインが発生するたびに、毎回バッファーウィンドウを更新するのが難しくなります。次に、\nが見つかったら、その位置をスタックに押し込みます。これはO(L)で動作します.Lは出力する文字数です。だからそれよりも本当に良いことは何もないのですか?

関連する問題