Java 2D数组,使用HashMap的最佳平均计算器

Java 2D数组,使用HashMap的最佳平均计算器,java,algorithm,collections,space-complexity,Java,Algorithm,Collections,Space Complexity,问题陈述:我有一个包含学生姓名和相应标记的2D字符串数组,如下所示 String[][] scores = {{"Bob","85"},{"Mark","100"},{"Charles","63"},{"Mark","34"}}; 我想计算所有可用学生的最佳平均值,即根据上述输入,最佳平均值应为85 我的尝试: 我尝试使用HashMap解决这个问题,如下所示 public int bestAverageCalculator(String[][] scores) { // This

问题陈述:我有一个包含学生姓名和相应标记的2D字符串数组,如下所示

String[][] scores = {{"Bob","85"},{"Mark","100"},{"Charles","63"},{"Mark","34"}};
我想计算所有可用学生的最佳平均值,即根据上述输入,最佳平均值应为85

我的尝试: 我尝试使用HashMap解决这个问题,如下所示

public int  bestAverageCalculator(String[][] scores) {

    // This HashMap maps student name to their list of scores
    Map<String,List<Integer>> scoreMap = new HashMap<String,List<Integer>>();
    for(String[] score:scores) {
        String name = score[0];
        int currentScore =Integer.parseInt(score[1]);

        if(scoreMap.containsKey(name)) {
            List<Integer> scoreList = scoreMap.get(name);
            scoreList.add(currentScore);
            scoreMap.put(name, scoreList);
        }
        else {
            List<Integer> scoreList = new ArrayList<Integer>();
            scoreList.add(currentScore);
            scoreMap.put(name, scoreList);
        }
    }
    //scoreMap will be {Charles=[63], Bob=[85], Mark=[100, 34]}
    //After Map is formed i am iterating though all the values and finding the best average as below
    int bestAverage = 0;
    for(List<Integer> value:scoreMap.values()) {
        int sum = 0;
        int count = 0;
        for(int i:value) {
            sum+=i;
            count++;
        }
        int average = (int)Math.floor(sum/count);
        if(average>bestAverage)
            bestAverage = average;
    }

    return bestAverage;// returns 85

}
实现是正确的,我得到了预期的答案,但我被告知该程序的空间复杂度更高,不使用分数列表就可以实现,我无法理解如何在不存储分数列表的情况下动态计算平均值

请建议除HashMap之外是否还有其他方法可以解决此问题


任何帮助都将不胜感激。

您可以为每个学生存储恒定数量的数据:

学生的名字 所有学生成绩的总和 学生的分数 这将使空间复杂度Om,其中m是唯一学生的数量,而不是n是分数的数量

例如,您可以使用具有这3个属性的Student类并将数据存储在列表中,也可以使用键为学生姓名、值为包含标记和标记数的两个元素的数组的映射

可以在迭代输入时构造此数据


现在,您可以计算每个学生的平均值并找到最高平均值。

您可以为每个学生存储恒定数量的数据:

学生的名字 所有学生成绩的总和 学生的分数 这将使空间复杂度Om,其中m是唯一学生的数量,而不是n是分数的数量

例如,您可以使用具有这3个属性的Student类并将数据存储在列表中,也可以使用键为学生姓名、值为包含标记和标记数的两个元素的数组的映射

可以在迭代输入时构造此数据


现在,您可以计算每个学生的平均数并找到最高的平均数。

为了节省空间,您可以每人存储两个数字
avgSum,最后计算平均值。

为了节省空间,您可以每人存储两个数字
avgSum和count并计算最后的平均值。

我已经基于您的代码实现了@Eran的方法,并使用

关键词:学生姓名

值:两个元素的数组[分数之和,分数的数量]


我已经基于您的代码实现了@Eran的方法,并使用

关键词:学生姓名

值:两个元素的数组[分数之和,分数的数量]

@埃兰的想法,但在学生课堂上,至少对我来说,这更清楚

import java.util.*;

public class Main {
    static String[][] scores = {{"Bob", "85"}, {"Mark", "100"}, {"Charles", "63"}, {"Mark", "34"}};

    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        for (String[] score : scores) {
            String name = score[0];
            int currentScore = Integer.parseInt(score[1]);

            Student student = findStudentByName(name, students);
            if (student != null) {
                student.setNumberOfScores(student.getNumberOfScores() + 1);
                student.setSumOfScores(student.getSumOfScores() + currentScore);
            } else {
                student = new Student(name, 1, currentScore);
                students.add(student);
            }
        }
        findStudentWithBestAverage(students);
    }

    private static void findStudentWithBestAverage(List<Student> students) {
        Student bestStudent = null;
        int bestAverage = 0;
        for (int i = 0; i < students.size(); i++) {
            if ((students.get(i).getSumOfScores() / students.get(i).getNumberOfScores()) > bestAverage) {
                bestStudent = students.get(i);
                bestAverage = (students.get(i).getSumOfScores() / students.get(i).getNumberOfScores());
            }
        }
        System.out.println(bestStudent + " with average: " + bestAverage);
    }

    private static Student findStudentByName(String name, List<Student> students) {
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getName().equals(name)) {
                return students.get(i);
            }
        }
        return null;
    }

    public static class Student {
        private String name;
        private int numberOfScores;
        private int sumOfScores;

        public Student(String name, int numberOfScores, int sumOfScores) {
            this.name = name;
            this.numberOfScores = numberOfScores;
            this.sumOfScores = sumOfScores;
        }

        public String getName() {
            return name;
        }

        public int getNumberOfScores() {
            return numberOfScores;
        }

        public void setNumberOfScores(int numberOfScores) {
            this.numberOfScores = numberOfScores;
        }

        public int getSumOfScores() {
            return sumOfScores;
        }

        public void setSumOfScores(int sumOfScores) {
            this.sumOfScores = sumOfScores;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return name.equals(student.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name);
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", numberOfScores=" + numberOfScores +
                    ", sumOfScores=" + sumOfScores +
                    '}';
        }
    }
}
@埃兰的想法,但在学生课堂上,至少对我来说,这更清楚

