Generic Codes and Comparator - java

This is generic array sort code.
I have no idea how to use setComparator that are in BubbleSort class and ArraySort. I keep getting an error about a "raw type" ...
Here is the full code:
package sortNumbers;
import java.util.Scanner;
import java.util.Random;
class sortNumbers
{
public static void main(String[] args)
{
int arrayLength = 4;
String chooseArray = "BubblesSort";
boolean asORds = true;
Integer[] arr = new Integer[4];
Random randomGen = new Random() ;
for(int i = 0; i<arrayLength; i++)
{
arr[i] = randomGen.nextInt(101);
}
intComparator ic = new intComparator(asORds);
BubbleSort bs = new BubbleSort(arr);
//bs.setComparator(ic);
}
}
interface Comparator<T>
{
public int compare(T a, T b);
}
class intComparator<T> implements Comparator<T>
{
boolean ascend;
public intComparator(boolean ascend) {
this.ascend = ascend;
}
public int compare(T a, T b)
{
int aA = (Integer)a;
int bB = (Integer)b;
//int temp;
int changePosition = 1;
if(this.ascend == false)
changePosition = -1;
/*if(this.ascend == false)
{
temp = aA;
aA = bB;
bB = temp;
}*/
if(aA == bB)
return 0*changePosition;
else if(aA < bB)
return -1*changePosition;
else
return 1*changePosition;
}
}
class strComparator<T> implements Comparator<T>
{
protected boolean ascend;
public strComparator(boolean ascend) {
this.ascend = ascend;
}
public int compare(T a, T b)
{
String aA = (String)a;
String bB = (String)b;
//int temp;
int changePosition = 1;
if(this.ascend == false)
changePosition = -1;
/*if(this.ascend == false)
{
temp = aA;
aA = bB;
bB = temp;
}*/
if(aA.compareTo(bB) == 0)
return 0*changePosition;
else if(aA.compareTo(bB) == -1)
return -1*changePosition;
else
return 1*changePosition;
}
}
class floatComparator<T> implements Comparator<T>
{
protected boolean ascend;
public floatComparator(boolean ascend)
{
this.ascend = ascend;
}
public int compare(T a, T b)
{
float aA = (Float)a;
float bB = (Float)b;
//int temp;
int changePosition = 1;
if(this.ascend == false)
changePosition = -1;
/*if(this.ascend == false)
{
temp = aA;
aA = bB;
bB = temp;
}*/
if(aA == bB)
return 0*changePosition;
else if(aA < bB)
return -1*changePosition;
else
return 1*changePosition;
}
}
abstract class ArraySort<T>
{
protected T[] inArray;
public ArraySort(T[] inArray)
{
this.inArray = inArray;
}
abstract public void iSort(T[] inArray);
abstract public T[] oSort(T[] inArray);
public void setComparator(Comparator<T> comparator)
{
}
}
class BubbleSort<T> extends ArraySort<T>
{
protected Comparator<T> forCompare;
public BubbleSort(T[] inArray)
{
super(inArray);
}
public void iSort(T[] inArray)
{
T temp;
for(int i = 0; i < inArray.length-1; i++)
{
for(int j=1; j<inArray.length-i; j++)
{
//int compared = compare(in)
if(forCompare.compare(inArray[j-1],inArray[j]) < 0)
// inArray[j-1] > inArray[j])
{
temp=inArray[j-1];
inArray[j-1] = inArray[j];
inArray[j] = temp;
}
}
}
if(inArray.length <= 10)
{
for(int i = 0; i <inArray.length; i++)
{
System.out.print(inArray[i] + " ");
}
System.out.println("");
}
}
public T[] oSort(T[] inArray)
{
T[] tempArray = (T[]) new Object[inArray.length];
//is this right way to creat generic type array?
for(int i = 0; i<tempArray.length; i++)
{
tempArray[i] = inArray[i];
}
T temp;
for(int i = 0; i < tempArray.length-1; i++)
{
for(int j=1; j<tempArray.length-i; j++)
{
if(forCompare.compare(tempArray[j-1],tempArray[j]) < 0)
{
temp=tempArray[j-1];
tempArray[j-1] = tempArray[j];
tempArray[j] = temp;
}
}
}
if(tempArray.length <= 10)
{
for(int i = 0; i <tempArray.length; i++)
{
System.out.print(tempArray[i] + " ");
}
System.out.println("");
}
return tempArray;
}
public void setComparator(Comparator<T> comparator) {
// How should I use this...please some o
}
}
In BubbleSort, oSort method, I am trying to create a new T array.
Is this the way to do it?
T[] tempArray = (T[]) new Object[inArray.length];

