iali87
iali87

Reputation: 147

Java Max and Min values- two approaches

I have this assignment that I already did. but My professor didn't like my approach.

write a Java program that reads in any number of lines from an input file. The input file consist of one column for the names of the players and next to it a column for the scores for each player. Find the count of the number of values read the total sum the average score (to 2 decimal places) the maximum value along with the corresponding name. the minimum value along with the corresponding name.

hint: Handle each data item as it is read in and move on. Don't save all of the data in your program.

===========

I did the program using 2 arraylist to store the data and then sort the arraylist in an ascending order and then pick the first and the last data in the sorted arraylist. The professor didn't like the way I handeled the program because he he doesn't want me to consume so much of a ram and ask me to use the hint mentioned above.

I am not sure in what approach should I reach the problem. any suggestion would be appreciated. here is part of the input file
9290 alebam0
9390 davige0
9490 hassa0
9590 luxtt0
9690 raflra0
9790 smithbl0
9890 hallasm0
9990 afflrj0
90 amosre0
190 cottat0
290 luzijc0
3553 philel01
4553 poulcp02 ... (thousands of lines)

And there is my code

import java.util.*;
import java.io.*;
import java.text.DecimalFormat;

public class GCGC
{
    public static void main(String[] args) throws IOException
    {

   ArrayList<String> names = new ArrayList<String>(); 
   ArrayList<Integer> scores = new ArrayList<Integer>();
   int nRead = 0;                         // hold the number of lines
   int ListSize;                          // hold the size of arraylist            

   final String INPUT_FILE  = "/Users/Ali/Desktop/HW1_InputFile.txt";
    final String OUTPUT_FILE = "/Users/Ali/Desktop/HW1_Output.txt";

   FileWriter fw = new FileWriter(OUTPUT_FILE,false);
   PrintWriter pw = new PrintWriter(fw);
   File f = new File(INPUT_FILE);
    Scanner input = new Scanner(f);

   // read all data from input line by line
   while (input.hasNext() ) {
   scores.add(input.nextInt());            
   names.add(input.nextLine().trim());   
   nRead++;   
   }

   ListSize = scores.size(); // size of the arraylist would be used throw the program

   int scoresArray[] = new int [ListSize];
   String namesArray [] = new String [ListSize];

   // This for loop will convert the arraylist into an array
   for (int i =0; i<ListSize;i++)
   {
   scoresArray[i]=scores.get(i);
   namesArray[i]=names.get(i);
   }

   int theSum = sum (scoresArray);
   double theAvg = average(scoresArray);
   outputData(theSum, theAvg, nRead, pw);
   max_and_min(scoresArray, namesArray, pw);

   input.close();
   pw.close();
   System.exit(0);

   } // end of main

// #############################################################################
// ####################          METHODS         ###############################
// #############################################################################

// This method will find and return the average to the main method
   public static int sum (int [] scoresArray)
   {

   int sum=0;
   for (int i =0; i < scoresArray.length; i++){
   sum+=scoresArray[i];}
   return sum;
   }

// #############################################################################
// This method will find and return the average to the main method
   public static double average (int [] scoresArray)
   {

   int sum=0;
   double avg;
   for (int i =0; i < scoresArray.length; i++)
     {
      sum+=scoresArray[i];
     }
   avg = (double)sum/scoresArray.length ;

   return avg;
   }

// #############################################################################
// This method will sort the scores array in an assending order, thus the
// first element of the array will represnet the minimum  and the last element of
// the array will represent the maximum.
   public static void max_and_min(int [] score, String [] name, PrintWriter pw)
   {

   int tempNum; String tempName;
   boolean fixed = false; // fixed is true once the array is sorted

   while (fixed ==false)
   {  fixed = true;       // ture to exit the while loop once the array is fixed
      for (int i =0 ; i<score.length-1 ; i++) 
      {
      if (score[i] > score[i+1]) 
         {
         tempNum = score [i+1]; score [i+1] = score[i]; score[i] = tempNum; 
         tempName = name [i+1]; name [i+1] = name[i]; name[i] = tempName;

         fixed = false;   // Once we are inside the if statment, that 
                          //means the array is still not fixed
         }    
      }
   }

   pw.println("The maximum score is: "+score[score.length-1]+" belongs to: "
   +name[score.length-1]+"\n\n");

   pw.println("The Minimum score is: " + score[0] + " belongs to: "+name[0] +"\n\n");

   }

// #############################################################################
// This method is for outputting the report to a text file
  public static void outputData(int theSum, double theAvg, int nRead, PrintWriter pw)
   {

   // DecimalFormat is to format the average
   DecimalFormat f = new DecimalFormat("#0.##");

   pw.println("\t\t    GCGC Statistical Report");
   pw.println("###################################################################");
   pw.println("\n\n");
   pw.println("The number of read values is: " + nRead + "\n\n");
   pw.println("The total Sum is: " + theSum + "\n\n");
   pw.println("The average Score  is: " + f.format(theAvg) + "\n\n");

   }
}

