The sortYears() method should sort the movies by year of release in descending order. It compiles fine, but does not change the order of the movies in the array sorted. What is the least uncomplicated way to fix make it work? Thanks.
Movie2 class:
public class Movie2 implements Comparable<Movie2>
{
// instance variables
private String title;
private int year;
private String studio;
public Movie2(String title, int year, String studio)
{
// initialise instance variables
this.title = title;
this.year = year;
this.studio = studio;
}
public String toString()
{
String listing;
listing = title + ", " + year + ", " + studio;
return listing;
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
public void setYear(int year)
{
this.year = year;
}
public int getYear()
{
return year;
}
public void setStudio(String studio)
{
this.studio = studio;
}
public String getStudio()
{
return studio;
}
public int compareTo(Movie2 obj)
{
if (title.equals(obj.title))
return -1;
else if (title == obj.title)
return 0;
else
return 1;
}
}
TestMovie2 class:
public class TestMovie2
{
public static void main(String[] args)
{
Movie2[] myMovies = new Movie2[10];
Movie2[] sorted = new Movie2[10];
myMovies[0] = new Movie2("The Muppets Take Manhattan", 2001, "Columbia Tristar");
myMovies[1] = new Movie2("Mulan Special Edition", 2004, "Disney");
myMovies[2] = new Movie2("Shrek 2", 2004, "Dreamworks");
myMovies[3] = new Movie2("The Incredibles", 2004, "Pixar");
myMovies[4] = new Movie2("Nanny McPhee", 2006, "Universal");
myMovies[5] = new Movie2("The Curse of the Were-Rabbit", 2006, "Aardman");
myMovies[6] = new Movie2("Ice Age", 2002, "20th Century Fox");
myMovies[7] = new Movie2("Lilo & Stitch", 2002, "Disney");
myMovies[8] = new Movie2("Robots", 2005, "20th Century Fox");
myMovies[9] = new Movie2("Monsters Inc.", 2001, "Pixar");
System.out.println(" Movies (before change) ");
System.out.println("______________________________");
System.out.println();
printMovies(myMovies);
System.out.println();
System.out.println();
for (int i = 0; i < myMovies.length; i++)
{
int next = myMovies[i].getYear();
int insertIndex = 0;
int k = i;
while (k>0 && insertIndex == 0)
{
if (next > sorted[k-1].getYear())
{
insertIndex = k;
}
else
{
sorted[k] = sorted[k-1];
}
k--;
}
sorted[insertIndex].setYear(next);
}
sortYears(myMovies, sorted);
System.out.println(" Sorted by year - descending");
System.out.println("______________________________");
System.out.println();
printMovies(sorted);
System.out.println();
System.out.println();
public static void printMovies(Movie2[] sorted)
{
for(int i = 0; i < sorted.length; i++)
System.out.println(sorted[i]);
}
public static void sortYears(Movie2[] myMovies, Movie2[] sorted)
{
for ( int i = 0 ; i < myMovies.length ; i++ )
{
Movie2 next = myMovies[ i ];
int insertindex = 0;
int k = i;
while ( k > 0 && insertindex == 0 )
{
if ( next.getYear() > sorted[k-1].getYear() )
{
insertindex = k;
}
else
{
sorted[ k ] = sorted[ k - 1 ];
}
k--;
}
sorted[ insertindex ] = next;
}
You are going about your insertion sort incorrectly. Think about the logic needed to sort from Highest to lowest. This is an insertion sort working with an array, but this works, and can be extrapolated to fit your code.
public static void main(String[] args) {
int [] ar1 = {1, 5, 4, 9, 3, 2, 7, 8, 6, 0};
int temp = 0;
System.out.println ("Unsorted: ");
for (int i = 0; i < ar1.length; i++)
System.out.print (ar1[i] + " ");
for (int i = 1; i < ar1.length; i++) {
temp = ar1[i];
// temp < ar1[j] = Sort in ascending order
for (int j = i - 1; j >= 0 && temp > ar1[j]; j--) {
ar1[j + 1] = ar1[j];
}
ar1[j + 1] = temp;
}
System.out.println ("\nSorted: ");
for (int i = 0; i < ar1.length; i++)
System.out.print (ar1[i] + " ");
}
}
Related
hi so im currently trying to get past this error in my code, if anyone could explain where I went wrong, would be greatly appreciated.
public class Lab07vst100SD
{
public static void main (String[] args)
{
System.out.println();
int size = 10;
School bhs = new School(size);
System.out.println(bhs);
System.out.println(bhs.linearSearch("Meg"));
System.out.println(bhs.linearSearch("Sid"));
System.out.println();
bhs.selectionSort();
System.out.println(bhs);
System.out.println(bhs.binarySearch("Meg"));
System.out.println(bhs.binarySearch("Sid"));
System.out.println();
}
}
class School
{
private ArrayList<Student> students;
private int size;
public School (int s)
{
students = new ArrayList<Student>();
size = s;
}
public void addData()
{
String [] name = {"Tom","Ann","Bob","Jan","Joe","Sue","Jay","Meg","Art","Deb"};
int[] age = {21,34,18,45,27,19,30,38,40,35};
double[] gpa = {1.685,3.875,2.5,4.0,2.975,3.225,3.65,2.0,3.999,2.125};
for(int i = 0; i < name.length; i++)
{
students.add(new Student(name[i], age[i], gpa[i]));
}
size = students.size();
}
public void selectionSort ()
{
for(int h = 0; h < students.size(); h++)
{
int index = h;
Student least = students.get(h);
for (int t = 0; t < size; t++) {
if (students.get(t).equals(least)) {
least = students.get(t);
index = t;
}
Student temp = students.get(h);
students.set(h, least);
students.set(t, temp);
}
}
}
public int linearSearch (String str)
{
// new arraylist
ArrayList<String> names = new ArrayList<String>();
for (int q = 0; q < size; q++) {
names.add(students.get(q).getName());
}
//comparison
for (int y = 0; y < size; y++) {
if (names.get(y).equals(str))
return y;
}
return -1;
};
public int binarySearch (String str) {
// new arraylist and variables
ArrayList<String> names = new ArrayList<String>();
Boolean found = false;
int lo = 0;
int hi = size;
int mid = (lo + hi) / 2;
//for loop for to transverse the array.
for (int m = 0; m < size; m++) {
names.add(students.get(m).getName());
}
while (lo <= hi && !found) {
if (names.get(mid).compareTo(str) == 0)
{
found = true;
return mid;
}
if (names.get(mid).compareTo(str) < 0) {
lo = mid + 1;
mid = (lo + hi) / 2;
}
else {
hi = mid -1;
mid = (lo + hi) / 2;
}
}
if (found)
return mid;
else
return -1;
}
public String toString() {
String temp = "";
for (int s = 0; s < students.size(); s++) {
temp += students.get(s);
}
return temp;
}
}
also, I should mention this uses the student class.
here
public class Student
{
private String name;
private int age;
private double gpa;
public Student (String n, int a, double g)
{
name = n;
age = a;
gpa = g;
}
public String getName() {
return name; }
public int getAge() {
return age; }
public double getGPA() {
return gpa; }
public String toString()
{
String temp = name + " " + age + " " + gpa + "\n";
return temp;
}
}
the school class calls to the student class.
this is what comes back.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at School.linearSearch(Lab07vst100SD.java:78)
at Lab07vst100SD.main(Lab07vst100SD.java:16)
I'm completely confused on why this is happening, I think it may have to do with the ArrayList, other than that, I'm not sure.
please help, and thank you
p.s. I'm new so please bear with my horrible format.
You need call addData:
public static void main (String[] args)
{
System.out.println();
int size = 10;
School bhs = new School(size);
bhs.addData(); // here
System.out.println(bhs);
System.out.println(bhs.linearSearch("Meg"));
System.out.println(bhs.linearSearch("Sid"));
System.out.println();
bhs.selectionSort();
System.out.println(bhs);
System.out.println(bhs.binarySearch("Meg"));
System.out.println(bhs.binarySearch("Sid"));
System.out.println();
}
...
class School
{
private ArrayList<Student> students;
private int size;
public School (int s)
{
students = new ArrayList<Student>(); // Here, it can throw IndexOutOfBoundsException
size = s;
}
...
Please see https://www.tutorialspoint.com/java/util/arraylist_add_index.htm
The capacity of ArrayList must be initialized before ArrayList.add method
.
I've created a program with an object called CarlysCatering. I'm trying to sort the CarlysCatering objects by number of guests.
I've tried using a bubble sort but I get an error message.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
CarlysCatering[] event = new CarlysCatering[100];
event[0] = new CarlysCatering(10, "A547", "6874714145", 0);
event[1] = new CarlysCatering(100, "B527", "6874874945", 2);
event[2] = new CarlysCatering(50, "C546", "6874785145", 3);
event[3] = new CarlysCatering(40, "L577", "6874321485", 1);
event[4] = new CarlysCatering(70, "A111", "6874714145", 4);
event[5] = new CarlysCatering(90, "K222", "6874974855", 2);
event[6] = new CarlysCatering(11, "F798", "6875555555", 3);
event[7] = new CarlysCatering(17, "T696", "6474763898", 0);
//SORT
int selection = 0;
do {
System.out.println("1 - sort by eventID. 2 - sort by number of guests. 3 - sort by event type. 4 - quit");
selection = input.nextInt();
input.nextLine();
if(selection == 1) {
}
if(selection == 2) {
int n = event.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (event[j].getGuests() > event[j + 1].getGuests()) {
// swap arr[j+1] and arr[i]
CarlysCatering temp = event[j];
event[j] = event[j + 1];
event[j + 1] = temp;
}
}
}
}
} while (selection != 4);
//Print totals
event[0].getTotals(); event[1].getTotals(); event[2].getTotals(); event[3].getTotals(); event[4].getTotals(); event[5].getTotals(); event[6].getTotals(); event[7].getTotals();
}
////////////////////////////////////////////////////// STATIC METHODS //////////////////////////////////////////////////////////////////////
}
public class CarlysCatering {
public static final int PRICE_PER_GUEST_HIGH = 35;
public static final int PRICE_PER_GUEST_LOW = 32;
public static final int CUTOFF_VALUE_LARGE = 49;
private int guests;
private int totalPrice;
private String eventID;
private String phoneNumber;
private String eventType;
private boolean largeEvent;
///////////////////////////////////////////////////// CONSTRUCTORS //////////////////////////////////////////////////////////////////
CarlysCatering() {
this.guests = 0;
this.eventID = "A000";
this.phoneNumber = "0000000000";
}
CarlysCatering(int guests, String eventID, String phoneNumber, int eventType) {
this.guests = guests;
this.eventID = eventID;
//Phone Number formatting
String phoneNumber2 = "";
int count = 0;
for(int i = 0; i < phoneNumber.length(); i++) {
if (Character.isDigit(phoneNumber.charAt(i))) {
phoneNumber2 += phoneNumber.charAt(i);
count += 1;
}
}
if (count != 10) {
this.phoneNumber = "0000000000";
} else {
String phoneNumber3 = "(" + phoneNumber2.substring(0,3) + ") " + phoneNumber2.substring(3,6) + "-" + phoneNumber2.substring(6,10);
this.phoneNumber = phoneNumber3;
}
//Event type formatting
final String[] eventString = new String[5];
eventString[0] = "wedding"; eventString[1] = "baptism"; eventString[2] = "birthday"; eventString[3] = "corporate"; eventString[4] = "other";
if(eventType > -1 && eventType < 5) {
this.eventType = eventString[eventType];
} else {
this.eventType = eventString[4];
}
}
///////////////////////////////////////////////////////// SETTERS AND GETTERS /////////////////////////////////////////////////
//Setters
public void setEventID(String eventID) {
this.eventID = eventID;
}
public void setGuests(int guests) {
this.guests = guests;
}
public void setPhoneNumber(String phoneNumber) {
String phoneNumber2 = "";
int count = 0;
for (int i = 0; i < phoneNumber.length(); i++) {
if (Character.isDigit(phoneNumber.charAt(i))) {
phoneNumber2 += phoneNumber.charAt(i);
count += 1;
}
}
if (count != 10) {
this.phoneNumber = "0000000000";
} else {
String phoneNumber3 = "(" + phoneNumber2.substring(0, 3) + ") " + phoneNumber2.substring(3, 6) + "-" + phoneNumber2.substring(6, 10);
this.phoneNumber = phoneNumber3;
}
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
//Getters
public int getTotalPrice() {
return totalPrice;
}
public int getGuests() {
return guests;
}
public String getEventID() {
return eventID;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getEventType() {
return eventType;
}
/////////////////////////////////////////////////////// ADDITIONAL METHODS ///////////////////////////////////////////////////////////////////
public void isLargeEvent() {
if (this.guests > CUTOFF_VALUE_LARGE) {
largeEvent = true;
System.out.println("Yes this is a large event.");
} else {
largeEvent = false;
System.out.println("This is not a large event");
}
}
public void getTotals() {
boolean largeEvent = false;
if(this.guests > CUTOFF_VALUE_LARGE) {
largeEvent = true;
this.totalPrice = this.guests * PRICE_PER_GUEST_HIGH;
} else {
largeEvent = false;
this.totalPrice = this.guests * PRICE_PER_GUEST_LOW;
}
System.out.println("The number of guests attending event " + this.eventID + " " + this.eventType + " is: " + this.guests + ". The total price is $" + this.totalPrice);
System.out.println("Large event: " + largeEvent);
System.out.println("The phone number on file is " + this.phoneNumber);
}
// Static methods
public static void showMotto() {
System.out.println("*****Carly's makes the food that makes it a party.*****");
}
}
The error message I get when I try to sort by guests is Exception in thread "main" java.lang.NullPointerException and then error code exit -1. The line that's causing the error is:
if (event[j].getGuests() > event[j + 1].getGuests()) {
You create an Array with the size 100.
After that, you fill it from index 0 to 7.
Every other place of the array remains null but the length is 100.
Then, you try to sort the array.
This throws a NullPointerException when you try to dereference (access) the 8. element:
event[j+1].getGuests()
I think you should use a smaller array(size 8) or a List.
So basically, I am trying to output both the top film for a specific year and the total income that movies made that year. Both of my methods are not working correctly and I am especially having trouble in getting the year that was input to match with the year that the movies have in the arrays in order to output the total income and top film of that year.
For now my program outputs like so:
**
Enter a year from 1991 - 2018: 2016
Thank you received 2016
The total amount made for 2016 was $966.50
The greatest income made by a movie in 2016 was The Jungle Book at $966.50**
However, the total amount for 2016 is not $966.50 and the top 2016 movie is not The Jungle Book, it is Finding Dory...
Here is the getInput.getUserInput()
public static int getUserInput(int minYear, int maxYear) {
int year = 0;
boolean keepLooping = true;
Scanner input = new Scanner(System.in);
while (keepLooping) {
System.out.printf("\nEnter a year from %s - %s:", minYear, maxYear);
year = input.nextInt();
if (year < minYear || year > maxYear) {
System.out.printf("Invalid entry . . .");
} else {
keepLooping = false;
}
}
return year;
}
Here is the class
public class Films {
private String filmTitle;
private double filmIncome;
private int premiereYear;
Films(String title, double income, int year) {
filmTitle = title;
filmIncome = income;
premiereYear = year;
}
public String getFilmTitle() {
return filmTitle;
}
public void setFilmTitle(String filmTitle) {
this.filmTitle = filmTitle;
}
public double getFilmIncome() {
return filmIncome;
}
public void setFilmIncome(double filmIncome) {
this.filmIncome = filmIncome;
}
public int getPremiereYear() {
return premiereYear;
}
public void setPremiereYear(int premiereYear) {
this.premiereYear = premiereYear;
}
}
Here is the file that runs the program
public static void main(String[] args) {
Films[] f = new Films[8];
f[0] = new Films("Frozen", 1290.0, 2013);
f[1] = new Films("The Lion King", 968.4, 1994);
f[2] = new Films("Zootopia", 1023.7, 2016);
f[3] = new Films("Incredibles 2", 1240.3, 2018);
f[4] = new Films("Finding Dory", 1028.5, 2016);
f[5] = new Films("Shrek 2", 919.8, 2004);
f[6] = new Films("The Jungle Book", 966.5, 2016);
f[7] = new Films("Despicable Me 2", 970.7, 2013);
int yearEntered = getInput.getUserInput(1991, 2018);
System.out.printf("\nThank you received %s", yearEntered);
Films total = getTotalIncome(f, yearEntered);
System.out.printf("\nThe total amount made for %s was $%2.2f", yearEntered, total.getFilmIncome());
Films top = getTopFilm(f, yearEntered);
if (top == null) {
System.out.printf("0");
} else {
System.out.printf("\nThe greatest income made by a movie in %s was %s at $%2.2f", yearEntered,
top.getFilmTitle(), top.getFilmIncome());
}
}
private static Films getTotalIncome(Films[] f, int yearEntered) {
Films totalIncome = null;
double add = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() == yearEntered) {
add += f[i].getFilmIncome();
totalIncome = f[i];
}
}
return totalIncome;
}
private static Films getTopFilm(Films[] f, int yearEntered) {
Films topFilm = null;
double max = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() != yearEntered) {
continue;
}
if (f[i].getFilmIncome() > max) {
topFilm = f[i];
}
}
return topFilm;
}
There seems to be a bug in your max function.
private static Films getTopFilm(Films[] f, int yearEntered) {
Films topFilm = null;
double max = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() != yearEntered) {
continue;
}
if (f[i].getFilmIncome() > max) {
topFilm = f[i];
max = f[i].getFilmIncome(); // you forget to set the value of max.
}
}
return topFilm;
}
Like Vivek said you have a problem in you max function
private static Films getTopFilm(Films[] f, int yearEntered) {
Films topFilm = null;
double max = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getFilmIncome() > max) {
topFilm = f[i];
//need to reset max here
max = f[i].getFilmIncome();
}
}
return topFilm;
}
but you also have a bug in your get getTotalIncome method as well:
private static double getTotalIncome(Films[] f, int yearEntered) {
double total = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() == yearEntered) {
total += f[i].getFilmIncome();
}
}
return total;
}
Im not sure why you were returning a Film object from there, what you wanted to do was iterate over the films summing up all movies from that year.
you would then edit your main function to call it as such
public static void main(String[] args) {
...
double total = getTotalIncome(f, yearEntered);
System.out.printf("\nThe total amount made for %s was $%2.2f", yearEntered, total);
...
}
public static void main(String[] args) {
Films[] f = new Films[8];
f[0] = new Films("Frozen", 1290.0, 2013);
f[1] = new Films("The Lion King", 968.4, 1994);
f[2] = new Films("Zootopia", 1023.7, 2016);
f[3] = new Films("Incredibles 2", 1240.3, 2018);
f[4] = new Films("Finding Dory", 1028.5, 2016);
f[5] = new Films("Shrek 2", 919.8, 2004);
f[6] = new Films("The Jungle Book", 966.5, 2016);
f[7] = new Films("Despicable Me 2", 970.7, 2013);
int yearEntered = getInput.getUserInput(1991, 2018);
System.out.printf("\nThank you received %s", yearEntered);
Films total = getTotalIncome(f, yearEntered);
System.out.printf("\nThe total amount made for %s was $%2.2f", yearEntered, total.getFilmIncome());
Films top = getTopFilm(f, yearEntered, total.getFilmIncome());
if (top == null) {
System.out.printf("0");
} else {
System.out.printf("\nThe greatest income made by a movie in %s was %s at $%2.2f", yearEntered, top.getFilmTitle(), top.getFilmIncome());
}
}
private static Films getTotalIncome(Films[] f, int yearEntered) {
Films totalIncome = null;
double add = 0;
double max = Double.MIN_VALUE;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() == yearEntered && max < f[i].getFilmIncome()) {
max = f[i].getFilmIncome(); totalIncome = f[i];
}
}
return totalIncome;
}
private static Films getTopFilm(Films[] f, int yearEntered,double total) {
Films topFilm = null;
double max = 0;
for (int i = 0; i < f.length; i++) {
if (f[i].getPremiereYear() != yearEntered) {
continue;
}
if (f[i].getFilmIncome() == total) {
topFilm = f[i];
break;
}
}
return topFilm;
}
I have a problem with implementation of merge sort in java. I am looking for the error almost week unfortunately without result. ArrayList at the entrance is the same as the output.
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
ArrayList<Integer> arrayListA = new ArrayList<Integer>();
ArrayList<Integer> arrayListB = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int firstIndexOfArrayList = 0;
private int lastIndexOfArrayListA;
private int lastIndexOfArrayListB;
public void Scal(ArrayList<Integer> basicArrayList, int p, int q, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListA = q;
this.lastIndexOfArrayListB = r;
int numberOfElementsArrayListA = lastIndexOfArrayListA
- firstIndexOfArrayList + 1;
int numberOfElementsArrayListB = lastIndexOfArrayListB
- lastIndexOfArrayListA;
for (int i = 0; i < numberOfElementsArrayListA; i++) {
arrayListA.set(i, basicArrayList.get(firstIndexOfArrayList + i));
}
for (int j = 0; j < numberOfElementsArrayListB; j++) {
arrayListB.set(j, basicArrayList.get(lastIndexOfArrayListA + j));
}
arrayListA.add(Integer.MAX_VALUE);
arrayListB.add(Integer.MAX_VALUE);
int i = 0;
int j = 0;
for (int k = firstIndexOfArrayList; k <= lastIndexOfArrayListB; k++) {
if (arrayListA.get(i) <= arrayListB.get(j)) {
basicArrayList.set(k, arrayListA.get(i));
i = i + 1;
} else {
basicArrayList.set(k, arrayListB.get(j));
j = j + 1;
}
}
}
public void MergeSort(ArrayList basicArrayList, int p, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListB = r;
if (firstIndexOfArrayList < lastIndexOfArrayListB) {
int lastIndexOfArrayListA = (firstIndexOfArrayList + lastIndexOfArrayListB) / 2;
MergeSort(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA);
MergeSort(basicArrayList, lastIndexOfArrayListA + 1,
lastIndexOfArrayListB);
Scal(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA,
lastIndexOfArrayListB);
}
}
public void setSize() {
System.out.println("Enter the number of elements to sort: ");
this.lastIndexOfArrayListB = input.nextInt();
}
public int getSize() {
return lastIndexOfArrayListB;
}
public void setData() {
System.out.println("Enter the numbers: ");
for (int i = 0; i < lastIndexOfArrayListB; i++) {
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable() {
System.out.println(basicArrayList.toString());
}
public static void main(String[] args) {
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.MergeSort(output.basicArrayList,
output.firstIndexOfArrayList, (output.getSize() - 1));
output.getTable();
}
}
In terms of fixing your code I had a crack at it and as far as I can tell this seems to work. To do this a lot of your code had to be changed but it does now sort all Integers properly
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int numbersToSort;
public void doMergeSort(int firstIndexOfArrayList,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
if(firstIndexOfArrayList<lastIndexOfArrayListB && (lastIndexOfArrayListB-firstIndexOfArrayList)>=1)
{
int mid = (lastIndexOfArrayListB + firstIndexOfArrayList)/2;
doMergeSort(firstIndexOfArrayList, mid, arrayList);
doMergeSort(mid+1, lastIndexOfArrayListB, arrayList);
Scal(firstIndexOfArrayList,mid,lastIndexOfArrayListB, arrayList);
}
}
public void Scal(int firstIndexOfArrayList,int lastIndexOfArrayListA,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
ArrayList<Integer> mergedSortedArray = new ArrayList<Integer>();
int leftIndex = firstIndexOfArrayList;
int rightIndex = lastIndexOfArrayListA+1;
while(leftIndex<=lastIndexOfArrayListA && rightIndex<=lastIndexOfArrayListB)
{
if(arrayList.get(leftIndex)<=arrayList.get(rightIndex))
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
else
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
}
while(leftIndex<=lastIndexOfArrayListA)
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
while(rightIndex<=lastIndexOfArrayListB)
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
int i = 0;
int j = firstIndexOfArrayList;
while(i<mergedSortedArray.size())
{
arrayList.set(j, mergedSortedArray.get(i++));
j++;
}
}
public void setSize()
{
System.out.println("Enter the number of elements to sort: ");
this.numbersToSort = input.nextInt();
}
public int getSize()
{
return numbersToSort;
}
public void setData()
{
System.out.println("Enter the numbers: ");
for (int i = 0; i < numbersToSort; i++)
{
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable()
{
System.out.println(basicArrayList.toString());
}
public void runSort(ArrayList<Integer> arrayList)
{
doMergeSort(0, this.numbersToSort-1, arrayList);
}
public static void main(String[] args)
{
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.runSort(output.basicArrayList);
output.getTable();
}
}
Try this code. The following code takes an ArrayList input and outputs an ArrayList as well so it still works along the same basis of your code. The actual sort is handled in a different class MergeSort and is passes into ForMergeSort. Hope this helps
MergeSort.java
public class MergeSort
{
private int[] array;
private int[] tempMergArr;
private int length;
public void sort(int[] inputArr)
{
}
public int[] getSortedArray(int[] inputArr)
{
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
for(int i=0;i<length;i++)
{
int correctNumber = i+1;
System.out.println("Value "+correctNumber+" of the sorted array which was sorted via the Merge Sort is: "+inputArr[i]);
}
return inputArr;
}
private void doMergeSort(int lowerIndex, int higherIndex)
{
if (lowerIndex < higherIndex)
{
int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
doMergeSort(lowerIndex, middle);
doMergeSort(middle + 1, higherIndex);
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex)
{
for (int i = lowerIndex; i <= higherIndex; i++)
{
tempMergArr[i] = array[i];
}
int i = lowerIndex;
int j = middle + 1;
int k = lowerIndex;
while (i <= middle && j <= higherIndex)
{
if (tempMergArr[i] <= tempMergArr[j])
{
array[k] = tempMergArr[i];
i++;
}
else
{
array[k] = tempMergArr[j];
j++;
}
k++;
}
while (i <= middle)
{
array[k] = tempMergArr[i];
k++;
i++;
}
}
}
ForMergeSort.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class ForMergeSort
{
ArrayList<Integer> arrayList = new ArrayList<Integer>();
ArrayList<Integer> sortedArrayList = new ArrayList<Integer>();
MergeSort mS = new MergeSort();
public void buildArrayList()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of elements to sort: ");
int toSort = input.nextInt();
System.out.println("Enter the numbers: ");
for(int i =0; i<toSort; i++)
{
int number = input.nextInt();
arrayList.add(number);
}
}
public void runMergeSort(ArrayList<Integer> arrayList)
{
int[] arrayOfValues = new int[arrayList.size()];
int i = 0;
for(int a:arrayList)
{
arrayOfValues[i] = a;
i++;
}
MergeSort mS = new MergeSort();
for(int intOfArray:mS.getSortedArray(arrayOfValues))
{
sortedArrayList.add(intOfArray);
}
System.out.println(sortedArrayList.toString());
}
public static void main(String[] args)
{
ForMergeSort fMS = new ForMergeSort();
fMS.buildArrayList();
fMS.runMergeSort(fMS.arrayList);
}
}
So I have been trying to run my LibraryTest.java program but it crashes when it has to use sortBooksByTitle() and sortBooksByNumPages(). The two sorting methods compile, but when I try to run the test class, it crashes.
These are my three java files.
Book.java
public class Book {
private String author;
private String title;
private int numPages;
public Book() {
title = "EMPTY";
}
public Book(String titleIn, String authorIn, int numPagesIn) {
title = titleIn;
author = authorIn;
numPages = numPagesIn;
}
public String getAuthor() {
return author;
}
public String getTitle() {
return title;
}
public int getNumPages() {
return numPages;
}
public String toString() {
return title + " by " + author + " (" + numPages + " pages)";
}
}
Library.java
import java.util.Random;
import java.util.Arrays;
public class Library {
private Book[] array;
private int count;
private Random randomBook = new Random();
public Library(int numBooks) {
array = new Book[numBooks];
count = 0;
}
public int getCount() {
return count;
}
public void addBook(Book b) {
//check if program can add new book
if (count < array.length) {
array[count] = b;
count++;
} //if array is full, a message is thrown
else {
System.out.println("The Library is full!");
}
}
//Adds content of a library to another library.
public void addLibrary(Library l) {
for (Book b : l.array) {
addBook(b);
}
}
//Returns a book after receiving a String input.
public Book getBook(String book) {
for (int i = 0; i < array.length - 1; i++) {
String titleBook = array[i].getTitle();
if (titleBook.equals(book)) {
return array[i];
}
}
Book newBook = new Book();
return newBook;
}
//Returns the book located in the array index given by the input.
public Book getBook(int index) {
if (index < array.length) {
System.out.printf("num: %d", index);
return array[index - 1];
}
Book newBook = new Book();
return newBook;
}
//Uses the random number generator and returns a book located in the array which
//index is the random number obtained.
public Book getBook() {
int num = randomBook.nextInt(array.length);
//System.out.printf("random num: %d", num);
return array[num];
}
//Sorts books alphabetically.
public void sortBooksByNumPages() {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i].getNumPages() > array[j].getNumPages()) {
Book temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
//Sorts books by number of pages in ascending order.
public void sortBooksByTitle() {
for (int i = 0; i < array.length - 1; i++) {
for (int n = i; n < array.length; n++) {
if (array[n].getTitle().compareToIgnoreCase(array[i].getTitle()) < 0) {
Book temp = array[i];
array[i] = array[n];
array[n] = temp;
}
}
}
}
//Output each book's information.
public String toString() {
String s = "Number of books: " + count + "\n";
for (int i = 0; i < array.length; i++) {
s = s + array[i] + "\n";
}
return s;
}
}
LibraryTest.java
public class LibraryTest {
public static void main(String args[]) {
Library lib = new Library(3);
Book b1 = new Book("Java: How to Program", "Deitel and Deitel", 1496);
lib.addBook(b1);
Book b2 = new Book("A Brief History of Time", "Stephen Hawking", 212);
lib.addBook(b2);
Book b3 = new Book("The Art of War", "Sun Tzu", 384);
lib.addBook(b3);
Book b4 = new Book("Ender's Game", "Orson Scott Card", 352);
// This addBook call should fail since the Library lib is full
lib.addBook(b4);
Book b5 = new Book("The Singularity is Near", "Ray Kurzweil", 672);
Library lib2 = new Library(10);
lib2.addBook(b4);
lib2.addBook(b5);
System.out.print("\n\nOriginal library contents\n");
// This should display that there are 3 books in the library & info
System.out.print(lib);
System.out.print("\n\nAfter combining libraries\n");
lib2.addLibrary(lib);
lib = lib2;
// This should display that there are 5 books in the library & info
System.out.print(lib);
System.out.print("\n\nSorted by title\n");
try {
lib.sortBooksByTitle();
} catch (Exception e) {
System.out.println(e.toString());
System.out.println(e.getMessage());
}
// This should display the books in alphabetical order by title
System.out.print(lib);
/*
* System.out.print("\n\nSorted by number of pages\n");
* lib.sortBooksByNumPages(); // This should display the books in
* increasing order of the number of //pages each one has
* System.out.print(lib);
*/
// This should display Ender's Game
System.out.print("\n\nBook 2:\n" + lib.getBook(1));
// This should display the EMPTY book
System.out.print("\n\nBook 20:\n" + lib.getBook(20));
System.out.print("\n\nBook 'The Art of War':\n"
+ lib.getBook("The Art of War"));
// This should randomly display a book from the library (potentially
//different each time)
System.out.print("\n\nRandom book:\n" + lib.getBook());
}
}
Again the 3 files compile just fine but crash when I try to run. Help me please. Thank you.
The problem is a NullPointerException thrown in your sortBooksByTitle() method. The specific line where the exception is thrown is
if (array[n].getTitle().compareToIgnoreCase(array[i].getTitle()) < 0).
This is happening because when you create lib2you do so by calling new Library(10) which causes it to initialize its array to size 10. At the time of calling sortBooksByTitle() the array contains 5 books and 5 null values. Once the loop has gone through the 5 books it hits a null and calls getTitle() on it, which results in your NPE.