Big Java / Java Concepts Lab 8

Using Arrays

1.

In the text, we have frequently used the Random.nextInt method to generate random integers. For example, 1 + Random.nextInt(6) generates random numbers between 1 and 6, simulating the throw of a die. In this lab assignment, use an array to test whether the random generator is fair, that is, whether each possible value is generated approximately the same number of times.

Your program should ask the user:

  • How many random numbers should be generated?
  • What is the number of values for each random draw? (e.g., 6)

Make an array with one element for each possible outcome. Set each element to 0. Then keep calling the random number generator. If it returns a value v, then increment the counter belonging to v.

After all numbers have been generated, print the counters. Here is a typical program run:

How many numbers do you want to generate? 1000
What is the number of values? 10
0 78
1 101
2 118
3 97
4 103
5 102
6 112
7 91
8 94
9 104

What is the code for your program?


Simple Array Algorithms

2.

<>In the following problem you will write a method for the class ScoreSet
that finds an average score from a sequence of scores where the lowest two scores are discarded. Part of the class has been provided for you:

public class ScoreSet
{
   public ScoreSet()
   {
      scores = new ArrayList<Integer>();  
   }

    public void add(int score)
    {
       Integer wrapper = new Integer(score);
       scores.add(wrapper);
   }
   public double averageWithoutLowest2() { . . . }

   private ArrayList<Integer> scores;
}

Change the add method so that it uses auto-boxing instead of explicitly creating a wrapper.



3.

Provide an implementation for the method averageWithoutLowest2 that finds an average score from a sequence of scores where the lowest two scores are discarded.



4.

How does your class process duplicate scores? For example, how does it process 95, 90, 90, 68, 78, 68, 68, 80? What do you think it should do?


The Enhanced for Loop

5.

Write a toString method to the class ScoreSet that creates a string representation of the array list, using an enhanced for loop (a for each loop).

For example, a ScoreSet with the values of the previous question should yield the string "[95 90 90 68 78 68 68 80]"


Avoiding Parallel Arrays

6.

Write a program that reads in the names and scores of students and then computes and displays the names of the students with the highest and lowest scores.

A simple method of carrying out this task would be to have two parallel arrays.


String[] names;
int[] scores;

However, you should avoid parallel arrays in your solution.

First, write a class Student to solve the parallel array problem. Leave the StudentScores class and tester class for the following exercises. A Student simply holds a student name and a score.

What is your Student class?



7.

Next is a bad implementation of the StudentScores class that uses two parallel arrays. Modify it to eliminate the use of parallel arrays. Use an array list of students in your solution.


public class BadStudentScores
{
    public BadStudentScores()
    {
        scores = new int[MAX_STUDENTS];
        names = new String[MAX_STUDENTS];
        numStudents = 0;
    }

    public void add(String name, int score)
    {
       if (numStudents >= MAX_STUDENTS)
       return; // not enough space to add new student score

       names[numStudents] = name;
       scores[numStudents] = score;
       numStudents++;
    }

    public String getHighest()
    {
       if (numStudents == 0)
          return null;

      int highest = 0;

      for (int i = 1; i < numStudents; i++)
         if (scores[i] > scores[highest])
      highest = i;

      return names[highest];
    }

    public String getLowest()
    {
      if (numStudents == 0)
         return null;

      int lowest = 0;

      for (int i = 1; i < numStudents; i++)
      if (scores[i] < scores[lowest])
         lowest = i;

      return names[lowest];
    }

    private final int MAX_STUDENTS = 100;

    private String[] names;
    private int[] scores;
    private int numStudents;
}

Supply the code for the StudentScores class. Use the Student class that you created.



8.

Write a program that reads in the names and scores of students and then computes and displays the names of the students with the highest and lowest scores.

Part of the class code has been provided for you:


public class StudentScoresTester
{
    public static void main(String[] args)
    {
       StudentScores studSc = new StudentScores();
       Scanner in = new Scanner(System.in);
       boolean done = false;

       // Read the students names and scores, and add them to studSc

       do
       {
          System.out.println("Enter a student name or -1 to end: ");
          String name = in.nextLine();

          if (name.equals("-1"))
             done = true;
          else
          {
              System.out.println("Enter the student's score: ");
              int score = in.nextInt();
              in.nextLine(); // skip the end-of-line character

              /** Your code goes here */
          }
       }
       while (!done);

       // Find the students with highest and lowest scores and print
       // their names and scores
       /** And here */
    }
}

Complete the tester class, using the StudentScores class that you created in the previous exercise. What is the complete code for your class?


Using Array Lists to Collect Objects

9.

Array Lists can hold collections of objects that may be quite large. In the following lab program, generate random circle objects and store them in an ArrayList. If a circle does not intersect any of the previously stored circles, add it to the array. Finally, display all circles that you collected in the array. The result should look something like the image below. (Note that none of the circles intersect.)


.

If you don't know how to draw the circles, then you will need to print them out, which is less fun.

Use the code of the circleIntersect method that is given below to test whether two circles intersect. To randomly generate a circle, simply pick random x- and y- positions between 0 and 300 for the center and a random radius between 1 and 30. Compare each newly generated circle with all other circles before you add it. If the new circle passes the test, add it to the end of the array. Note that the array will have fewer elements than the number of generated circles since you are rejecting some of the circles.

Part of the code for the component class has been provided for you. Look for comments enclosed in "/** . . . */" which give you suggestions of how to complete the class.

public class CirclesComponent extends JComponent 
{
public CirclesComponent()
{
circles = new ArrayList<Ellipse2D.Double>();

// fill circles array list with circles

for (int i = 1; i <= NCIRCLES; i++)
{

// Set the values of x, y and r to three randomly generated values.
// Then, create a new Circle (Ellipse2D.Double) using these values



// Check that the new circle does not intersect a previous one.
// You will need to iterate through the array list and verify
// that the current circle does not intersect with a circle
/// in the array list.

// Add the circle to the array list if it does not intersect
// with another one.
}
}

/**
Test if two circles intersect.
(distance between centers is less than sum of radii)
@param c1 the first circle
@param c2 the second circle
@return true if c1 and c2 intersect
*/
public boolean circlesIntersect(Ellipse2D.Double c1,
Ellipse2D.Double c2)
{
double radius1 = c1.getWidth() / 2;
double radius2 = c2.getWidth() / 2;

double dx = c1.getX() + radius1 - c2.getX() - radius2;
double dy = c1.getY() + radius1 - c2.getY() - radius2;

double distance = Math.sqrt(dx * dx + dy * dy);
return distance < radius1 + radius2;
}

public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;

for (. . .) // iterate through every circle in the list
g2.draw(. . .); // draw the circle
}

private ArrayList<Ellipse2D.Double> circles;
}

Complete this class.


10.

Using the debugger or a print statement, find out what percentage of circles was rejected. (NCIRCLES - circles.size())

Run your program five times. What rejection percentages do you get?

Two-Dimensional Arrays

11.

In this problem, you will modify the TicTacToe class from the textbook. Add a method flipVertical that flips the board position along the vertical axis. For example, the position
x x o
o
x
is flipped to
o x x
o
x
This is not useful for playing the game, but it can be useful for recognizing a winning strategy in a database of strategies.

Also supply a flipHorizontal method that would flip the original position to
    x
o
x x o
(Hint: If you are clever and understand how two-dimensional arrays are implemented as "arrays of arrays", this method can be much simpler than the vertical flip.)

What is your implementation of the flipVertical and flipHorizontal methods?


12.

Supply a program that tests your method.