programming_QA
programming_QA

Reputation: 11

Print file contents in decreasing order java

I need to write a Java program where I can read data from a file which has students names and grades. I must find the max grade for each student and then write his name and max grade in a new file. I have been able to do this. The thing is, students should be printed in decreasing order based on their max grade and I can't find out how to do that. Can you help me please? Thank you!

public class NotaMax {
    public static void main(String args[]) throws FileNotFoundException{
        Scanner input=new Scanner(new File("teksti.txt"));
        PrintStream output=new PrintStream(new File("max.txt"));
        while(input.hasNextLine()) {
            String rreshti=input.nextLine();
            max(rreshti,output);
        }
    }

    public static void max(String text,PrintStream output) {
        Scanner data=new Scanner(text);
        String emri=data.next();
        double max=0;
        while(data.hasNext()) {
            double nota=data.nextDouble();
            if(nota>max) {
                max=nota;
            }
        }
        output.println(""+emri+":"+max);
    }
}

Upvotes: -1

Views: 289

Answers (3)

Esterlinkof
Esterlinkof

Reputation: 1524

This should solve your problem. First of all read students and grades in teksti.txt in an Map and then find max grade for each student.

public class NotaMax {
    private static Map<String, ArrayList<Integer>> students = new HashMap<>();

    private static void readTeksti() throws FileNotFoundException {
        Scanner input = new Scanner(new File("teksti.txt"));

        // read teksti.txt
        String[] line;
        while (input.hasNextLine()) {
            String rreshti = input.nextLine();
            line = rreshti.split(" ");
            ArrayList<Integer> grades = students.get(line[0]);

            if (grades == null) {
                grades = new ArrayList<>();
                grades.add(Integer.parseInt(line[1]));
                students.put(line[0], grades);
            } else {
                grades.add(Integer.parseInt(line[1]));
            }
        }
    }

    public static void main(String args[]) throws FileNotFoundException {

        readTeksti();

        max();

    }

    private static void max() throws FileNotFoundException {

        PrintStream output = new PrintStream(new File("max.txt"));
        List<Map.Entry<String,Integer>> maximums = new LinkedList<>();

        for (String current : students.keySet()) {
            ArrayList<Integer> grades = students.get(current);
            Integer max = Collections.max(grades);

            maximums.add(new AbstractMap.SimpleEntry<>(current, max));
        }

        Collections.reverse(maximums);

        for (Map.Entry<String,Integer> current : maximums) {
            output.println("" + current.getKey() + ":" + current.getValue());
        }
    }
}

I assumed that teksti.txt is like :

saman 100
samad 80
samsam 70
samsam 90
saman 90

Upvotes: 0

Hades
Hades

Reputation: 119

First thing that comes to my mind is creating a separate class for your students and implementing a simple binary heap as a maximum heap with max grade of each student as a sorting criteria. Then just printing it. Shouldn't be to hard.

Upvotes: 1

user9896706
user9896706

Reputation:

There are two approaches for this, one filling up the other.

You can save them in an ArrayList and then call the method Array#reverse so it will reverse the ArrayList. To add another layer of certainty, it's better to make an Object/Class named Student and apply a Comparator to the #sort method of the ArrayList in order to assure the outcome. This however takes a lot more steps than the easiest and most efficient way of tackling this problem.

What the best you could do is save the Student Object inside an ArrayList (or HashSet, really any Comparable Collection/Map) and use the #sort method to sort it from the down to the top. I could (if requested), provide some code for this.

Upvotes: 1

Related Questions