You're implementing your Comparators wrong. For example, your intComparator should be declared as:
class intComparator implements Comparator<Integer>
{
//...
public int compare(Integer a, Integer b)
{
...
}
}
Instantiating generics in Java is kind of tricky. Find out why and what options you have here.
Read more about generic types here.
FYI, remember that class names start with Uppercase letters.

Related

Created a class to print an array of generic objects but I get no output?

Basically it's a array list implementation and I need to time how long it takes to add elements to it, along with other features. I compiled it though and there's no output and I can't find the problem. I instantiate an array of objects in the class then defined a method add(E e) to add an element E using basic assignment. Then the ListDriver should populate the array using the add() method and print it, but again, no output.
public class MyArrayList<E> {
public Object array[];
public int size = 0;
private static final int INITIAL_CAPACITY = 100;
public MyArrayList() {
array = new Object[INITIAL_CAPACITY];
this.size = 0;
}
private boolean arrayFull() {
if (size == array.length)
return true;
else
return false;
}
private boolean remove(Object o) {
for (int i = 0; i < size; i++) {
if (array[i].getClass() == o.getClass()) {
remove(i);
return true;
}
}
return false;
}
private void resize(int i) {
if (i == 0) {
Object[] temp = new Object[array.length*2];
for (int j = 0; j < size; j++) {
temp[j] = array[j];
}
this.array = temp;
}
if (i == 1) {
Object[] temp = new Object[array.length/2];
for (int j = 0; j < size; j++) {
temp[j] = array[j];
}
this.array = temp;
}
}
public void add(E e) {
if (!arrayFull()) {
array[size] = e;
size++;
}
else if (arrayFull()) {
resize(0);
add(e);
}
}
public int size() {
return size;
}
private void clear() {
array = null;
}
private Object remove(int index) {
if (halfFull()) {
resize(1);
}
Object temp = array[index];
for (int i = index; i < size; i++) {
array[i] = array[i+1];
}
size--;
return temp;
}
private boolean halfFull() {
if (size < (array.length/4)) {
return true;
}
else return false;
}
public void add(int index, E element) {
if (!arrayFull()) {
for (int i = size-1 ; i >= index ; i--) {
array[i] = array[i+1];
}
array[index] = element;
size++;
}
else {
resize(0);
add(index, element);
}
}
public String toString() {
String list = new String();
for (int i = 0; i < size; i++) {
list += " " + array[i];
}
return list;
}
public static void main(String[] args) {
MyArrayList temp = new MyArrayList();
System.out.println(temp.size);
}
}
And the driver
public class ListTester {
public static void main(String[] args) {
int n = 100;
MyArrayList arrayList = new MyArrayList();
int[] array = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = (int)Math.random() *2*n +1;
}
long startTime = System.nanoTime();
for (int i = 0; i < arrayList.size(); i++) {
arrayList.add(array[i]);
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(arrayList);
System.out.println(duration);
}
}

Inapplicable method error regarding interfaces

