Print file contents in decreasing order java - 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);
}
}

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.

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.

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

Related

Finding specific instance of class? [duplicate]

This question already has answers here:
How to find an object in an ArrayList by property
(8 answers)
Closed 5 years ago.
I've just started learning java and I'm trying to create an application to register students.
Based on this question how-would-i-create-a-new-object... I created a while loop to create an instance of a class.
public class RegStudent {
ArrayList<Student> studentList = new ArrayList<>();
Scanner input = new Scanner(System.in);
public void reggaStudent(int start) {
while (start != 0) {
String programNamn, studNamn;
int totalPoint, antalKurser;
System.out.println("Vad heter programmet?");
programNamn = input.nextLine();
System.out.println("Vad heter studenten");
studNamn = input.nextLine();
System.out.println("Hur många poäng har studenten?");
totalPoint = input.nextInt();
System.out.println("Hur många kurser är studenten registrerad på?");
antalKurser = input.nextInt();
// Add student to list of students
studentList.add(new Student(totalPoint, antalKurser,
programNamn, studNamn));
System.out.println("Vill du registrera in en fler studenter? "
+ "Skriv 1 för ja och 0 för nej");
start = input.nextInt();
input.nextLine();
} // End of whileloop
}
}
The class is:
public class Student {
private int totalPoint;
private int antalKurser;
private String programNamn;
private String studNamn;
private static int counter;
public Student(int totalPoint, int antalKurser, String program, String studNamn) {
this.totalPoint = totalPoint;
this.antalKurser = antalKurser;
this.programNamn = program;
this.studNamn = studNamn;
counter++;
}
public int getTotalPoint() {
return totalPoint;
}
public void setTotalPoint(int totalPoint) {
this.totalPoint = totalPoint;
}
public int getAntalKurser() {
return antalKurser;
}
public void setAntalKurser(int antalKurser) {
this.antalKurser = antalKurser;
}
public String getProgramNamn() {
return programNamn;
}
public void setProgramNamn(String programNamn) {
this.programNamn = programNamn;
}
public String getStudNamn() {
return studNamn;
}
public void setStudNamn(String studNamn) {
this.studNamn = studNamn;
}
public static int getCount(){
return counter;
}
#Override
public String toString() {
return String.format(" Namn: %s, Program: %s, Antal poäng: %d, "
+ "Antal kurser: %d\n ", studNamn, programNamn, totalPoint, antalKurser);
}
}
How do I go about to get and set the instance variables in specific instance? I.e find the instances.
I understand it might be bad design but in that case I would appreciate some input on how to solve a case where i wanna instantiate an unknown number of students.
I've added a counter just to see I actually created some instances of the class.
You simply query objects for certain properties, like:
for (Student student : studentList) {
if (student.getProgramName().equals("whatever")) {
some match, now you know that this is the student you are looking for
In other words: when you have objects within some collection, and you want to acquire one/more objects with certain properties ... then you iterate the collection and test each entry against your search criteria.
Alternatively, you could "externalize" a property, and start putting objects into maps for example.
studentList.add(new Student(totalPoint, antalKurser,
programNamn, studNamn));
You now have your Student objects in a list. I assume you have something like
List<Student> studentList = new ArrayList<>();
somewhere in your code. After you populate the list with Student objects, you can use it to find instances. You need to decide what criteria to use for a search. Do you want to find a student with a specific name? Do you want to find all students in a given program? Do you want to find students with more than a certain number of points?
Maybe you want to do each of these. Start by picking one and then get a piece of paper to write out some ideas of how you would do the search. For example, say you want to find a student with the name "Bill". Imagine that you were given a stack of cards with information about students. This stack of cards represents the list in your program. How would you search this stack of cards for the card with Bill's name on it? Describe the steps you need to take in words. Don't worry about how you will code this yet. The first step in writing a computer program is breaking the solution down into small steps. After you have a clear idea how you might do this by hand in the physical world, you can translate your description into Java code.

how to take many multiple inputs in java and then perform a same operation on all those inputs

import java.util.Scanner;
class sexy
{
void even(String s)
{
for( int i=0;i<s.length();i++)
{
if((i==0) ||(i%2==0))
{
System.out.print(s.charAt(i));
}
}
}
void odd(String s)
{
for( int i=0;i<s.length() ; i++)
{
if(i%2!=0)
{
System.out.print(s.charAt(i));
}
}
}
}
class sassy
{
public static void main(String args[])
{
sexy se = new sexy();
Scanner scan = new Scanner(System.in);
int i=0,p;
p=scan.nextInt();
scan.nextLine();
String s;
while(i<p)
{
s = scan.nextLine();
se.even(s);
System.out.print(" ");
se.odd(s);
i++;
}
scan.close();
}
}
Now here i am able to take multiple inputs..and after every input i have to perform the operation on that particular input.. But I want to take multiple inputs at first and then perform the same operation on all the inputs using minimum variables..(if possible just one)
Well, it looks like you would either need a string array or a string arraylist.
You would use a string array if you knew how many inputs you would get, and an arraylist if you don't know how many inputs would be put in.
The code would look something like this:
ArrayList<String> lines = new ArrayList<>();
To put the values in, you would use lines.put(), and then lines.get(i) in your for loop to get values back out.
So to use it in your program, just add all the lines that the user inputs into the arraylist, and then traverse the arraylist to do the even and odd functions.
Good luck!

Why is the null error showing in my program; Stringtokenizer to array

This essentially is a small code I'm writting for practice that requires me to use StringTokenizer. I've done the same kind of programs before , but now when I store the strings in an array and try to print them it show's a null pointer exception. Any help?
import java.util.*;
public class board1
{
String key;
String m[];
//function to accept the sentence
void getsent()
{
Scanner in=new Scanner(System.in);
System.out.println("Enter a sentence terminated by'.' or '?'");
String take=in.nextLine();
StringTokenizer taken=new StringTokenizer(take);
int numtokens=taken.countTokens();
String m[]=new String[numtokens];
for(int i=0;i<m.length;i++)
{
m[i]=taken.nextToken();
}
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]);
}
}
// function to display
void display()
{
System.out.println("The words seperately right now are:");
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]+"\t");
System.out.println();
}
}
// main to get functions
public static void main(String args[])
{
board1 ob= new board1();
ob.getsent();
ob.display();
}
}
You're shadowing the variable m. Replace
String m[] = new String[numtokens];
with
m = new String[numTokens];
I think because you are shading properties. You have an array called m into which you are putting tokens in getSent, but display is using the m array defined in the class to which you haven't added anything.
Print out the size of m in display, this will show you that you are not adding anything to the property called m.

