【问题标题】:Sorting a string array and a int array对字符串数组和 int 数组进行排序
【发布时间】:2015-07-27 02:53:06
【问题描述】:

我正在练习数组排序,我已经成功排序了一个字符串数组。

我的小程序允许用户输入第一个学生人数,然后是每个学生的姓名,最后是每个学生的年级。

但我还想对 int studentGrade 数组进行排序,以便打印输出中的成绩与学生匹配。在这里,我真的被困住了。方法中的更多解释请参见下文:public void sortingAlgorithm

package assignment8exam;

import java.util.Scanner;
import java.util.Arrays;

/**
 *
 * @author Anders
 */
public class Course {

    Scanner sc = new Scanner(System.in);

    public void MainMenu() {

        System.out.println("Enter data about a student, start by entering how many");

        int numbers = sc.nextInt();// amount of student
        String studentNames[] = new String[numbers];
        int studentGrade[] = new int[numbers];
        for (int i = 0; i < numbers; i++) {

            System.out.println("Enter name of student");
            Scanner name = new Scanner(System.in);

            String names = name.nextLine();
            studentNames[i] = names;
        }

        for (int j = 0; j < numbers; j++) {

            System.out.println("Enter grade of student");
            Scanner gradeSc = new Scanner(System.in);

            int grade = gradeSc.nextInt();
            studentGrade[j] = grade;
        }

        sortingArray(studentNames);
        System.out.println("------------------------------------\n");
        sortAlgorithm(studentNames, studentGrade);
        System.out.println("What do you want");
        System.out.println("Exit application 1");
        System.out.println("Print out all names of the students 2");
        System.out.println("Print out all the grades of the students 3");
        System.out.println("Print out pairs consisting of “name­grade 4");
        System.out.println("Search for a student - 5");
        Scanner choice = new Scanner(System.in);
        int order = choice.nextInt();

        switch (order) {

            case 1:
                System.exit(1);

            case 2:
                PrintOutNames(numbers, studentNames);

            case 3:
                PrintOutGrades(numbers, studentGrade);

            case 4:
                PrintOutAll(numbers, studentGrade, studentNames);

            case 5:
                search(numbers, studentGrade, studentNames);

        }

    }

    public static void PrintOutNames(int numbers, String studentNames[]) {

        for (int i = 0; i < numbers; i++) {

            System.out.println(studentNames[i]);

        }
    }

    public static void PrintOutGrades(int numbers, int studentGrade[]) {

        for (int i = 0; i < numbers; i++) {

            System.out.println(studentGrade[i]);

        }

    }

    public static void PrintOutAll(int numbers, int studentGrade[], String studentNames[]) {
        System.out.println("--------------------------------------------------------\n");
        for (int i = 0; i < numbers; i++) {

            System.out.println("Name----> " + studentNames[i] + " grade ---> " + studentGrade[i]);

        }

    }

    public static void search(int numbers, int studentGrade[], String studentNames[]) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter name on student you want to search on ");
        String search = sc.nextLine();
        for (int i = 0; i < numbers; i++) {

            if (search.equals(studentNames[i])) {

                System.out.println("Yes we have a student named " + studentNames[i] + " with the Grade " + studentGrade[i] + " \n ");

            }

        }
    }

    public static void sortingArray(String studentNames[]) {

        Arrays.sort(studentNames);
        System.out.println("-------------\n" + Arrays.toString(studentNames));

    }

    public static void sortAlgorithm(String studentNames[], int studentGrade[]) {

        boolean flag = true;

        while (flag) {

            flag = false;

            for (int j = 0; j < studentNames.length - 1; j++) {

                for (int i = j + 1; i < studentNames.length; i++) {
                    if (studentNames[i].compareTo(studentNames[j]) < 0) {
                        String temp = studentNames[j];
                        studentNames[j] = studentNames[i];
                        studentNames[i] = temp;

                                                                                             // Here i want to place another array that sorts the grade?? how do i do that?
                    }

                }

                System.out.println(Arrays.toString(studentNames));
                System.out.println(Arrays.toString(studentGrade));

            }
        }
    }
}

【问题讨论】:

  • 我的第一条建议是避免从多个数组开始 - 拥有一个 Student 对象集合,其中每个学生都有一个姓名和一个年级。这将使您的生活更轻松。 (我还阅读了 Java 命名约定...)
  • 创建一个类Student,该类使用名称和等级创建。将所有 Student 对象存储在列表中。然后独立于您对列表进行排序的标准(使用Comparator),您可以访问相关的其他值。
  • 有一个学生抽象是关键。
  • 有点跑题了,但是你的switch-case 没有breaks

标签: java arrays sorting


【解决方案1】:

您的方法的问题在于学生姓名和成绩之间没有关系。如果您对姓名进行排序并对成绩进行排序,您最终会得到字母 A 成绩最低的学生。

如果这是一个 java 作业,最好的方法是创建一个名为 Student 的数据结构(类),它有名字和等级。

class Student{
 String name;
 int grade;
}

那么您将不会有两个数组,一个包含姓名,另一个包含成绩,而只有一个学生数组,您将能够按成绩、姓名等对该数组进行排序。

如果您想要一个更快的解决方案,那就是使用像 Map&lt;String,Integer&gt; 这样包含每个学生成绩的地图。

如果您想使用多个数组,您可以使用sortAlgorithm 方法交换两个数组中的相同索引(不仅在名称数组中),这样您最终将获得按名称排序的成绩。这是 IMO 最糟糕的方法,因为您过于依赖数组索引,而不是在对象之间建立某种关系。