I'm having an issue with one of my methods findLargest(Comparable[ ] arr) in class FindLargest that's meant to return the largest element in an array.
Apparently, in class Lab5Main this method works fine with fractions, but I get a compilation error with dates. In the system print out command, I'm getting this error:
The method findLargest(Comparable[ ]) in the type FindLargest is not applicable for the arguments (MyDate[ ])
Here is the supposed program output:
The largest fraction is 9/4
The latest date is 18/8/2011
My codes are shown below:
public class Lab5Main {
public static void main(String[] args) {
// Fraction
Fraction fractions[] = new Fraction[3];
fractions[0] = new Fraction(1, 2);
fractions[1] = new Fraction(6, 11);
fractions[2] = new Fraction(9, 4);
System.out.println("The largest fraction is " + FindLargest.findLargest(fractions));
// MyDate
MyDate dates[] = new MyDate[3];
dates[0] = new MyDate(1898, 6, 9);
dates[1] = new MyDate(2003, 4, 1);
dates[2] = new MyDate(2011, 8, 18);
System.out.println("The latest date is " + FindLargest.findLargest(dates));
}
}
public class FindLargest {
public static <T extends Comparable<? super T>> T findLargest(T[] arr) {
if (arr.length == 0) {
return null;
}
T max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i].compareTo(max) > 0) {
max = arr[i];
}
}
return max;
}
public class Fraction implements Comparable<Fraction> {
private int num, denom;
public int gcd(int a, int b) {
if (a%b==0) {
return b;
}
return gcd(b, a%b);
}
public void reduce() {
int g = gcd(num, denom);
num = num / g;
denom = denom / g;
}
public Fraction(int n, int d) {
if (n==0) {
d=1;
}
if (d==0) {
n=1;
d=2;
}
if(d<0) {
n=-n;
d=-d;
}
num = n;
denom = d;
reduce();
}
public String toString() {
return num + "/" + denom;
}
#Override
public int compareTo(Fraction f) {
// Fraction f = (Fraction) obj;
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
public int compareTo(Object obj) {
Fraction f = (Fraction) obj;
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
}
public class MyDate implements Comparable<MyDate> {
private int year, month, day;
public MyDate(int z, int y, int x) {
if (z<1000 || z>3000) {
z = 2000;
}
if (y<1 || y>12) {
y = 1;
}
if (x<1 || x>31) {
x = 1;
}
day = x;
month = y;
year = z;
}
public String toString() {
return day + "/" + month + "/" + year;
}
#Override
public int compareTo (MyDate date){
// MyDate date = (MyDate) obj;
int diffYear = year - date.year;
if (diffYear < 0) {
return -1;
}
else if (diffYear > 0) {
return 1;
}
int diffMonth = month - date.month;
if (diffMonth < 0) {
return -1;
}
else if (diffMonth > 0) {
return 1;
}
int diffDay = day - date.day;
if (diffDay < 0) {
return -1;
}
else if (diffDay > 0) {
return 1;
}
return 0;
}
}
The issue is one of raw-types and generics. Comparable is a generic interface, but you are implementing it with a raw-type and you are using it with raw-types. You should fix that. Something like,
public static <T extends Comparable<? super T>> T findLargest(T[] arr) {
if (arr.length == 0) {
return null;
}
T max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i].compareTo(max) > 0) {
max = arr[i];
}
}
return max;
}
will ensure that you call findLargest with a generic type T that can be compared with itself and all of its' superclasses. You should also change Fraction and MyDate. Something like,
public class Fraction implements Comparable<Fraction> {
// ...
#Override
public int compareTo(Fraction f) {
if (Math.abs(value() - f.value()) < 0.00001) {
return 0;
}
if (value() > f.value()) {
return 1;
}
return -1;
}
}
And MyDate similarly. I would recommend you always use the #Override annotation when you intend to override a method.

Max heap and Min heap implementation for median Java