How to call a method which reads data from a file?

The question is
Write a method readStock(String[] sAr, double[] pAr, int[] qAr) to read the following details from a file named “stock.txt”.
So I created the stock file which contain
pillow 14.50 30
Sheet 43 40
Quilt 52.50 40
Set 100 200
and I do this method
public static void readStock(String[] sAr, double[] pAr, int[] qAr) throws FileNotFoundException
{
Scanner input = new Scanner(new FileReader("stock.txt")) ;
int i = 0;
while (input.hasNext())
{
sAr[i]= input.next();
pAr[i] = input.nextDouble();
qAr[i] =input.nextInt();
i++;
}
input.close();
System.out.print("ITEM"+" "+"Price"+" "+"Quantity");
for (i=0;i<qAr.length;i++)
{
System.out.println(sAr[i]+" "+pAr[i]+" "+qAr[i]+"");
}
}
but I don't know the way to call it ?
I did
public static void main(String[] args)
{
readStock();
}
}
but there is an error.
You should pass in 3 corresponding parameters, in your case they are String[] sAr, double[] pAr, int[] qAr. Therefore you should do something like readStock(sAr, pAr, qAr);
You require 3 parameters in you method signature, 3 arrays so you need to pass them to the method. You can do it like: readStock(new String[4], new double[4], new int[4]); However with this design you need to know how many lines you file contains (because you need to create arrays with proper size). To make it work with any file length just replace arrays with Lists:
public static void readStock(List<String> names, List<Double> prices, List<Integer> quantity) throws FileNotFoundException
{
Scanner input = new Scanner(new FileReader("stock.txt")) ;
while (input.hasNext())
{
names.add(input.next());
prices.add(input.nextDouble());
quantity.add(input.nextInt());
}
input.close();
System.out.print("ITEM"+" "+"Price"+" "+"Quantity");
for (int i=0; i<names.size(); i++)
{
System.out.println(names.get(i)+" "+prices.get(i)+" "+quantity.get(i)+"");
}
}
Lists have the ability to expand their size when you are adding an element and there is not enough space for him. To create new List you can use for example new ArrayList<String>()

