【问题标题】:Comparing lines for a similar String in a text file比较文本文件中类似字符串的行
【发布时间】:2018-07-01 21:14:33
【问题描述】:

我有一个看起来像这样的文本文件:

6
3.3 John Rodgers
3.9 Jim Braash
3.5 Kathy Calderon
3.2 Steve Hernandez
2.4 Stacy Lu
2.8 Faith Simmons

我已经写了一个Student类,它有基本的功能:

package com.company;

public class Student {

    private String firstName;
    private String lastName;
    private double grades;

    public Student(String firstName, String lastName, double grades) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.grades = grades;
    }

    @Override
    public String toString() {
        return lastName + ", " + firstName + ", " + grades;
    }

    @Override
    public boolean equals(Object obj) {

        if(obj == null){
            return false;
        }

        Student other = (Student) obj;

        if (other.firstName.equals(this.firstName) && other.lastName.equals(this.lastName) && other.grades == this.grades) {
            return true;
        } else {
            return false;
        }
    }

    public String getFirstName() {

        return this.firstName;
    }

    public String getLastName() {

        return this.lastName;
    }

    public double getGrade() {

        return this.grades;
    }

    public void setFirstName(String firstName) {

        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setGrades(double grades) {
        this.grades = grades;
    }

}

这是我的Main 课程:

package com.company;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Scanner;


public class Main {

    public static void main(String[] args) throws FileNotFoundException {
        Student[] s = initialize();
        Student max = maxIndex(s);
        Student min = minIndex(s);
        double avg = avg(s);
        flush(max, min, avg);

    }

    public static void flush(Student max, Student min, double avg) throws FileNotFoundException {
        DecimalFormat df = new DecimalFormat("#.#");
        double avgFormatted = Double.parseDouble(df.format(avg));
        PrintWriter writer = new PrintWriter("final.txt");
        writer.write("Highest: " + max);
        writer.write("\n");
        writer.write("Lowest: " + min);
        writer.write("\n");
        writer.write("Average GPA: " + avgFormatted);
        writer.close();
    }

    public static Student[] initialize() throws FileNotFoundException {
        Scanner reader = new Scanner(new File("data.txt"));
        int size = reader.nextInt();
        Student[] students = new Student[size];
        int index = 0;

        while (reader.hasNextLine()) {
            double grades = reader.nextDouble();
            String firstName = reader.next();
            String lastName = reader.next();
            Student student = new Student(firstName, lastName, grades);
            students[index] = student;
            index++;
        }
        return students;
    }

    public static double avg(Student[] students) {
        double avg = 0;
        double sum = 0;
        for (int i = 0; i < students.length; i++) {
            sum += students[i].getGrade();
            avg = sum / students.length;
        }
        return avg;
    }

    public static Student maxIndex(Student[] students) {
        int max = 0;
        for (int i = 1; i < students.length; i++) {
            if (students[i].getGrade() > students[max].getGrade()) {
                max = i;
            }
        }

        return students[max];
    }

    public static Student minIndex(Student[] students) {
        int min = 0;
        for (int i = 1; i < students.length; i++) {
            if (students[i].getGrade() < students[min].getGrade()) {
                min = i;
            }
        }
        return students[min];
    }
}

所以,我的问题涉及处理文件。假设我再次将名称 Jim Braash 添加到我的文件中,而没有更改顶部的整数。所以我的文件看起来像这样:

6
3.3 John Rodgers
3.9 Jim Braash
3.9 Jim Braash
3.5 Kathy Calderon
3.2 Steve Hernandez
2.4 Stacy Lu
2.8 Faith Simmons

虽然有 7 行,但由于重复了一个,所以仍然只有 6 个学生。我已经在我的Student 类中实现了equals() 方法,但是我无法弄清楚如何在main() 方法中跳过该行并且仍然得到与以前相同的结果。谢谢。

【问题讨论】:

  • 我唯一能想到的是你应该对你的文件进行预处理,在你进行实际处理之前删除所有重复的行。添加一个您首先调用的方法以删除所有重复的行。请参阅此示例:stackoverflow.com/questions/996041/…
  • 您可能应该在使用完 Scanner 后关闭它 - reader.close()

标签: java


【解决方案1】:

使用HashSet&lt;Student&gt; 代替Student[] 并覆盖hascode 以符合您的equals。您将不再有任何重复。

请注意,equalshashcode 的错误实现可能会导致严重问题。不应修改此方法中使用的属性。这可能会导致重复和/或您可能无法访问或删除 HashSet 中的已修改元素。

【讨论】:

    【解决方案2】:

    其他答案有很好的想法。但是,如果您只想使用 Student 类中的 equals() 方法以简单的方式执行此操作,则可以为您的 initialize() 方法尝试以下操作:

    public static Student[] initialize() throws FileNotFoundException {
        Scanner reader = new Scanner(new File("data.txt"));
        int size = reader.nextInt();
        Student[] students = new Student[size];
        int index = 0;
    
        while (reader.hasNextLine()) {
            double grades = reader.nextDouble();
            String firstName = reader.next();
            String lastName = reader.next();
    
            Student student = new Student(firstName, lastName, grades);
    
            boolean duplicate = false;
            for (int i = 0; i < students.length; i++) {
                if (student.equals(students[i])) {
                    duplicate = true;
                    break;
                }
            }
    
            if (!duplicate) {
                students[index] = student;
                index++;
            }
        }
    
        reader.close(); // <--- Make sure to close the Scanner
        return students;
    }
    

    让我知道这是否适合你。

    【讨论】:

    • 非常感谢您。我永远也想不通这个逻辑。我意识到这是一个 O(n^2) 并且我想知道是否有办法获得更快的运行时间。但是,仅此一项就回答了我的问题!
    • 顺便说一句,我取出了 prevStudents 数组,只使用了students数组,效果也很好
    • @moo cow 太棒了,很高兴能帮到你。是的,将studentstudents 的数组进行比较是一个很好的简化。我会将这种简化添加到我的帖子中。
    【解决方案3】:

    尝试使用学生的Set,而不是学生数组

    不包含重复元素的集合。更正式地说,集合不包含满足 e1.equals(e2) 的元素 e1 和 e2 对,并且最多包含一个空元素。

    这种数据类型只有唯一的项目。

    编辑 1 带数组

         while (reader.hasNextLine()) {
            Double grades = Double.valueOf(reader.next());
            String firstName = reader.next();
            String lastName = reader.next();
            Student student = new Student(firstName, lastName, grades);
            if (Arrays.stream(students).noneMatch(s -> student.equals(s))) {
                System.out.println(student);
                students[index] = student;
                index++;
            }
        }
    

    编辑 2

    您可以用流替换 max、min、avg 计算

     public static void main(String[] args) throws FileNotFoundException {
        Student[] s = initialize();
        Student max = Arrays.stream(s).max(Comparator.comparing(student -> student.getGrade())).orElse(null);
        Student min = Arrays.stream(s).min(Comparator.comparing(student -> student.getGrade())).orElse(null);
        double avg = Arrays.stream(s).map(student -> student.getGrade()).reduce(0d, (x,y) -> x + y).doubleValue() / s.length;
        flush(max, min, avg);
    }
    

    【讨论】:

    • 这不可能只用数组吗?
    • 你也可以用数组来做,但是你必须检查新元素是否已经存在于数组中。如果存在,则跳过它并处理下一个元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多