Penyortiran leksikografis di Java menciptakan tatanan yang aneh

Saya mencoba mengurutkan array objek berdasarkan nama yang ada di dalam array.

grades[].name

Saya menggunakan metode penyisipan dengan penyortiran leksikografis menggunakan bandingkanTo dan ini berfungsi jadi saya tahu saya menggunakan bandingkanTo dengan benar tetapi tidak semua nama dipindahkan dengan benar dan saya tidak yakin apakah itu pemahaman saya tentang cara kerja leksikografis atau jika loop saya yang menyebabkan masalah. Saya tahu leksikografik membandingkan setiap huruf dengan sendirinya untuk menentukan tempatnya. Saya awalnya mengira itu hanya memberi string nilai numerik dan sedang mencari cara untuk menemukannya, tetapi menurut saya bukan itu masalahnya. Saya telah melihat pertanyaan lain sehubungan dengan cara kerja penyortiran ini tetapi tampaknya tidak menjelaskan masalah saya. Saya ingin tahu apakah masalah saya adalah perulangan, pemahaman saya tentang metode pengurutan atau hal lain yang menyebabkan masalah keluaran ini.

Saya memiliki 3 kelas. Objek yang memanggil metode .insert adalah referensi ke kelas yang berisi array saya yang sebenarnya sehingga array tersebut dapat tetap bersifat pribadi.

   `GradeArray gradeArr = new GradeArray();

    gradeArr.insert("Evans", 78, courseID);
    gradeArr.insert("Smith", 77, courseID);
    gradeArr.insert("Yee", 83, courseID);
    gradeArr.insert("Adams", 63, courseID);
    gradeArr.insert("Hashimoto", 91, courseID);
    gradeArr.insert("Stimson", 89, courseID);
    gradeArr.insert("Velasquez", 72, courseID);
    gradeArr.insert("Lamarque", 74, courseID);
    gradeArr.insert("Vang", 52, courseID);
    gradeArr.insert("Creswell", 88, courseID);`

ini untuk membuat entri dalam array.

Inilah lingkaran penyortiran saya.

`  public String reportgrades() //this is grade sorted by name 
    {
        String output = "Sorted by name ";
        int in, out;
        StudentGrade temp; //this is to hold the orginal variable. 
        //for the first letter cycle
        for (out = 1; out < nElems; out++) {
            temp = grades[out];
            in = out;
            while (in > 0 && 0 < (grades[in - 1].name.compareTo(grades[in].name))) {
                grades[in] = grades[in - 1];
                in--;
            }
            grades[in] = temp;
        }
        for (int j = 0; j < nElems; j++) {
            output += grades[j].name + ", ";
        }
        return output;
    }`

Output yang dibuat adalah Sorted by name Evans, Smith, Adams, Hashimoto, Stimson, Velasquez, Lamarque, Vang, Creswell, Yee,

Saya bingung kenapa Evans dan Smith lebih dulu dari Adams. Saya telah mencoba melihat dokumen tentang cara kerja CompareTo tetapi sepertinya saya tidak melihat apa pun yang dapat memberi saya informasi apa pun tentangnya.


person Grimmjow56    schedule 03.02.2018    source sumber
comment
Apakah ini semacam pekerjaan rumah yang tantangan utamanya adalah menulis algoritma pengurutan Anda sendiri? Atau mengapa Anda tidak menggunakan pengurutan bawaan?   -  person Ringo Store    schedule 04.02.2018
comment
Mungkin SO memiliki motivasi diri dan ingin menulis semacam itu. Itu mungkin terjadi.   -  person nicomp    schedule 04.02.2018
comment
Secara serius, ini adalah pekerjaan untuk SO dan debuggernya. Lewati itu.   -  person nicomp    schedule 04.02.2018
comment
Perulangan while terputus segera setelah Anda menemukan nama yang 'lebih besar', Adams diganti dengan Yee.yang selalu 'lebih besar' . Jadi perulangan while akan selalu terputus setelah mencapai/memindahkan Yee.   -  person user85421    schedule 04.02.2018


Jawaban (4)


Ada masalah dengan algoritme saat Anda menggeser nilainya. Anda harus memasukkan grades[in-1] = temp; di dalam pernyataan while Anda untuk melakukan shift kerja. Saya tidak menggunakan GradeStudent hanya sebuah String tetapi Anda dapat beradaptasi. Array nilai hanyalah sebagai contoh.

public static String reportgrades() //this is grade sorted by name 
    {

    String[] grades = {"Evans", "Smith", "Adams", "Hashimoto", 
    "Stimson", "Velasquez", "Lamarque", "Vang", "Creswell", "Yee"};
    String output = "Sorted by name ";
    int in, out;
    String temp; //this is to hold the orginal variable. 
    //for the first letter cycle
    long nElems = grades.length; 
    for (out = 1; out < nElems; out++) {
        in = out;
        while (in > 0 &&  0 < (grades[in - 1].compareTo(grades[in]))) {
            temp = grades[in];
            grades[in] = grades[in-1];
            grades[in-1] = temp;
            in--;
        }    
    }
    for (int j = 0; j < nElems; j++) {
         output += grades[j] + ", ";
    }
    return output;
}
person vladwoguer    schedule 03.02.2018
comment
Perhatikan bahwa jika Anda perlu menganggap Adam dan Adam sama saat memesan, Anda perlu menambahkan huruf besar atau kecil. - person vladwoguer; 04.02.2018

Penggunaan bandingkanTo Anda baik-baik saja, tetapi Anda tidak membandingkan elemen yang tepat untuk penyortiran sisipan. Anda perlu membandingkan elemen yang ada di out dengan setiap elemen sebelumnya. Namun setelah langkah pertama dalam loop Anda, Anda hanya membandingkan elemen dari sebelumnya yang out satu sama lain.

Anda dapat mengubah loop while untuk membandingkannya dengan temp:

while (in > 0 && 0 < (grades[in - 1].name.compareTo(temp.name))) {

atau simpan sementara, tetapi ubah loop untuk menukar elemen dalam array, bukan hanya menggesernya ke kanan:

    for (out = 1; out < nElems; out++) {
        in = out;
        while (in > 0 && 0 < (grades[in - 1].name.compareTo(grades[in].name))) {
            // swap grades at in-1 and in
            StudentGrade temp = grades[in];
            grades[in] = grades[in - 1];
            grades[in - 1] = temp;
            in--;
        }
    }
person Peter Moore    schedule 03.02.2018

Pertama, tambahkan semua nama ke dalam daftar, lalu urutkan:

Collections.sort(list);      
person Ozodbek Kamolov    schedule 03.02.2018

Saya mengikuti vladwoguer menjawab dan memindahkan grades[in-1] = temp; ke dalam loop while saya. Saya tidak menyadari bahwa saya sebenarnya tidak memindahkan variabel yang saya inginkan. Saya pikir semuanya harus dipindahkan semuanya sebelum saya memasukkan kembali nama aslinya.

person Grimmjow56    schedule 04.02.2018