1.) I'm having difficulty testing me heap class. When I try to print my heap, it's giving me code instead of the array. I tried using toString() and DeeptoString() and neither worked.
2.) In my updateValue method. I realize that it doesn't know what to do once it's reached a node that has no children. It shoots me an index out of bounds. I think an easy way to check for that is to see if the left and right child index is greater or equal to the size. If it is...I guess I want it to do nothing.
Code below:
import java.util.NoSuchElementException;
public class MaxHeap {
public int[] heap;
private int size;
public static void main(String args[]){
MaxHeap testHeap = new MaxHeap(5);
testHeap.add(5);
testHeap.add(4);
testHeap.add(3);
testHeap.add(2);
testHeap.add(1);
System.out.println((testHeap));
testHeap.maxHeapify(0);
System.out.println(testHeap);
testHeap.extractMax();
System.out.println(testHeap);
testHeap.updateValue(1, 6);
System.out.println(testHeap);
}
/**
* _Part 0: Implement this constructor._
*
* Creates a new Heap instance initially capable of storing the specified
* number of elements.
*
* #param initialsize the initial size of the heap array
*/
public MaxHeap(int initialsize) {
// TODO: implement this
heap = new int [initialsize];
}
/**
* Provides read-only access to the heap's size. Size here is the number
* of *valid* items in the heap
*
* #return the number of items in the heap
*/
public int size() {
return size;
}
/**
* _Part 1: Implement this method._
*
* Adds an item to the heap maintaining the heap condition.
*
* An item is added to the next available slot in the array, and then
* bubbled up to its parent until the heap condition is restored.
*
* #param item
* the new int to add to the heap
*/
public void add(int item) {
// TODO: implement this
int parentIndex = (size-1)/2;
int childIndex = size;
heap[size] = item; //put it at the end
while (heap[parentIndex] < heap[childIndex] && parentIndex >= 0){ //check to make sure it's a proper heap
int temp = heap[parentIndex]; //start percolating up
heap[parentIndex] = heap[childIndex];
heap[childIndex] = temp;
childIndex = parentIndex;
parentIndex = (parentIndex-1)/2;
}
size+=1;
}
/**
* _Part 2: Implement this method._
*
* Restore the heap condition to a tree rooted at the specified index when
* the left and right subtrees obey the heap condition, but the root may
* not. This is also known as "Bubble Down".
*
* That is, given the specified index, and the fact that the left and
* right subtrees are heaps (if they exist), ensure that the largest of
* these three nodes get's swapped with the root, and then recursively
* restore the heap condition for the subtree with the element that was
* moved from the root.
*
* In essence, this method bubbles a value down from the root until the
* heap condition is restored.
*
* #param index
* the root tree to restore
*/
public void maxHeapify(int index) {
// TODO: implement this
int left, right, large, tmp; // declare variables left child, right child, largest node, temp for swap
int i = index;
left = 2 * i + 1; // left child
right = 2 * i + 2; // right child
if(left <= heap.length-1 && heap[left] > heap[i]) // find smallest child
large = left; // save index of smaller child
else
large = i;
if(right <= heap.length-1 && heap[right] > heap[large])
large = right; // save index of smaller child
if(large != i) // swap and percolate, if necessary
{
tmp = heap[i]; // exchange values at two indices
heap[i] = heap[large];
heap[large] = tmp;
maxHeapify(large);}
}
/**
* _Part 3: Implement this method._
*
* Removes the maximum valued item from the heap and restores the heap
* condition. If the heap is empty, this method should throw
* a NoSuchElementException
*
* This function is performed by:
*
* 1. removing the root of the heap
* 2. placing element from the end of the heap at the root
* 3. calling maxHeapify to restore the heap condition
* 4. making sure the size is updated
*
* #return the highest valued item from the heap
* #throws NoSuchElementException if called on an empty heap
*/
public int extractMax() {
// TODO: implement this
if (size < 1){
//throw no such element
throw new NoSuchElementException();
}
int max = heap[0];
heap[0] = heap[size-1];
size = size-1;
maxHeapify(0);
return max;
}
/**
* _Part 4: Implement this method._
*
* Checks to make sure that the *max* heap condition is upheld on a
* given array of integers.
*
* HINT: Full credit will be given on this one if you implement this
* method as a *recursive* function. It will probably make sense to
* create a private method that takes another argument (e.g., the index
* of the heap's root) to indicate where the checking should begin.
*
* My private method has the following signature:
* private static boolean check(int [] arry, int rootindx, int sz)
*
*
* #param array
* the array of data to check
* #param size
* the number of elements 'in' the heap (starting at index 0)
* #return true if the *max* heap condition is upheld
*/
public static boolean checkHeapCondition(int[] array, int size) {
// TODO: implement this
if (array != null)
return helpCheck(array,0, size);
return false;
}
//Helper method
private static boolean helpCheck(int[] arr, int i, int size) {
//Base case
if (i == size-1)
return true;
//2nd base case
if (2*i+1 >= size){
return true;
}
// check if a parent's value is larger or equal to both of
// its left child and right child
else if (arr[i] >= arr[2*i + 1] && arr[i] >= arr[2*i + 2])
return (helpCheck(arr, 2*i + 1, size) && helpCheck(arr, 2*i + 2, size));
else
return false;
}
/**
* _Part 5: Implement this method._
*
* Changes the value of an element in the heap. And bubbles the value
*
* #param index
* the index of the item to be modified
* #param newValue
* the new value of the specified item
* #return the old value of that item
* #throws IndexOutOfBoundsException if the specified index is invalid
*/
public int updateValue(int index, int newValue) {
// TODO: implement this
int parent = (index-1)/2;
int leftChild = (2*index +1);
int rightChild = (2*index+2);
if (heap == null || index >= size ){
throw new IndexOutOfBoundsException();}
int oldValue = heap[index];
heap[index] = newValue;
while (heap[parent] < heap[index] && parent >= 0 ){
int temp = heap[parent];
heap[parent] = heap[index];
heap[index] = heap[temp];
index = parent;
parent = (parent-1)/2;
}
//We need to check to see if the children don't exist
if (heap[leftChild] > heap[index] || heap[rightChild] > heap[index]){
maxHeapify(index);
return oldValue;
}
else return oldValue;
}
}
The method System.out.print(Object o) uses the parameter Object's toString() method. If you have not overridden this method to provide custom behavior, it will use the parent method (in this case, the default Object.toString()).
To print the value of MaxHeap, override it's toString method, returning a String that you want to represent an instance of this class. For instance:
#Override
public String toString(){
return java.util.Arrays.toString(heap);
}
I have found what's wrong with my updateValue. I created another if statement to check if the index value of the left and right child were within bounds. Thanks for all your help.
Related
I'm trying to implement the Union-Find algorithm, but all of the implementations i've looked up use integers. I need to implement the algorithm so that I can call the union() and the connected() methods in this way: union(Vertex v, Vertex, w) - connected(Vertex v, Vertex w)
I've tried adapting my algorithm for it to work with vertices, but I don't know how to replace the parent and rank atributes to make it work. Please help :(
public class UF {
private int[] parent; // parent[i] = parent of i
private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31)
private int count; // number of components
/**
* Initializes an empty union–find data structure with {#code n} sites
* {#code 0} through {#code n-1}. Each site is initially in its own
* component.
*
* #param n the number of sites
* #throws IllegalArgumentException if {#code n < 0}
*/
public UF(int n) {
if (n < 0) throw new IllegalArgumentException();
count = n;
parent = new int[n];
rank = new byte[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 0;
}
}
/**
* Returns the component identifier for the component containing site {#code p}.
*
* #param p the integer representing one site
* #return the component identifier for the component containing site {#code p}
* #throws IllegalArgumentException unless {#code 0 <= p < n}
*/
public int find(int p) {
validate(p);
while (p != parent[p]) {
parent[p] = parent[parent[p]]; // path compression by halving
p = parent[p];
}
return p;
}
/**
* Returns the number of components.
*
* #return the number of components (between {#code 1} and {#code n})
*/
public int count() {
return count;
}
/**
* Returns true if the the two sites are in the same component.
*
* #param p the integer representing one site
* #param q the integer representing the other site
* #return {#code true} if the two sites {#code p} and {#code q} are in the same component;
* {#code false} otherwise
* #throws IllegalArgumentException unless
* both {#code 0 <= p < n} and {#code 0 <= q < n}
*/
public boolean connected(int p, int q) {
return find(p) == find(q);
}
/**
* Merges the component containing site {#code p} with the
* the component containing site {#code q}.
*
* #param p the integer representing one site
* #param q the integer representing the other site
* #throws IllegalArgumentException unless
* both {#code 0 <= p < n} and {#code 0 <= q < n}
*/
public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) return;
// make root of smaller rank point to root of larger rank
if (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
else {
parent[rootQ] = rootP;
rank[rootP]++;
}
count--;
}
// validate that p is a valid index
private void validate(int p) {
int n = parent.length;
if (p < 0 || p >= n) {
throw new IllegalArgumentException("index " + p + " is not between 0 and " + (n-1));
}
}
}
In the standard algorithm each vertex is given an int id which represents it's place in an array. So this means parent[0] contains the id of the parent of vertex 0 and so.
Really you can consider arrays to be just a very efficient map from int to something else. If you replace the int with a more complex type then you need to start using a Map rather than an array.
So if you want to use a class called Vertex to represent vertices then you need to declare parents and ranks differently:
Map<Vertex,Vertex> parent = new HashMap<>();
Map<Vertex,Rank> rank = new HashMap<>();
You could replace Rank with Byte if you want to stick to the current scheme - though it's probably better encapsulation to use a class.
You'll then end up with code that looks something like:
while (!vertex.equals(parent.get(vertex))) {
parent.put(vertex, parent.get(parent.get(vertex)));
vertex = parent.get(vertex);
}
return vertex;
One thing to be aware of is that if you are going to use Vertex as the key of a map (as I've recommended) then you must implement equals and hashCode methods.
I'm trying to print out the full array id[] after each time the union() method is called. in the main() method. also need to bee able to count the number of times the array is accessed. I am aware that it is accessed twice when calling the connected method, once when calling find() and up to 2n + 1 when calling union(). Please help.
public class QuickFindUF {
private int[] id; // id[i] = component identifier of i
private int count; // number of components
/**
* Initializes an empty union–find data structure with {#code n} sites
* {#code 0} through {#code n-1}. Each site is initially in its own
* component.
*
* #param n the number of sites
* #throws IllegalArgumentException if {#code n < 0}
*/
public QuickFindUF(int n) {
count = n;
id = new int[n];
for (int i = 0; i < n; i++)
id[i] = i;
}
/**
* Returns the number of components.
*
* #return the number of components (between {#code 1} and {#code n})
*/
public int count() {
return count;
}
/**
* Returns the component identifier for the component containing site {#code p}.
*
* #param p the integer representing one site
* #return the component identifier for the component containing site {#code p}
* #throws IndexOutOfBoundsException unless {#code 0 <= p < n}
*/
public int find(int p) {
validate(p);
return id[p];
}
// validate that p is a valid index
private void validate(int p) {
int n = id.length;
if (p < 0 || p >= n) {
throw new IndexOutOfBoundsException("index " + p + " is not between 0 and " + (n-1));
}
}
/**
* Returns true if the the two sites are in the same component.
*
* #param p the integer representing one site
* #param q the integer representing the other site
* #return {#code true} if the two sites {#code p} and {#code q} are in the same component;
* {#code false} otherwise
* #throws IndexOutOfBoundsException unless
* both {#code 0 <= p < n} and {#code 0 <= q < n}
*/
public boolean connected(int p, int q) {
validate(p);
validate(q);
return id[p] == id[q];
}
/**
* Merges the component containing site {#code p} with the
* the component containing site {#code q}.
*
* #param p the integer representing one site
* #param q the integer representing the other site
* #throws IndexOutOfBoundsException unless
* both {#code 0 <= p < n} and {#code 0 <= q < n}
*/
public void union(int p, int q) {
validate(p);
validate(q);
int pID = id[p]; // needed for correctness
int qID = id[q]; // to reduce the number of array accesses
// p and q are already in the same component
if (pID == qID)
return;
for (int i = 0; i < id.length; i++)
if (id[i] == pID) id[i] = qID;
count--;
}
/**
* Reads in a sequence of pairs of integers (between 0 and n-1) from standard input,
* where each integer represents some site;
* if the sites are in different components, merge the two components
* and print the pair to standard output.
*
* #param args the command-line arguments
*/
public static void main(String[] args) {
int n = StdIn.readInt();
QuickFindUF uf = new QuickFindUF(n);
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt();
if (uf.connected(p, q)){
continue;
}
uf.union(p, q);
StdOut.println(p + " " + q);
}
StdOut.println(uf.count() + " components");
}
}
Trying to break down your question...
Part 1:
I'm trying to print out the full array id[] after each time the union
method is called. in the main method.
try to create a string buffer and add the elements while you access it. once you are done and wanna print the array, you can just print the string buffer..
public void union(int p, int q) {
validate(p);
validate(q);
int pID = id[p]; // needed for correctness
int qID = id[q]; // to reduce the number of array accesses
// p and q are already in the same component
if (pID == qID)
return;
StringBuilder sb=new StringBuilder("");
for (int i = 0; i < id.length; i++)
{
sb.append(id[i]) + " "; // you are accessing all id elements anyway; add it to the 'sb' string while you are at it
// seperate each id element with a space
// do it in this place (before the if statement below) if you would like to print the before state of the array
if (id[i] == pID)
id[i] = qID;
//sb.append(id[i]) + " "; // do it here if you would like to print the after state of the array
}
System.out.println(sb);
count--;
}
Part 2:
also need to bee able to count the number of times the array is
accessed. i am aware that it is accessed twice when calling the
connected method, once when calling find() and up to 2n + 1 when
calling union()
For this you need to consider refactoring your code.. since you are dealing with arrays in the same class, you will not be able to count the number of times you access this array.. You can however consider having the Array in a different class as a private variable. create points of access via a getter and/or setter methods. then you can count the number of times you access the array in a reliable way..
hope this helps..
This is more of a general solution for printing an array of primitives in java. You could do it much more simple than this by iterating over the array and printing each member, inserting a newline character once your print loop has completed it's last loop.
int length = Array.getLength(aObject);
Object[] objArr = new Object[length];
for (int i=0; i<length; i++)
objArr[i] = Array.get(aObject, i);
System.out.println(Arrays.toString(objArr))
Try a search next time :)
Print arrays in Java
Okay so this is one of my last assignments and of course this is creating the most stress for me but the only thing keeping me from turning this assignment in is being able to apply heapsort on the Heap that the user inputs their own integer values into an array list which is displayed and here is the code for that:
The heap propgram works fine but the Heapsort doesn't work or i can't use it or make a call for it in the HeapApp class
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
*/
public class Heap<T extends Comparable<T>> {
private ArrayList<T> items;
public Heap() {
items = new ArrayList<T>();
}
private void siftUp() {
int k = items.size() - 1;
while (k > 0) {
int p = (k-1)/2;
T item = items.get(k);
T parent = items.get(p);
if (item.compareTo(parent) > 0) {
// swap
items.set(k, parent);
items.set(p, item);
// move up one level
k = p;
} else {
break;
}
}
}
public void insert(T item) {
items.add(item);
siftUp();
}
private void siftDown() {
int k = 0;
int l = 2*k+1;
while (l < items.size()) {
int max=l, r=l+1;
if (r < items.size()) { // there is a right child
if (items.get(r).compareTo(items.get(l)) > 0) {
max++;
}
}
if (items.get(k).compareTo(items.get(max)) < 0) {
// switch
T temp = items.get(k);
items.set(k, items.get(max));
items.set(max, temp);
k = max;
l = 2*k+1;
} else {
break;
}
}
}
public T delete()
throws NoSuchElementException {
if (items.size() == 0) {
throw new NoSuchElementException();
}
if (items.size() == 1) {
return items.remove(0);
}
T hold = items.get(0);
items.set(0, items.remove(items.size()-1));
siftDown();
return hold;
}
public int size() {
return items.size();
}
public boolean isEmpty() {
return items.isEmpty();
}
public String toString() {
return items.toString();
}
//----------------------------------------------------------------------------------------------------------------------------------------
public class Heapsort<T extends Comparable<T>> {
/**
* Sort the array a[0..n-1] by the heapsort algorithm.
*
* #param a the array to be sorted
* #param n the number of elements of a that have valid values
*/
public void sort(T[] a, int n) {
heapsort(a, n - 1);
}
/**
* Sort the ArrayList list by the heapsort algorithm.
* Works by converting the ArrayList to an array, sorting the
* array, and converting the result back to the ArrayList.
*
* #param list the ArrayList to be sorted
*/
public void sort(ArrayList<T> items) {
// Convert list to an array.
#SuppressWarnings("unchecked")
T[] a = (T[]) items.toArray((T[]) Array.newInstance(items.get(0).getClass(), items.size()));
sort(a, items.size()); // sort the array
// Copy the sorted array elements back into the list.
for (int i = 0; i < a.length; i++)
items.set(i, a[i]);
}
/**
* Sort the array a[0..lastLeaf] by the heapsort algorithm.
*
* #param items the array holding the heap
* #param lastLeaf the position of the last leaf in the array
*/
private void heapsort(T[] items, int lastLeaf) {
// First, turn the array a[0..lastLeaf] into a max-heap.
buildMaxHeap(items, lastLeaf);
// Once the array is a max-heap, repeatedly swap the root
// with the last leaf, putting the largest remaining element
// in the last leaf's position, declare this last leaf to no
// longer be in the heap, and then fix up the heap.
while (lastLeaf > 0) {
swap(items, 0, lastLeaf); // swap the root with the last leaf
lastLeaf--; // the last leaf is no longer in the heap
maxHeapify(items, 0, lastLeaf); // fix up what's left
}
}
/**
* Restore the max-heap property. When this method is called, the max-heap
* property holds everywhere, except possibly at node i and its children. When
* this method returns, the max-heap property holds everywhere.
*
* #param items the array holding the heap
* #param i index of the node that might violate the max-heap property
* #param lastLeaf the position of the last leaf in the array
*/
private void maxHeapify(T[] items, int i, int lastLeaf) {
int left = leftChild(i); // index of node i's left child
int right = rightChild(i); // index of node i's right child
int largest; // will hold the index of the node with the largest element
// among node i, left, and right
// Is there a left child and, if so, does the left child have an
// element larger than node i?
if (left <= lastLeaf && items[left].compareTo(items[i]) > 0)
largest = left; // yes, so the left child is the largest so far
else
largest = i; // no, so node i is the largest so far
// Is there a left child and, if so, does the right child have an
// element larger than the larger of node i and the left child?
if (right <= lastLeaf && items[right].compareTo(items[largest]) > 0)
largest = right; // yes, so the right child is the largest
// If node i holds an element larger than both the left and right
// children, then the max-heap property already held, and we need do
// nothing more. Otherwise, we need to swap node i with the larger
// of the two children, and then recurse down the heap from the larger
// child.
if (largest != i) {
swap(items, i, largest);
maxHeapify(items, largest, lastLeaf);
}
}
/**
* Form array a[0..lastLeaf] into a max-heap.
*
* #param items array to be heapified
* #param lastLeaf position of last valid data in a
*/
private void buildMaxHeap(T[] items, int lastLeaf) {
int lastNonLeaf = (lastLeaf - 1) / 2; // nodes lastNonLeaf+1 to lastLeaf are leaves
for (int j = lastNonLeaf; j >= 0; j--)
maxHeapify(items, j, lastLeaf);
}
/**
* Swap two locations i and j in array a.
*
* #param items the array
* #param i first position
* #param j second position
*/
private void swap(T[] items, int i, int j) {
T t = items[i];
items[i] = items[j];
items[j] = t;
}
/**
* Return the index of the left child of node i.
*
* #param i index of the parent node
* #return index of the left child of node i
*/
private int leftChild(int i) {
return 2 * i + 1;
}
/**
* Return the index of the right child of node i.
*
* #param i index of the parent node
* #return the index of the right child of node i
*/
private int rightChild(int i) {
return 2 * i + 2;
}
/**
* For debugging and testing, print out an array.
*
* #param a the array to print
* #param n number of elements of a to print
*/
public void printArray(T[] items, int n) {
for (int i = 0; i < n; i++)
System.out.println(items[i]);
}
}
}
import java.util.Scanner;
public class HeapApp{
/**
* #param args
*/
public static void main(String[] args) {
Heap<Integer> hp = new Heap<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Enter next int, 'done' to stop: ");
String line = sc.next();
while (!line.equals("done")) {
hp.insert(Integer.parseInt(line));
System.out.println(hp);
System.out.print("Enter next int, 'done' to stop: ");
line = sc.next();
}
while (hp.isEmpty()) {
//int max = hp.delete();
System.out.println( " " + hp);
}
System.out.println(hp);
System.out.println("After sorting " + hp);
}
}
Now i'm not asking anyone to do it for me but i just need help figuring out how to get the Heapsort to work with the heap PLEASE HELP! The most i have tried is setting the parameters within the Heap sort method.
My question and code is not a duplicate for one this is based on a Heap and heapsort from the user input:
public static void main(String[] args) {
Heap<Integer> hp = new Heap<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Enter next int, 'done' to stop: ");
String line = sc.next();
while (!line.equals("done")) {
hp.insert(Integer.parseInt(line));
System.out.println(hp);
System.out.print("Enter next int, 'done' to stop: ");
line = sc.next();
}
Also the entire Heap is implemented using an ArrayList:
public class Heap<T extends Comparable<T>> {
private ArrayList<T> items;
public Heap() {
items = new ArrayList<T>();
}
Add a sort method to your Heap class like this:
public void sort()
{
new Heapsort<T>().sort(items);
}
Then in your HeapApp class call the sort method before printing it out:
hp.sort();
System.out.println("After sorting " + hp);
I am an Undergraduate Computer Science Student and we're actually starting to learn the Java Language.
I am trying to solve one of my Labs but I have a problem.
My Problem is how to call a method from an other class, which is located in another package, and the package is already imported in my class.
I tried to write the nameOftheClass.nameOfthemethod(parameters); but that didn't work for me.
To be more Specefic, I was trying to call the method getElementAt(index) which is located in the frame package and in the SortArray Class .. But I don't have a clue why is this not working for me!
this is my QuicksortB Class :
package lab;
import frame.SortArray;
public class QuickSortB extends QuickSort {
/**
* Quicksort algorithm implementation to sort a SorrtArray by choosing the
* pivot as the median of the elements at positions (left,middle,right)
*
* #param records
* - list of elements to be sorted as a SortArray
* #param left
* - the index of the left bound for the algorithm
* #param right
* - the index of the right bound for the algorithm
* #return Returns the sorted list as SortArray
*/
#Override
public void Quicksort(SortArray records, int left, int right) {
// TODO
// implement the Quicksort B algorithm to sort the records
// (choose the pivot as the median value of the elements at position
// (left (first),middle,right(last)))
int i = left, j = right;
//Get The Element from the Middle of The List
int pivot = SortArray.getElementAt(left + (right-left)/2);
//Divide into two Lists
while (i <= j) {
// If the current value from the left list is smaller then the pivot
// element then get the next element from the left list
while (SortArray.getElementAt(i) < pivot) {
i++;
}
// If the current value from the right list is larger then the pivot
// element then get the next element from the right list
while (SortArray.getElementAt(j) > pivot) {
j--;
}
// If we have found a values in the left list which is larger then
// the pivot element and if we have found a value in the right list
// which is smaller then the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
exchange(i,j)
i++;
j--;
}
}
public void exchange(int i, int j) {
int temp = SortArray.getElementAt(i);
SortArray.getElementAt(i) = SortArray.getElementAt(j);
SortArraz.getElementAt(j) = temp;
}
}
}
And this is My SortArray Class :
package frame;
import java.util.ArrayList;
import lab.SortingItem;
/**
* Do NOT change anything in this class!
*
* The SortArray class provides simple basic functions, to store a list of
* sortingItems to track the number of operations.
*
* This class contains two members (readingOperations and writingOperations)
* that act as counters for the number of accesses to the arrays to be sorted.
* These are used by the JUnit tests to construct the output. The methods
* provided in this class should be sufficient for you to sort the records of
* the input files.
*
* #author Stefan Kropp
*/
public class SortArray {
private int numberOfItems;
private ArrayList<SortingItem> listOfItems;
private int readingOperations;
private int writingOperations;
/**
* #param numberOfItems
* number of items to hold
*/
public SortArray(ArrayList<String[]> items) {
numberOfItems = items.size();
readingOperations = 0;
writingOperations = 0;
listOfItems = new ArrayList<>();
for (String[] element : items) {
SortingItem s = new SortingItem();
s.BookSerialNumber = element[0];
s.ReaderID = element[1];
s.Status = element[2];
listOfItems.add(s);
}
}
/**
* sets the elements at index. if index is >= numberOfItems or less then
* zero an IndexOutOfBoundException will occur.
*
* #param index
* the index of the Elements to set
* #param record
* a 3-dimensional record which holds: BookSerialNumber,
* ReaderID, Status
*/
public void setElementAt(int index, SortingItem record) {
this.listOfItems.set(index, record);
writingOperations++;
}
/**
* Retrieves the information stored at position Index. if index is >=
* numberOfItems or less then zero an IndexOutOfBoundException will occur.
*
* #param index
* Index defines which elements to retrieve from the SortArray
* #return Returns a 3-dimensional String array with following format:
* BookSerialNumber, ReaderID, Status.
*
*/
public SortingItem getElementAt(int index) {
SortingItem result = new SortingItem(this.listOfItems.get(index));
readingOperations++;
return result;
}
/**
* #return Returns the number of reading operations.
*/
public int getReadingOperations() {
return readingOperations;
}
/**
* #return Returns the number of writing operations.
*/
public int getWritingOperations() {
return writingOperations;
}
/**
* #return Returns the numberOfItems.
*/
public int getNumberOfItems() {
return numberOfItems;
}
}
You attempted to call the method getElementAt as a static function. You have to create an instance of SortArray and then call the method on that object, e.g.
ArrayList<String[]> myList = ...; // some initialization
SortArray sortObject = new SortArray(myList);
SortingItem result = sortObject.getElementAt(0);
If you want your function to be accessible as you tried, you have to use the static modifier, which in turn means, you don't have access to members of the class (i.e. non-static fields).
public void doSomething() {
this.numberOfItems++; // this is allowed
}
In contrast to:
public static void doSomethingStatic() {
this.numberOfItems++; // this is not allowed
}
to call a method, you have to know if the method is static method (class method) or object method.
If it is static method, (like the famous main(String[] args)) you can just call it by ClassName.method(), if it is not static method, you have to first get the instance of the class, by calling the constructor for example, then call the method via oneInstance.method()
I suggest you reading the related chapters in your lecture text book, then do some test on your own.
I just don't give codes since this is an assignment.
The way you are trying to access the function is as if it were static, since you try to call it through the actual class, not from an object.
You should generate an object which references the desired class, in this case SortArray.
In QuickSortB
public SortArray sortArray;
#Override
public void Quicksort(SortArray records, int left, int right) {
// TODO
// implement the Quicksort B algorithm to sort the records
// (choose the pivot as the median value of the elements at position
// (left (first),middle,right(last)))
sortArray = new SortArray ();
int i = left, j = right;
//Get The Element from the Middle of The List
int pivot = sortArray.getElementAt(left + (right-left)/2);
//Divide into two Lists
while (i <= j) {
// If the current value from the left list is smaller then the pivot
// element then get the next element from the left list
while (sortArray.getElementAt(i) < pivot) {
i++;
}
// If the current value from the right list is larger then the pivot
// element then get the next element from the right list
while (sortArray.getElementAt(j) > pivot) {
j--;
}
// If we have found a values in the left list which is larger then
// the pivot element and if we have found a value in the right list
// which is smaller then the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
exchange(i,j)
i++;
j--;
}
}
public void exchange(int i, int j) {
int temp = SortArray.getElementAt(i);
sortArray.getElementAt(i) = SortArray.getElementAt(j);
sortArray.getElementAt(j) = temp;
}
}
}
Hope it helps^^
Create an instance of SortArray object and call using that reference check the below code for clarity
public class QuickSortB extends QuickSort {
//create instance of sortArray
SortArray sortArray=new SortArray();
//call the method like this
sortArray.getElementAt(i)
}
public class SortArray {
// code skipped for clarity
public SortingItem getElementAt(int index) {
SortingItem result = new SortingItem(this.listOfItems.get(index));
readingOperations++;
return result;
}
// code skipped for clarity
}
I'm a first year computer science student having a problem with part of an assignment. The goal of the assignment was to store the coefficients for a polynomial and find its roots using both an array and a linked list. I was able to successfully complete the array version; however the linked list is giving me a headache.
I am able to successfully store the initial round of variables provided in polynomial.java; however, things go a bit crazy once the root calculations begin and the program ends up terminating without giving any roots. I have a feeling this might be being cause by the way the Polynomial.java calculates the roots causing problems with the linked list; however, I am not allowed to change polynomial.java, only LinkedIntList.java. I have been banging my head against the computer for the past 7 hours trying to find the bug and am about ready to just give up on the assignment as I can't reach the professor for help.
I'd greatly appreciate anyone who can spot the bug or are willing to look over the code to provide tips on what I may be doing wrong or how I can work around my problem.
File 1: Node.Java
package lists;
public class Node
{
int element;
Node next = null;
/**
* Constructor which creates a new node containing the value specified by item
*
*/
public Node (int item)
{
element = item;
}
/**
* Returns the current value of the data item contained inside this node
*/
public int getElement ()
{
return element;
}
/**
* Sets the current value of the data item contained inside this node to
* the value specified by newVal
*/
public void setElement (int newVal)
{
element = newVal;
}
/**
* Links this node to the node passed in as an argument
*/
public void setNext (Node n)
{
next = n;
}
/**
* Returns a reference to the node that follows this node in the
* linked list, or null if there is no such node
*/
public Node getNext ()
{
return next;
}
/**
* Returns a string based representation of the data item contained
* in this node.
*/
public String toString()
{
return Integer.toString(element);
}
}
File 2: LinkedIntList.Java
package lists;
public class LinkedIntList implements IntList
{
Node head = null;
int count = 0;
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* #return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString()
{
String retVal = "";
String intermediary = "";
Node n;
for (n = head; n.getNext() != null; n = n.getNext())
{
intermediary = Integer.toString(n.getElement());
retVal = intermediary + " " + retVal;
}
retVal = n.getElement() + " " + retVal;
return retVal;
}
/**
* Adds the given value to the <b>end</b> of the list.
*
* #param value the value to add to the list
*/
public void add (int value)
{
Node newNode = new Node (value);
if (head == null)
head = newNode;
else
{
Node n = head;
while (n.getNext() != null)
{
n = n.getNext();
}
n.setNext(newNode);
}
count++;
}
/**
* Returns the number of elements currently in the list.
*
* #return the number of items currently in the list
*/
public int size()
{
return count;
}
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return (zero-based)
* #return the element at the specified position in this list.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index) throws IndexOutOfBoundsException
{
Node reference = head;
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
for (int i = 0; i != index; i++)
{
reference.getNext();
}
return reference.getElement();
}
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* #param index index of the element to return (zero-based)
* #param value element to be stored at the specified position.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value) throws IndexOutOfBoundsException
{
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
Node newNode = new Node (value);
Node trailingReference = head;
Node leadingReference = head.getNext();
for(int i = 1; i != index; i++)
{
trailingReference = leadingReference;
leadingReference = leadingReference.getNext();
}
trailingReference.setNext(newNode);
newNode.setNext(leadingReference);
count++;
}
}
File 3: IntList.Java
package lists;
public interface IntList
{
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* #return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString();
/**
* Adds the given value to the <b>end</b> of the list.
*
* #param value the value to add to the list
*/
public void add (int value);
/**
* Returns the number of elements currently in the list.
*
* #return the number of items currently in the list
*/
public int size();
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return (zero-based)
* #return the element at the specified position in this list.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index);
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* #param index index of the element to return (zero-based)
* #param value element to be stored at the specified position.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value);
}
File 4: Polynomial.java
/**
* A program which finds the integer (whole number) roots of a
* polynomial with integer coeffecients. The method used is based
* upon the ideas presented at:
*
*/
import lists.*;
public class Polynomial
{
public static void main (String [] args)
{
// trick to get out of static context
new Polynomial().runMe();
}
public void runMe()
{
IntList poly = new LinkedIntList();
// Create the polynomial:
// 3x^10 + 12x^9 - 496x^8 - 211x^7 + 18343x^6 -43760x^5 +
// 11766x^4 + 26841x^3 - 126816x^2 + 37278x - 84240
poly.add (-84240);
poly.add (37278);
poly.add (-126816);
poly.add (26841);
poly.add (11766);
poly.add (-43760);
poly.add (18343);
poly.add (-211);
poly.add (-496);
poly.add (12);
poly.add (3);
System.out.print ("Finding the integer roots of the polynomial: ");
System.out.println (poly);
IntList roots = findRoots (poly);
for (int x = 0; x < roots.size(); x++)
System.out.println ("Root found: " + roots.get(x));
}
/**
* Find all *integer* roots of the polynomial represented by the IntList.
*
* #param poly a polynomial encoded as a list of coefficients
* #return a list of all roots of the given polynomial. Note that
* the returned list may have duplicate entries.
*/
public IntList findRoots (IntList poly)
{
IntList l = new LinkedIntList();
int q = poly.get(poly.size() - 1);
int p = poly.get(0);
IntList pVals = divTerms(Math.abs(p));
IntList qVals = divTerms(Math.abs(q));
IntList possibleZeros = findPotentialZeros(pVals, qVals);
//for (Integer i : possibleZeros)
for (int x = 0; x < possibleZeros.size(); x++)
if (eval (poly, possibleZeros.get(x)) == 0)
l.add (possibleZeros.get(x));
return l;
}
/**
* Evaluates the polynomial represented by the IntList with the given
* value.
*
* #param poly a
* #param val the value to evaluate the polynomial with.
* #return f(val), where f is the polynomial encoded as poly
*/
private int eval (IntList poly, int val)
{
int result = 0;
for (int x = poly.size() - 1; x >= 0; x--)
result += poly.get(x) * (int) Math.pow (val, x);
return result;
}
private IntList findPotentialZeros (IntList plist, IntList qlist)
{
IntList result = new LinkedIntList();
for (int p = 0; p < plist.size(); p++)
{
for (int q = 0; q < qlist.size(); q++)
{
// add it only if q evenly divides p (we're looking
// for integer roots only
if (plist.get(p) % qlist.get(q) == 0)
{
int x = plist.get(p) / qlist.get(q);
result.add (x);
result.add (-x);
}
}
}
return result;
}
/**
* Find all integers that evenly divide i.
*
* #param i the integer to find all divisors of
* #return a list of all integers that evenly divide i
*/
private IntList divTerms (int i)
{
IntList v = new LinkedIntList();
// 1 divides all numbers
v.add(1);
// find all divisors < i and >= 2
for (int x = 2; x < i; x++)
if (i % x == 0)
v.add(x);
// all numbers are evenly divisible by themselves
if (i > 1)
v.add(i);
return v;
}
}
I think, the mistake (or one of them) is in your LinkedList imlementation, exactly in get method:
public int get(int index) throws IndexOutOfBoundsException
{
Node reference = head;
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
for (int i = 0; i != index; i++)
{
reference.getNext(); // <--- the mistake is here
}
return reference.getElement();
}
Your reference always refers on the head of the list.
If you're allowed to use any java packages - use java.util.LinkedList. Otherwise, use java.util.LinkedList until all other parts of your programm would be finished and tested and work as you wish. After that carefully replace it with your LinkedList implementation.
The set method in the LinkedIntList isn't adhering to the contract specified in the Javadoc. It says replace the element at the given index but I see code that adds a new Node.
Have a look at what methods the Node class provides to help you make the set method a lot easier and correct.
Take a good look at your get implementation. It does not do what you think.