I have to create an ADT to read a number of data and calculate the median of those data. The ADT consist in a MIN and a MAX heap.
The MinHeap class takes the numbers greaters or equal than the median.
public class MinHeap {
public double[] data;
public int Size;
public MinHeap(int size) {
data = new double[size];
Size = 0;
}
public double getMinimum(){
return this.data[0];
}
public boolean isEmpty() {
return (Size == 0);
}
private int getParentIndex(int nodeIndex) {
return (nodeIndex - 1) / 2;
}
public void insertu(double value) throws Exception {
if (Size == data.length)
throw new Exception("Heap's underlying storage is overflow");
else {
Size++;
data[Size - 1] = value;
siftUp(Size - 1);
}
}
public void siftUp(int nodeIndex) {
int parentIndex;
double tmp;
if (nodeIndex != 0) {
parentIndex = getParentIndex(nodeIndex);
if (data[parentIndex] > data[nodeIndex]) {
tmp = data[parentIndex];
data[parentIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftUp(parentIndex);
}
}
}
}`
The MaxHeapclass takes the numbers that are less or equal than the median.
public class MaxHeap{
public double [] _Heap;
public int _size;
public int tam=0;
public MaxHeap (int a){
_Heap = new double[a];
_size = _Heap.length;
for (int i = _Heap.length / 2 ; i >=0 ; i--) {
tam++;
maxHeapify(i);
}
}
private int parent(int pos)
{ return pos / 2; }
private int leftChild(int pos)
{ return (2 * pos); }
private int rightChild(int pos)
{ return (2 * pos) + 1; }
private void swap(int fpos,int spos) {
double tmp;
tmp = _Heap[fpos];
_Heap[fpos] = _Heap[spos];
_Heap[spos] = tmp;
}
private void maxHeapify (int i) {
int l = leftChild(i), r = rightChild(i), largest;
if(l < _size && _Heap[l] > _Heap[i]) {
tam+=2;
largest = l;
}
else largest = i;
if(r < _size && _Heap[r] > _Heap[largest]) {
largest = r;
tam+=2; }
if (largest != i) {
tam++;
swap(i, largest);
maxHeapify (largest); }
}
protected boolean isEmpty() { return _size == 0; }
protected void deleteMax() {
if (_size > 1) {
tam++;
maxHeapify(0);
double max = _Heap[0];
_size--;
swap(0, _size);
maxHeapify(0); }
else _size = 0;
}
protected double extractMax() {
maxHeapify(0);
return _Heap[0];
}
public void insert(double element)
{
_Heap[++tam] = element;
int current = tam;
while(_Heap[current] > _Heap[parent(current)])
{
swap(current,parent(current));
current = parent(current);
}
}
}`
And the ADT:
`import java.util.InputMismatchException;`
`import java.util.Scanner;`
public class ColaPrioridadMediana {
private MinHeap MIN;
private MaxHeap MAX;
private int size;
public ColaPrioridadMediana(int cap) {
if (cap%2==0){
MIN = new MinHeap(cap/2);
MAX = new MaxHeap(cap/2);
}
else{
MIN = new MinHeap((cap+1)/2);
MAX = new MaxHeap((cap+1)/2);
}
size = MAX.counter + MIN.Size;
}
public void insertar(double x) throws Exception{
if (x <= MAX.extractMax()){
if (MAX.counter > MIN.Size){
double d = MAX.extractMax();
MIN.insertu(d);
MAX.insert(x);
}
else{
MAX.insert(x);
}
}
else{
if (MIN.Size > MAX.counter){
double d = MIN.getMinimum();
MAX.insert(d);
MIN.data[0] = x;
MIN.siftUp(1);
}
else{
MIN.insertu(x);
}
}
}
public int getSize(){
return size;
}
public double getMediana() throws Exception{
if(MAX.counter==MIN.Size){return ((MAX.extractMax()+MIN.getMinimum())/2);}
else{
if (MAX.counter<MIN.Size){return MIN.getMinimum();}
else{return MAX.extractMax();}
}
}
public static void main(String[] args) throws NumberFormatException, Exception{
#SuppressWarnings("resource")
Scanner num=new Scanner(System.in);
ColaPrioridadMediana allNumbers=new ColaPrioridadMediana(10);
while(true){
System.out.print("Number:");
try{
String number=num.nextLine();
double d;
if(!number.isEmpty()){
allNumbers.insertar(Double.parseDouble(number));
}else{
d = allNumbers.getMediana();
System.out.println("The result is " + d);
System.out.println(allNumbers.MAX.extractMax());
System.out.println(allNumbers.MIN.getMinimum());
System.out.println(allNumbers.MAX.counter);
System.out.println(allNumbers.MIN.Size);
for (int i=0;i<allNumbers.MAX._Heap.length;i++){
System.out.println(allNumbers.MAX._Heap[i]);
System.out.println(allNumbers.MIN.data[i]);
}
System.exit(0);
}
}
catch(InputMismatchException e){
System.out.println("Not number");
}
}
}
}`
The MinHeap works, but the MaxHeap don't store any numbers, and prints only 0.0. I'm really stuck in here.
In java, using the Java Standard class PriorityQueue to simulate Max-Min heap is not a bad idea. It will reduce coding significantly.
public class MaxMinHeap{
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((x,y)->(y-x));
private void add(int val) {
if (maxHeap.size() == 0) {
maxHeap.add(val);
} else {
int maxTop = maxHeap.peek();
if (val <= maxTop) {
maxHeap.add(val);
} else {
minHeap.add(val);
}
if (maxHeap.size() - minHeap.size() > 1) {
minHeap.add(maxHeap.poll());
} else if (minHeap.size() - maxHeap.size() > 1) {
maxHeap.add(minHeap.poll());
}
}
}
private double findMedian() {
if(maxHeap.size() > minHeap.size()) {
return maxHeap.peek();
}else if(maxHeap.size() == minHeap.size()) {
return ((double) maxHeap.peek() + minHeap.peek()) / 2;
}else {
return minHeap.peek();
}
}
}

Displaying search results from a hash table

I can't figure out how to display the results from my search method. I put strings in where it needs to display the results.
Here is the client class
public class Client
{
private String name;
private String city;
public Client(String name, String city)
{
this.name = name;
this.city = city;
}
public String toString()
{
return name + " " + city;
}
public String getName()
{
return name;
}
public String getCity()
{
return city;
}
}
Here is my Hashtable class
public class Hashtable {
private int n;
private Client[] table;
public Hashtable(int n) {
this.n = n;
table = new Client[n];
}
public int hashFunction(String key) {
int sum = 0;
for (int i = 0; i < key.length(); i++) {
sum += (int) key.charAt(i);
}
sum = sum%n;
return sum;
}
public String search(String key) {
int sum = 0;
for (int i = 0; i < key.length(); i++) {
sum += (int) key.charAt(i);
}
sum = sum%n;
if (key.equals(table[sum])) {
return ("Returns the toString from the client class here");
} else if (table[sum] == null) {
return null;
} else {
while (table[sum] != null) {
sum++;
}
return ("Returns the toString from the client class here");
}
}
public boolean insert(Client myClient) {
int counter = 0;
String temp = myClient.getName();
boolean ret = false;
int tempSum = 0;
for (int i = 0; i < temp.length(); i++) {
tempSum += (int) temp.charAt(i);
}
tempSum = tempSum%n;
if (table[tempSum] == null) {
table[tempSum] = myClient;
ret = true;
} else {
while (table[tempSum] != null) {
if(tempSum == table.length){
tempSum = -1;
}
tempSum++;
counter++;
}
if(counter != n){
ret = true;
table[tempSum] = myClient;
}
}
return ret;
}
}
When you are comparing the key in search method, Make sure you compare against name.
Change table[sum] to table[sum].getName() ???? I modified the code and added comments for the change.
public class Hashtable {
private int n;
private Client[] table;
public Hashtable(int n) {
this.n = n;
table = new Client[n];
}
public int hashFunction(String key) {
int sum = 0;
for (int i = 0; i < key.length(); i++) {
sum += (int) key.charAt(i);
}
sum = sum%n;
return sum;
}
public String search(String key) {
int sum = 0;
for (int i = 0; i < key.length(); i++) {
sum += (int) key.charAt(i);
}
sum = sum%n;
if (key.equals(table[sum].getName())) { //This Should be table[sum].getName()
return ("Returns the toString from the client class here");
} else if (table[sum] == null) {
return null;
} else {
while (table[sum] != null) {
sum++;
}
return ("Returns the toString from the client class here");
}
}
public boolean insert(Client myClient) {
int counter = 0;
String temp = myClient.getName();
boolean ret = false;
int tempSum = 0;
for (int i = 0; i < temp.length(); i++) {
tempSum += (int) temp.charAt(i);
}
tempSum = tempSum%n;
if (table[tempSum] == null) {
table[tempSum] = myClient;
ret = true;
} else {
while (table[tempSum] != null) {
if(tempSum == table.length){
tempSum = -1;
}
tempSum++;
counter++;
}
if(counter != n){
ret = true;
table[tempSum] = myClient;
}
}
return ret;
}
}
Let me know if that helped

Odd return on PEMDAS calculator

It seems that this calculator works for all other cases, except cases like this:
(2*3^4)
It does not return 162, instead, it returns 0.0.
I identified that the error must be from the method public static double operation, since the default return statement is 0.0
Here is the code:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class StackC<Item> implements Stack<Item> {
private Item[] a; // array of items
private int N; // number of elements on stack
public StackC() {
a = (Item[]) new Object[2];
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
private void resize(int capacity) {
assert capacity >= N;
Item[] temp = (Item[]) new Object[capacity];
for (int i = 0; i < N; i++) {
temp[i] = a[i];
}
a = temp;
}
public void push(Item item) {
if (N == a.length) resize(2*a.length); // double size of array if necessary
a[N++] = item; // add item
}
public Item pop() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
Item item = a[N-1];
a[N-1] = null; // to avoid loitering
N--;
// shrink size of array if necessary
if (N > 0 && N == a.length/4)
resize(a.length/2);
return item;
}
public Item peek() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
return a[N-1];
}
public Iterator<Item> iterator() {
return new ReverseArrayIterator();
}
private class ReverseArrayIterator implements Iterator<Item> {
private int i;
public ReverseArrayIterator() {
i = N;
}
public boolean hasNext() {
return i > 0;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
return a[--i];
}
}
//---------------------------------------------------------------------
public static void main(String[] args) {
StackC<String> Operator = new StackC<String>();
StackC<Double> Values = new StackC<Double>();
while (!StdIn.isEmpty()) {
String token = StdIn.readString();
try {
Double x = Double.parseDouble(token);
Values.push(x);
}
catch(NumberFormatException nFE) {
}
if (token.equals("("))
Operator.push(token);
if (token.equals(")"))
{
if (Operator.peek() != "(")
{
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
Operator.pop();
}
if(token.equals("*") || token.equals("+") || token.equals("/") || token.equals("-") || token.equals("^") )
{
if(!Operator.isEmpty())
{
String prev = Operator.peek();
int x = comparePrecedence(token, Operator.peek()); // You need to compare precedence first
if(x == -1 || x == 0)
{
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
}
Operator.push(token);
}
}
while(!Operator.isEmpty())
{
String prev = Operator.peek();
String type = Operator.pop();
double b = Values.pop();
double a = Values.pop();
Values.push(operation(type,a,b));
}
System.out.println(Values.pop());
}
public static double operation(String operator, double a, double b) {
if (operator.equals("+"))
return a + b;
else if (operator.equals("-"))
return a - b;
else if (operator.equals("*"))
return a * b;
else if (operator.equals("/"))
return a / b;
else if (operator.equals("^"))
return Math.pow(a,b);
return 0.0;
}
public static int comparePrecedence(String x, String y)
{
int val1 = 0;
int val2 = 0;
if(x.equals("-"))
val1 = 0;
if(y.equals("-"))
val2 = 0;
if(x.equals("+"))
val1 = 1;
if(y.equals("+"))
val2 = 1;
if(x.equals("/"))
val1 = 2;
if(y.equals("/"))
val2 = 2;
if(x.equals("*"))
val1 = 3;
if(y.equals("*"))
val2 = 3;
if(x.equals("^"))
val1 = 4;
if(y.equals("^"))
val2 = 4;
if(val1 > val2)
return 1;
else if(val2 > val1)
return -1;
else
return 0;
}
}
Everything above the dotted line was given via the professor, and is not the problem for the code.
StdIn is simply a method that reads inputs.

Categories