3

次の擬似コードからJavaコードをどのように書くのか疑問に思います

 foreach file F in file directory D
        foreach int I in file F
               sort all I from each file

基本的にこれは外部ソーティングアルゴリズムの一部であるため、これらのファイルには並べ替えられた整数のリストが含まれています。各ファイルから最初の整数を読み取り、並べ替えてから別のファイルに出力してから、各ファイルから次の整数に移動します。すべての整数が完全にソートされるまで、もう一度。
問題は、各ファイルについて私が理解している限り、リーダーが必要なことです。したがって、N個のファイルがある場合、それはNのファイルリーダーが必要であることを意味しますか?

======更新=======

こんな感じなのかな?私が何かまたは他のより良いアプローチを逃した場合は私を訂正してください。

int numOfFiles = 10;
Scanner [] scanners = new Scanner[numOfFiles];
try{
    //reader all the files
    for(int i = 0 ; i < numOfFiles; i++){
        scanners[i] = new Scanner(new BufferedReader(
            new FileReader("file"+i+".txt");
    }
}
catch(FileNotFoundException fnfe){

}
4

5 に答える 5

1

問題は、各ファイルについて私が理解している限り、リーダーが必要なことです。したがって、N個のファイルがある場合、それはN個のファイルリーダーが必要であることを意味しますか?

はい、その通りです。データに戻るか、各ファイル全体をメモリに戻す必要がない限り、そうです。どちらの場合も、一度に1つのファイルだけを開いたままで済ませることができますが、それはあなたがやりたいことに適していない可能性があります。

オペレーティングシステムでは通常、一度に特定の数のファイルしか開くことができません。非常に多数のファイルから単一のソートされた結果セットを作成するようなことをしようとしている場合は、一度にいくつかのファイルを操作して、より大きな中間ファイルを作成することを検討することをお勧めします。最も単純な場合、これは一度に2つのファイルをソートするだけです。

input1 + input2 => tmp-a1
input3 + input4 => tmp-a2
input5 + input6 => tmp-a3
input7 + input8 => tmp-a4

tmp-a1 + tmp-a2 => tmp-b1
tmp-a3 + tmp-a4 => tmp-b2

tmp-b1 + tmp-b2 => result
于 2012-11-19T06:47:09.210 に答える
0

私が最近dsクラスで学んだPolyphaseマージソートと呼ばれるメソッドがあります。このメソッドでは、ファイルを実行の形式でトラバースします(実行はソートされたシーケンスです)。n個のソースと宛先があります。

この多相メソッドの要点は、(ファイルのセットが与えられた場合)ファイルをアイドル状態に保つ必要がないことです。反復が大幅に削減されます。これは、ファイル数と同じ順序のフィボナッチ数列を取ることによって行われます。したがって、5つのファイルの場合、次数5のfibシーケンスを使用します。[1,1,2,4,8]は、各ファイルから取り出して配置する実行の数を表します。ここで、runs = 1に対応するファイルから、そのうちの1つが宛先になります。

要するに:

  1. fibシーケンスに従ってファイルを実行に分散します。[これは、データセット全体が1つのファイルにあることを意味します。そうでない場合は、シーケンスに合わせてダミーの実行を追加したい場合に、いつでもその場で実行を作成できます]
  2. すべてのファイルから最初のn回の実行をバッファに取り、それらをソートし(挿入を推奨)、1つのファイルにダンプします。その1つのファイルは、フィボナッチ数列によって再び選択されます。
  3. 1回の実行で1つのファイルを取得するポイントまで実行します。

多相の概念をきちんと説明した論文です。ftp://reports.stanford.edu/pub/cstr/reports/cs/tr/76/543/CS-TR-76-543.pdf

http://en.wikipedia.org/wiki/Polyphase_merge_sortはアルゴをよりよく説明しています

于 2012-11-19T08:24:14.933 に答える
0

「N個のファイルリーダーが必要ですか?」と答えずに、コードを提示するだけです。:)

org.apache.commons.io を使用します。

//get line iterators :
Collection<File> files = FileUtils.listFiles(/* TODO : filter conf */);
List<LineIterator> iters = new ArrayList<LineIterator>();
for(File file : files) {
  iters.add(FileUtils.lineIterator(file, "UTF-8"));
}

//collect a line from each file
List<String> numbers = new ArrayList<String>();
for(LineIterator li : iters) {
  numbers.add(li.nextLine());
}

//sort
//Arrays.sort(numbers/*will fail*/);//  :)
于 2012-11-19T07:31:10.667 に答える
0

はい、N 個のファイルを読み取るには N 個のファイル リーダーが必要です。

ディレクトリ内のすべてのファイルを反復するには、ファイルを 1 つずつ読み取り、リストに保存します。次に、そのリストをもう一度並べ替えて、出力を取得します。

于 2012-11-19T06:52:28.210 に答える
-2

はい、N個のファイルリーダーが必要です。

public void workOnFiles(){

    File []D = new File("directoryName").listFiles(); //D.length should equal to N.

    for(File F:D){

        doSortingForEachFile(F);//do sorting part here. The same reader cannot open same file here again.

    }
}

public void doSortingForEachFile(File f){
    try{
        ArrayList<Integer> list=new ArrayList<Integer>();
        Scanner s=new Scanner(f);
        while(s.hasNextInt()){//store ints inside the file.
            list.add(s.nextInt());
        }
        s.close();//once closed, cannot open again.
        Collections.sort(list);//this method will sort the ArrayList of int.
        //...write numbers inside list to another file...
    }catch(Exception e){}
}
于 2012-11-19T06:48:30.657 に答える