Upvotes: 1

Views: 1252

Answers (4)

Mustafa sabir
Mustafa sabir

Reputation: 4360

QUESTION VARIABLES

Find the count of the number of values read int count

the total sum int sum

the average score double avgScore

the maximum value along with the corresponding name int max, String maxName

the minimum value along with the corresponding name int min, String minName

Intermediate variables int currentScore,String currentName

Now parse you input file, and in each iteration (for each line), do the following:-

1) count++

2) Assign current score to currentScore, current player name to currentName

3) sum+=currentScore

4) Check and compare for values in max and min with currentScore and update them as necessary, also update maxName and minName with currentName if max or min are updated.

5) Finally after the iteration is over, avgScore=(double)sum/count;

In this way you will have all values, without storing all unnecessary data into your program. Please point me if I missed something.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347214

Basically what your professor is asking, is for you to read each line individually and process it, incrementing the row count, adding the score to the running total and assessing if the score is higher or lower than any other scores you've read so far...

For example...

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.NumberFormat;

public class ReadScores {

    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader(new File("Scores.txt")))) {

            int count = 0;
            int tally = 0;
            int highest = 0;
            int lowest = Integer.MAX_VALUE;

            String highestPlayerName = null;
            String lowestPlayerName = null;

            String text = null;
            while ((text = br.readLine()) != null) {
                count++;
                String[] parts = text.split(" ");
                int score = Integer.parseInt(parts[0]);
                tally += score;
                if (score > highest) {
                    highest = score;
                    highestPlayerName = parts[1];
                } else if (score < lowest) {
                    lowest = score;
                    lowestPlayerName = parts[1];
                }
            }

            System.out.println("Number of entries = " + count);
            System.out.println("Sum of scores = " + tally);
            System.out.println("Average score = " + NumberFormat.getNumberInstance().format(tally / (double)count));
            System.out.println("Highest score of " + highest + " by " + highestPlayerName);
            System.out.println("Lowest score of " + lowest + " by " + lowestPlayerName);

        } catch (IOException exp) {
            exp.printStackTrace();
        }
    }

}

Which based on this data...

9290 alebam0
9390 davige0
9490 hassa0
9590 luxtt0
9690 raflra0
9790 smithbl0
9890 hallasm0
9990 afflrj0
90 amosre0
190 cottat0
290 luzijc0
3553 philel01

Outputs...

Number of entries = 12
Sum of scores = 81243
Average score = 6,770.25
Highest score of 9990 by afflrj0
Lowest score of 90 by amosre0

In this way you are only holding the current line of information in memory, along with the data you need in order to provide the summary

Upvotes: 2

ne1410s
ne1410s

Reputation: 7082

Sounds like he didn't want you to bung everything in memory in an array. For min/max you could check at each line of the value was lower/higher than a current value and if so, update new min/max accordingly. Likewise track the sum and the count and deduce the statistical mean from these.

It seems like the whole point is not use arrays, at least that's how I interpreted it

Upvotes: 3

ChusZ
ChusZ

Reputation: 41

As your teacher said, you should not use arraylists, just simple variables for each of the values to find. Update the variables as needed until you get the final result.

Hints: you will need a counter for the number of total read lines, a variable to store the total sum, use those two previous to get the average score, a variable to keep the maximum value and another to keep the corresponding name, and another couple to keep the minimum value and the corresponding name.

Upvotes: 0

Related Questions