Implementing classes and objects in java, calling a method

I'm having trouble with calling a method. The basis of the program is to read in data from data.txt, grab the name token given, then all of the grades that follow, then implement some operations on the grades to give details of the person's grades. I do all of the methods in a separate file named Grades.java, which has the Grades class. I'm just having trouble because I MUST have the testGrades method in my code (which I don't find necessary). I have done everything I need to do for the results to be perfect in a different program without having two different .java files. But it's necessary to do it this way. I think I have mostly everything pinned down, I'm just confused on how to implement and call the testGrades method. I commented it out and have the question on where it is in the program. Quite new to classes and objects, and java in general. Sorry for the lame question.
public class Lab2 {
public static void main(String[] args) {
Scanner in = null; //initialize scanner
ArrayList<Integer> gradeList = new ArrayList<Integer>(); //initialize gradeList
//grab data from data.txt
try {
in = new Scanner(new File("data.txt"));
} catch (FileNotFoundException exception) {
System.err.println("failed to open data.txt");
System.exit(1);
}
//while loop to grab tokens from data
while (in.hasNext()) {
String studentName = in.next(); //name is the first token
while (in.hasNextInt()) { //while loop to grab all integer tokens after name
int grade = in.nextInt(); //grade is next integer token
gradeList.add(grade); //adding every grade to gradeList
}
//grab all grades in gradeList and put them in an array to work with
int[] sgrades = new int[gradeList.size()];
for (int index = 0; index < gradeList.size(); index++) {
sgrades[index] = gradeList.get(index); //grade in gradeList put into grades array
}
//testGrades(sgrades); How would I implement this method call?
}
}
public static void testGrades(Grades grades) {
System.out.println(grades.toString());
System.out.printf("\tName: %s\n", grades.getName());
System.out.printf("\tLength: %d\n", grades.length());
System.out.printf("\tAverage: %.2f\n", grades.average());
System.out.printf("\tMedian: %.1f\n", grades.median());
System.out.printf("\tMaximum: %d\n", grades.maximum());
System.out.printf("\tMininum: %d\n", grades.minimum());
}
}
This is a little snippet of the beginning of the Grades.java file
public class Grades {
private String studentName; // name of student Grades represents
private int[] grades; // array of student grades
public Grades(String name, int[] sgrades) {
studentName = name; // initialize courseName
grades = sgrades; // store grades
}
public String getName() {
return studentName;
} // end method getName
public int length() {
return grades.length;
}
well your test grades take a Grades object so you need to construct a Grades object using your data and pass it to your test grades method
i.e.
Grades myGrade = new Grades(studentName,sgrades);
testGrades(myGrade);
It looks like what you need to do is have some type of local variable in your main method, that would hold your custom Grade type. So you need add a line like..
Grades myGrades = new Grades(studentName, sgrades);
Then you can call your testGrades method with a line like...
testGrades(myGrades);
Looks like you may also need a toString method in your Grades class.
Seems like homework, so I tried to leave a bit to for you to figure out :)

Categories