0

名前を追加できるプログラムを作成しようとしていますが、それはRandomAccessFile, (アルファベット順) に保存されるはずです。ファイルに保存される名前を追加するたびに、次の名前に対応する次の位置が最後にあるはずです。A で始まる名前を追加するたびに保存に問題があり、次に C で名前を追加します。B で始まる名前を追加する場所を指定すると、正しいアルファベット順で表示されません。

プログラムが何をすべきかの例を次に示します。

Aで始まる名前を追加します。

「左側」の数字は次の名前の開始位置、「右側」の数字は次の名前へのポインタです

[0]-----A----[-1] ----------- 「-1」ポインターは、リストの最後を意味します

Cで始まる名前を追加します。

[0]-----A----[100] ------- 「100」ポインターは、次の名前「C」がバイト 100 から始まることを意味します

[100]---C----[-1] --------- リスト ポインターの終わり、A が "-1" ポインターを持たなくなったことに注意してください

Bで始まる名前を追加します。

[0]-----A----[200] ------ 次の文字は「B」であるべきなので、「A」はもはや 100 を指しません。

[100]---C----[-1] -------- -1 は、「C」がリスト ポインターの末尾であることを意味します。

[200]---B----[100] --------- 「B」は「C」を指しています。

これまでのコードですが、リストの途中に属する名前が追加されている部分がありません。

public boolean add(String name, String lastName, String telf) {

    try {
        fileSize = file.length();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    if (fileSize == 0) { //must be a new entry

        try {

            byte entry[] = new byte[sizeEntry];  // size of each entry
            file.write(entry);
            file.seek(file.getFilePointer() - sizeEntry);

            file.writeUTF(name);   //name gets saved
            file.writeUTF(lastName);// last name gets saved
            file.writeUTF(telf);    // telf gets saved
            file.writeUTF("N");     // deleted "Y" or "N" gets saved
            file.writeUTF("-1");    // pointer gets saved

        } catch (IOException e) {
            System.out.println("Error at saving....");
            e.printStackTrace();
        }

    } else {
        pPresent= 0;     //variable for the pointer reading
        pPrevious= 0; // variable for the pointer read

        try {
            file.seek(0); //start reading at the top
            do {
                pPresent= file.getFilePointer();//saves present pointer
                file.seek(pPresent);//seeks to present pointer
                nameRead = file.readUTF();  //reads name
                file.readUTF();  //reads last name
                file.readUTF();  //reads telf
                file.readUTF();  //reads deleted?
                pNext= Long.parseLong(file.readUTF()); // reads the next pointer

                int comparison= name.compareTo(nameRead);
                if (comparison< 0) {

                    //enters here if the new entry goes before the present entry
                    if (pNext!= -1) {
                        file.seek(pNext);//enters here if pointer is not at end of list
                    } else {
                        try {// proceeds to writing a new entry 

                            file.seek(file.length()); //goes to the end of the file
                            byte entry[] = new byte[sizeEntry];
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);
                            file.writeUTF(lastname);
                            file.writeUTF(telf);
                            file.writeUTF("N");
                            file.writeUTF(Long.toString(pPrevious));//writes the previous pointer

                            file.seek(pPrevious);//seeks to the previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads lastname
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted?
                            file.writeUTF(Long.toString(pPrevious));//overwrites the new previous

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                } else {//enteres here if the entry is bigger than the present

                    if (pNext!= -1) {
                        file.seek(pNext);
                    } else {
                        try {

                            pPresent= file.length()-sizeEntry;//saves present entry
                            file.seek(pPrevious); //seeks to previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads last name
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted
                            file.writeUTF(Long.toString(pPresent+100));//overwrites the next pointer

                            file.seek(file.length());//seeks at the end
                            byte entry[] = new byte[sizeEntry];//creates a new entry
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);//writes name
                            file.writeUTF(lastname);//writes lastname
                            file.writeUTF(telf);//writes telf
                            file.writeUTF("N");//writes deleted
                            file.writeUTF(Long.toString(pNext));//writes next pointer

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                }
                pPresent= file.getFilePointer();//present pointer read
                pPrevious= pPresent;//present pointer becomes previous
            } while (true);


        } catch (IOException e) {

            System.out.println("Error at saving....");
            e.printStackTrace();
        }
    }
    return false;
}

ソースコードでプログラムの考え方を少しでも理解していただければ幸いです。どうすればよいかわからない部分は、リストの真ん中に属するエントリを追加する場所です。名前の順序は、次を指すポインターのみを変更するわけではないことに注意してください。

4

2 に答える 2

1

挿入ポイントを見つけるには、リストをたどる必要があり、その結果、名前ごとにディスク アクセスが必要になります。100 万の名前があり、通常のディスク アクセス時間が 10 ミリ秒であると仮定すると、1 つの名前を挿入するのに約 3 時間かかります。別の言い方をすれば、連結リストはディスクにデータを保存するのに非常に不適切なデータ構造です。

B ツリーなどの合理的なデータ構造では、わずか 3 回のディスク アクセスで 100 万の名前の検索と挿入が可能になります。

于 2012-10-26T23:45:19.623 に答える
1

ポインターを計算するメソッドを開発する必要があります。数日前にコードを開発しました。

public int getNext(String lastName){

    int auxNext=0;
    int auxActual=0;
    byte[] relleno= new byte[100];

    try{

        int Next=-1;

        while(auxNext!=-1){                                             

            auxActual=auxNext;              
            myRaf.seek(auxNext);
            String auxPreviousLastName=myRaf.readUTF();

            auxNext=Integer.valueOf(myRaf.readUTF());

            if(auxNext!=-1){

                myRaf.seek(auxNext);
                String auxApellido=myRaf.readUTF();

                String aux=myRaf.readUTF();

                if(lastName.compareTo(auxLastName)<0){                          

                    Next=auxNext;                                       
                    myRaf.seek(auxActual);                                  
                    myRaf.write(relleno);
                    myRaf.seek(auxActual);
                    myRaf.writeUTF(auxPreviousLastName);                        
                    myRaf.writeUTF(String.valueOf(myRaf.length()));
                    return Next;                                            

                }

            }else{                                                          

                updateEnds();
                return -1;                                                  

            }

        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return -1;

}

public void updateEnds(){       //This method search the last register, and updates that reference

    byte[] relleno= new byte[100];

    try {
        for (int i = 0; i < myRaf.length(); i+=100) {               

            myRaf.seek(i);
            String auxLastName=myRaf.readUTF();             
            String next=myRaf.readUTF();

            if (next.equals("-1")) {                                    

                myRaf.seek(i);                                          
                myRaf.write(relleno);                                   
                myRaf.seek(i);                                          
                myRaf.writeUTF(auxLastName);
                myRaf.writeUTF(String.valueOf(myRaf.length())); 


            }

        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

PD、申し訳ありませんが、私はあなたほど上手に英語を書くことができません。

于 2012-10-29T23:12:04.513 に答える