import java.util.*;

public class Main {
    static String[][] scores = {{"Bob", "85"}, {"Mark", "100"}, {"Charles", "63"}, {"Mark", "34"}};

    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        for (String[] score : scores) {
            String name = score[0];
            int currentScore = Integer.parseInt(score[1]);

            Student student = findStudentByName(name, students);
            if (student != null) {
                student.setNumberOfScores(student.getNumberOfScores() + 1);
                student.setSumOfScores(student.getSumOfScores() + currentScore);
            } else {
                student = new Student(name, 1, currentScore);
                students.add(student);
            }
        }
        findStudentWithBestAverage(students);
    }

    private static void findStudentWithBestAverage(List<Student> students) {
        Student bestStudent = null;
        int bestAverage = 0;
        for (int i = 0; i < students.size(); i++) {
            if ((students.get(i).getSumOfScores() / students.get(i).getNumberOfScores()) > bestAverage) {
                bestStudent = students.get(i);
                bestAverage = (students.get(i).getSumOfScores() / students.get(i).getNumberOfScores());
            }
        }
        System.out.println(bestStudent + " with average: " + bestAverage);
    }

    private static Student findStudentByName(String name, List<Student> students) {
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getName().equals(name)) {
                return students.get(i);
            }
        }
        return null;
    }

    public static class Student {
        private String name;
        private int numberOfScores;
        private int sumOfScores;

        public Student(String name, int numberOfScores, int sumOfScores) {
            this.name = name;
            this.numberOfScores = numberOfScores;
            this.sumOfScores = sumOfScores;
        }

        public String getName() {
            return name;
        }

        public int getNumberOfScores() {
            return numberOfScores;
        }

        public void setNumberOfScores(int numberOfScores) {
            this.numberOfScores = numberOfScores;
        }

        public int getSumOfScores() {
            return sumOfScores;
        }

        public void setSumOfScores(int sumOfScores) {
            this.sumOfScores = sumOfScores;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return name.equals(student.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name);
        }

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", numberOfScores=" + numberOfScores +
                    ", sumOfScores=" + sumOfScores +
                    '}';
        }
    }
}

你的意思是说,在空间复杂度方面,数组比ArrayList更好?@raviraja no,使用ArrayList代替数组仍然具有相同的渐近空间复杂度。重点是数组或ArrayList将有一个恒定的2个元素数。好的,明白了,我不需要存储所有的标记,而是将总和和计数值存储在一个2空间的数组中。非常感谢,接受了答案。你的意思是说数组在空间复杂度方面比ArrayList更好?@raviraja不,使用ArrayList代替数组仍然具有相同的渐近空间复杂度。重点是数组或ArrayList将有一个恒定的2个元素数。好的,明白了,我不需要存储所有的标记,而是将总和和计数值存储在一个2空间的数组中。非常感谢你接受了答案。