0
Main Class:
public class Main {

  private static String [] Countries={"UK", "Italy",
            "Germany", "Thailand","Denmark"};
  static double average[] = new double[5];
  double[] results = new double[5];

  public static String getWinner(ArrayList<MissUniverse>alist){
    int champion = 0;
    for (int s = 0; s < alist.size(); s++){
        if (alist.get(s).average() > alist.get(0).average() ) {
            winner= s;
        }
    }
    return alist.get(winner).getCountry();
  }

public static String firstRunnerUp(ArrayList<MissUniverse>alist){
    int firstrunnerUp =0;
    for (int s = 0; s < alist.size(); s++){
        if (alist.get(s).average() > alist.get(0).average() && alist.get(s).getCountry() != getWinner(alist) ) {
            firstrunnerUp = s;
        }
    }
    return alist.get(firstrunnerUp).getCountry();

  }

 public static void main (String[] args){
   ArrayList<MissUniverse> alist = new ArrayList<MissUniverse>();
 MissUniverse missUniverse[] = new MissUniverse[Countries.length];

        for(int i=0;i<Countries.length;i++)
        {
            missUniverse[i] = new MissUniverse(Countries[i]);
            missUniverse[i].getScore();
            alist.add(missUniverse[i]);
        }


   System.out.printf("%-15s%-5s%-5s%-5s%-5s%-5s%-10s",
                "Countries","1","2","3","4","5","Average");
    System.out.println();
    for (int i = 0; i < Countries.length; i++){
    System.out.print(Countries[i]);
    System.out.print("    ");
    missUniverse[i].printInfo();
    System.out.printf("%5.1f", alist.get(i).average() );  ///this line 
    System.out.println();
    }
    System.out.println("The result is");
    System.out.println("Winner: Miss " + getWinner(alist) );
    System.out.println("1st Runner Up: Miss " + firstRunnerUp(alist) );

  }
}

MissUniverse class:

class MissUniverse { 
  public static int SIZE=5;
  private String country;
  private double[] score;  

  public MissUniverse(String country){
    this.country = country;
    score = new double [SIZE];
  }

  public String getCountry(){
    return country;
  }

  public void getScore(){
      for (int i=0;i<score.length;i++)
        {
            score[i] = Math.random()*10;
        }
  }

  public void setCountry(String newCountry) {
    this.country = newCountry;
  }

 private int highest(){
  int i;
        double highest;
        highest = score[0];

        for (i = 0; i <score.length; i++)
        {
            if (highest < score [i])
            {
                highest = score[i] ;
            }
        }
        return i;
  }

  private int lowest(){      
  int i;
        double lowest;
        lowest = score[0];
        for (i = 0; i <score.length; i++)
        {
            if (lowest > score [i])
            {
                lowest = score[i];
            }
        }
        return i;  
  }

  public double average(){

    double sum = 0.0;
     for (int i = 0; i < score.length; i++){
        sum +=  score[i];
     }
    double average;
    average = (sum - score[lowest()] - score[highest()] )/ score.length -2;
  }

  public void printInfo(){

      for(int i=0;i< score.length;i++){  
      System.out.printf("%-5.1f",score[i]);
      }

  }
}

The error:

Countries      1    2    3    4    5    Average   
UK    3.3  5.8  6.6  4.8  0.2  Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
    at MissUniverse.average(Main.java:121)
    at Main.main(Main.java:50)

I think the problem is in the average() or lowest() or highest() methods but I cant find the bug. I dont think there is anything wrong in those methods that can lead to counting outside the array length (length is 8) and index is 0-7. I've looked at other links in stackoverflow but I can't find whats wrong. I hope someone can help me?

The output I am trying to achieve is:

Countries       1    2    3    4    5   Average   
UK             6.2  2.5  9.7  4.3  0.1  3.4
Italy          7.1  1.2  1.6  5.5  1.9  3.7
Germany        8.5  3.3  6.7  4.0  6.0  5.9
Thailand       5.3  8.5  1.5 10.0  2.7  4.1
Denmark        3.1  4.9  5.4  0.8  3.2  3.4


The result is:
Winner: Miss Germany
1st runner up: Miss Thailand
Isabel
  • 51
  • 1
  • 7
  • 2
    Show the complete stackstrace – drum May 29 '20 at 04:03
  • The answer lies in your stacktrace. A) The index value causing the error is 5. B) It occurs in the method 'average' which happens on line 121. It can be confusing because that line has multiple methods. When your stuck it is a good idea to break the call down into multiple calls. – matt May 29 '20 at 04:36
  • @matt but in lowest() and highest() the int i starts from 0. Why do I need to -1 still? Can you please explain? – Isabel May 29 '20 at 05:41
  • When you run your loop, the `i++` gets evaluated after each iteration. So when the loop is on the last iteration it says `i++` then it check if `i – matt May 29 '20 at 05:54
  • @matt sorry, but i thought i will only be increased until 4 ( so from 0 to 4 ) because 4<5? and score.length is equal to 5? like for example in this link: https://www.tutorialspoint.com/cprogramming/c_for_loop.htm – Isabel May 29 '20 at 06:44
  • Inside of the loop the value doesn't exceed 4, but the post loop action still gets executed (they call it increment), which means the value to increases. So look at the example you pasted. They never check `i` after the loop. https://ideone.com/1PVgMa you don't have to take my word for it though. – matt May 29 '20 at 07:04
  • @matt oh i see now. thank you very much. so is there a better way to write lowest() and highest() so that I don't have to -1 at the average() method? – Isabel May 29 '20 at 08:57
  • I can only guess how you want it to work. Maybe this would be better. https://ideone.com/bMuQey – matt May 29 '20 at 09:08
  • It is even normal to have error when you know how to code. – matt May 29 '20 at 12:29

1 Answers1

1

The problem is actually in your average method. This line:

average = (sum - score[lowest()] - score[highest()] )/ score.length -2;

Needs to be changed to:

average = (sum - lowest() - highest() )/ score.length -2;

Remember that all indices start at 0 in arrays.

You also forgot to return a value, so you need to put return average; at the end of the average method. Also, in your getWinner method, you need to declare the variable winner by putting int winner = 0; at the beginning of the getWinner method.

highest() also needs to be edited to return highest;, and lowest() needs to be edited to return lowest;. You will need to change those return types to double to make this work.

Charlie Armstrong
  • 2,332
  • 3
  • 13
  • 25
  • but in lowest() and highest() the int i starts from 0. Why do I need to -1 still? Can you please explain? – Isabel May 29 '20 at 05:38
  • In your `highest()` and `lowest()` methods, you return `i`, which is always incremented to `score.length`, no matter what happens inside the `for` loop. I did not debug your code, as I can never be sure what is intentional and what is not, but I think you mean to return the variables `highest` and `lowest`. I have updated my answer to reflect this. – Charlie Armstrong May 29 '20 at 05:52
  • If they return highest and lowest, they cannot use the value as an index. – matt May 29 '20 at 06:00
  • Exactly. You are returning a value from the array, not an index to look up in the array. Notice when I updated my answer I also updated the averaging line to use just the returned values, rather than looking them up in the array. This results in fewer operations and seems less messy. – Charlie Armstrong May 29 '20 at 16:15