【讨论】:

    【解决方案2】:

    在这种特殊情况下,解决方案相对容易。在这个地方,你交换两个学生的名字:

                for (int i = j + 1; i < studentNames.length; i++) {
                    if (studentNames[i].compareTo(studentNames[j]) < 0) {
                        String temp = studentNames[j];
                        studentNames[j] = studentNames[i];
                        studentNames[i] = temp;
    
    
                    }
    
                }
    

    你也同时交换相应的成绩:

                for (int i = j + 1; i < studentNames.length; i++) {
                    if (studentNames[i].compareTo(studentNames[j]) < 0) {
                        String temp = studentNames[j];
                        studentNames[j] = studentNames[i];
                        studentNames[i] = temp;
    
                        int tempGrade = studentGrades[j];
                        studentGrades[j] = studentGrades[i];
                        studentGrades[i] = tempGrade;
                    }
    
                }
    

    因此,每当您切换两个学生姓名时,都会同时切换相应的成绩。这将使两个数组保持同步。

    但正如其他人一直在推荐的那样,更好的方法是创建一个代表学生的班级 - 包括姓名和年级。为什么?因为在现实世界的案例中,学生可能拥有其他数据,例如不同的科目及其匹配的成绩、出勤记录、联系信息,无论大学需要什么。

    并且必须为每个此类数据项将其添加到循环中会使其变得难以处理。如果您在一条记录中拥有所有信息,则只需交换记录引用,然后将整个数据一起交换

    它的基础是这样的类:

    class Student implements Comparable<Student> {
       private String name;
       private int grade = 0;
    
       public Student( String name ) {
            this.name = name;
       }
    
       public void setGrade( int grade ) {
            this.grade = grade;
       }
    
       // In addition, you'll have getName(), getGrade(),
       // and possibly a good `toString()` for printing a
       // student record.
    
       @Override
       public int compareTo( Student otherStudent ) {
           return this.name.compareTo( otherStudent.name );
       }
    }
    

    现在您可以定义一个数组,例如:

    Student[] students = new Students[numbers];
    

    你可以直接用Arrays.sort()排序,因为Student实现了Comparable,或者你可以自己做排序算法,使用compareTo方法。你的循环是:

                for (int i = j + 1; i < students.length; i++) {
                    if (students[i].compareTo(students[j]) < 0) {
                        Student temp = students[j];
                        students[j] = students[i];
                        students[i] = temp;
    
                    }
    
                }
    

    【讨论】:

      【解决方案3】:

      如上所述,“正确”的解决方案可能是创建一个Student 对象并让它包含学生的姓名和年级。然而,如果你真的需要两个独立的数组,你可以在等级数组上执行与名称数组相同的交换:

      if (studentNames[i].compareTo(studentNames[j]) < 0) {
          String temp = studentNames[j];
          studentNames[j] = studentNames[i];
          studentNames[i] = temp;
      
          int tempGrade = studentGrade[i];
          studentGrade[j] = studentGrade[i];
          studentGrade[i] = tempGrade;
      }
      

      【讨论】:

        【解决方案4】:

        你要做的,是根据我认为的学生数组对成绩数组进行排序,所以在你的for循环中,每次切换学生时,你都想切换成绩

        for (int j = 0; j < studentNames.length - 1; j++) {
        
            for (int i = j + 1; i < studentNames.length; i++) {
                if (studentNames[i].compareTo(studentNames[j]) < 0) {
                    String temp = studentNames[j];
                    studentNames[j] = studentNames[i];
                    studentNames[i] = temp;
                    // Here i want to place another array that sorts the grade?? how do i do that?
                    int tempGrade = studentGrades[j];
                    studentGrades[j] = studentGrades[i]
                    studentGrades[i] = temp
                    }
        
              }
        
              System.out.println(Arrays.toString(studentNames));
              System.out.println(Arrays.toString(studentGrade));
        
        }
        

        这个设计不是很好,也许考虑到@Veselin Davidov 的建议

        【讨论】:

          【解决方案5】:

          您的问题是,当您对一个数组(例如您的学生名单)进行排序时,您的第二个数组无法跟上相同的方式....苹果和橙子。

          你有一些解决方案。现在想到的是使用地图将每个名称与其等级联系起来。您也可以使用 POO 并声明一个 Studen 对象,这实际上看起来是一个更好的解决方案,我会让您阅读 Veselin 的答案。

          让我们看一下快速修复,因为我认为这就是您要寻找的原因:

          个人而言,解决您有点损坏的代码的一种解决方法是将您的交换功能更改为:

          if (studentNames[i].compareTo(studentNames[j]) < 0) {
              String tmp = studentNames[j];
              studentNames[j] = studentNames[i];
              studentNames[i] = tmp;
          
              int tmpGrade = studentGrade[i];
              studentGrade[j] = studentGrade[i];
              studentGrade[i] = tmpGrade;
          }
          

          但是,我强烈建议使用类或地图。

          【讨论】:

            【解决方案6】:

            你真的应该有一个代表学生的抽象,例如

            public class Student {
               Integer grade;
               String name;
            
               // getters and setters omitted
            
               }
            

            然后,您将面临使用不同类型(整数和字符串)多次扩展 Comparator 接口的问题。此时,请阅读:

            Using Comparable for multiple dynamic fields of VO in java

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多