Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
Long story short, I am in a university Comp Sci class, and the Professor wants us to build a Vector but from scratch. Are their any good tutorials on the web for something like this? I did a Google search but nothing really came up.
EDIT
According to the document the teacher gave out the vector needs to be able to do the following:
append(Object element) – appending the element at the end of the vector
clear() – make the vector collection empty
contains(Object element) – check whether the vector contains the element
elementAt(int index) – access the element at the given index
indexOf(Object element) – find the index of the element
insertAt(int index, Object element) – insert the element at the given index
isEmpty() – check whether the vector is empty
removeAt(int index) – remove the element at the given index
remove(Object element) – remove the element from the vector
replace(int index, Object element) – replace the element at the given index with the given element
size() – get the number of elements in the current vector
ensureCapacity(int minCapacity) – make sure the vector gets at least the given capacity
clone() – returns a cloned copy of this vector
removeRange(int fromIndex, int toIndex) – removes from this vector all of the elements whose index is between fromIndex, inclusive and toIndex, exclusive
toString() – returns a string representation of this vector, containing the String representation of each element
reverse() – reverse the elements in this vector
merge(MyVector vector2) – add all the elements in vector2 to the end of this vector
Additionally the class needs to implment Cloneable and be self expanding.
This is what I have come up with so far:
package collection;
public class MyVector implements Cloneable {
protected Object[] items;
protected int arraySize;
protected int maxCap;
public MyVector (int initialCapacity) {
super();
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
this.items = new Object[initialCapacity];
this.arraySize = 0;
this.maxCap = initialCapacity;
}
public MyVector() {
this(10);
}
public void append(Object element) {
int newArraySize = this.arraySize + 1;
if(this.maxCap == newArraySize) {
this.items = this.increaseCap(newArraySize);
this.items[this.arraySize] = element;
this.arraySize += 1;
//System.out.println(this.items[this.arraySize);
} else {
this.items[this.arraySize] = element;
this.arraySize +=1;
}
}
#Override
public String toString() {
String output = "[";
//output = this.items[0].toString();
for(int i = 0; i < this.arraySize; i++) {
output += this.items[i] + ", ";
}
output += "]";
return output;
}
public void clear() {
for(int i = 0; i < this.arraySize; i++) {
this.items[i] = null;
this.arraySize = 0;
}
}
public boolean contains(Object element) {
boolean doesContain = false;
for(int i = 0; i < this.arraySize; i++) {
if(element == this.items[i]) {
doesContain = true;
i = this.arraySize;
}
}
return doesContain;
}
public Object elementAt(int index) {
if(this.arraySize >= index) {
return this.items[index];
} else {
Object temp = null;
System.out.println("No index of " + index);
return temp;
}
}
public Object indexOf(Object element) {
Object index = "No value found";
for(int i = 0; i < this.arraySize; i++) {
if(element == this.items[i]) {
index = i;
break;
}
}
return index;
}
public boolean isEmpty() {
if(this.arraySize == 0) {
return true;
}
return false;
}
public void replace(int index, Object element) {
if(this.arraySize > index) {
this.items[index] = element;
} else {
System.out.println("No element at " + index);
}
}
public int size() {
return this.arraySize;
}
public void reverse() {
Object[] temp = new Object[this.items.length];
int j = this.arraySize;
for(int i = 0; i < this.arraySize; i++) {
temp[j] = this.items[i];
j--;
}
this.items = temp;
}
public void ensureCapacity(int minCapacity) {
if(minCapacity > this.items.length) {
this.items = this.increaseCap(minCapacity);
}
}
public Object[] increaseCap(int minCap) {
Object[] arr1 = new Object[minCap * 2];
for(int i = 0; i < minCap; i++) {
arr1[i] = this.items[i];
}
this.maxCap = this.maxCap * 2;
return arr1;
}
#Override
public Object clone() {
return this.items;
}
public boolean checkIndex(int index) {
boolean check = false;
if(index < this.arraySize) {
check = true;
}
return check;
}
public void removeAt(int index) {
if(true == this.checkIndex(index)) {
Object[] temp = new Object[this.arraySize - 1];
for(int j = 0; j < index; j++) {
temp[j] = this.items[j];
}
for(int j = index + 1; j < this.arraySize; j++) {
temp[j-1] = this.items[j];
}
this.items = temp;
this.arraySize = this.arraySize - 1;
}
}
public void insertAt(int index, Object element) {
if (this.checkIndex(index) == true) {
Object[] temp = new Object[this.arraySize];
for(int i = index; i < this.arraySize; i++) {
temp[i+1] = this.items[i];
}
this.items[index] = element;
for (int i = index + 1; i < this.arraySize; i++) {
this.items[i] = temp[i - 1];
}
this.arraySize = this.arraySize - 1;
}
}
public void remove(Object element) {
for(int i = 0; i < this.items.length; i++) {
if(this.items[i] == element) {
this.removeAt(i);
}
}
}
public void removeRange(int fromIndex, int toIndex) {
for(int i = fromIndex; i < toIndex; i++) {
this.removeAt(i);
}
}
public void merge(MyVector vector2) {
this.ensureCapacity(vector2.size() + this.arraySize);
for(int i = 0; i < vector2.size(); i++) {
this.append(vector2);
}
}
}
Assuming your assignment is replicating java.util.Vector, I would look at what a Vector is in order to replicate it:
Vector implements a dynamic array. It is similar to ArrayList, but
with two differences:
Vector is synchronized.
Vector contains many legacy methods that are not part of the collections framework.
You could attempt to use an ArrayList in a synchronous manner in order to replicate a Vector, but I'm sure there are much better solutions.
Related
I have generated a minheap to this file but I think something I have missed but I can't identify what are the things I have missed. I have missed something on --private void bubbleDown() { }-- section but I can't find what are the things missed by me.
private int default_size = 100; // how big the heap should be
private T[] array;
private int size;
public Heap() {
#SuppressWarnings("unchecked")
T[] tmp = (T[]) (new Comparable[default_size]);
array = tmp;
size = 0;
}
boolean isRoot(int index) { return (index == 0); }
int leftChild(int index) { return 2 * index + 1; }
int parent(int index) { return (index - 1) / 2; }
int rightChild(int index) { return 2 * index + 2; }
T myParent(int index) { return array[parent(index)]; }
T myLeftChild(int index) { return array[leftChild(index)]; }
T myRightChild(int index) { return array[rightChild(index)]; }
boolean hasLeftChild(int i) { return leftChild(i) < size-1; }
boolean hasRightChild(int i){ return rightChild(i) < size-1; }
private void swap(int a, int b) {
T tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
public boolean isEmpty() { return (size == 0); }
/* adding heap */
public void add(T value) {
if(size == default_size) throw new IllegalStateException("Full array");
array[size++] = value;
bubbleUp();
}
public void bubbleUp() {
if(size == 0) throw new IllegalStateException("Shape error");
int index = size - 1;
while(!isRoot(index)) {
if(myParent(index).compareTo(array[index]) <= 0) break;
/* else part */
swap(parent(index), index);
index = parent(index);
}
}
/* removing */
public T remove() {
if(isEmpty()) return null;
T res = array[0]; /* root */
array[0] = array[size-1];
size --;
bubbleDown();
return res;
}
// i think this section having wrong something
private void bubbleDown() {
int parent = 0;
int leftChild = 2*parent + 1;
int rightChild = 2*parent + 2;
int choice = compareAndPick(leftChild, rightChild);
while (choice != -1)
{
swap(choice, parent);
parent = choice;
choice = compareAndPick(2*choice+1, 2*choice+2);
}
}
private int compareAndPick(int leftChild, int rightChild)
{
if (leftChild >= default_size || array[leftChild] == null) return -1;
if (array[leftChild].compareTo(array[rightChild]) <= 0 || (array[rightChild] == null))
return leftChild;
return rightChild;
}
public void show() {
for(int i=0; i<size; i++)
System.out.print(array[i] + " ");
System.out.println("=======");
}
public static void main(String [] args) {
Heap<Integer> heap = new Heap<Integer>();
for(int i=0; i<10; i++) {
heap.add((Integer)(int)(Math.random() * 100));
heap.show();
}
System.out.println("You should see sorted numbers");
while(!heap.isEmpty()) {
System.out.print(heap.remove());
System.out.print(" ");
heap.show();
}
System.out.println();
}
}
this code used generics and min heap functions.. i need to identify what is the wrong thing did by me on bubbleDown() section
Explanation
The bubbleDown() method is not a different way to insert a node and move it to it's correct position in the Heap. When bubbleDown() is called it's job is to Heapify the Binary Tree from any state. So your attempt to write the method just by changing the condition from the bubbleUp() method isn't gonna help you.
Extra
Here is a video that can give you the idea of how bubbleDown is supposed to work.
public class ourStack1 {
private int elements[];
private int index; // indicate the next position to put a new data
private int size;
public ourStack1() {
elements = new int[10];
index = 0;
size = 0;
}
public void push(int value) {
if(size == 10) {
System.out.println("Stack is full, no push");
return;
}
elements[index] = value;
++index;
++size;
}
public int pop() {
if(size == 0) {
System.out.println("Stack is empty, no pop");
return -1;
}
int temp = elements[index - 1];
--index;
--size;
return temp;
}
public int peek() {
if(size == 0) {
System.out.println("Stack is empty, no peek");
return -1;
}
return elements[index - 1];
}
/*
public int mySize() {
// you know how to do this
}
*/
public static void main(String[] args) {
ourStack1 x = new ourStack1();
for(int i = 0; i < 10; ++i)
x.push(i);
for(int i = 0; i < 10; ++i)
System.out.println(x.pop());
}
}
I'm confused on how to overwrite the last element added to the full stack. I want to add element to replace the last element while not exceeding the array size[10]
public void replaceLast(int value) {
if (this.size > 0) {
this.pop();
}
this.push(value);
}
This is my Queue class. I have implemented it using arrays.
public class QueueUsingArray {
private int data[];
private int firstElementIndex;
private int nextElementIndex;
private int size;
public QueueUsingArray() {
data = new int[10];
firstElementIndex = -1;
nextElementIndex = 0;
size = 0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size() == 0;
}
private void checkEmpty() throws QueueEmptyException {
if (size == 0) {
QueueEmptyException e = new QueueEmptyException();
throw e;
}
}
public int front() throws QueueEmptyException {
checkEmpty();
return data[firstElementIndex];
}
public int dequeue() throws QueueEmptyException {
checkEmpty();
int output = data[firstElementIndex];
size--;
data[firstElementIndex] = 0;
firstElementIndex = (firstElementIndex + 1) % data.length;
if (size == 0) {
firstElementIndex = -1;
nextElementIndex = 0;
size = 0;
}
return output;
}
public void enqueue(int element) {
if (size == data.length) {
int[] temp = data;
data = new int[data.length * 2];
int k = 0;
for (int i = firstElementIndex; i < temp.length; i++) {
data[k] = temp[i];
k++;
}
for (int i = 0; i < firstElementIndex; i++) {
data[k] = temp[i];
k++;
}
firstElementIndex = 0;
nextElementIndex = temp.length;
}
if (size == 0) {
firstElementIndex = 0;
}
data[nextElementIndex] = element;
size++;
nextElementIndex = (nextElementIndex + 1) % data.length;
}
}
Here is my QueueUse class.
public class QueueUse {
public static void main(String[] args) throws QueueEmptyException {
QueueUsingArray q=new QueueUsingArray();
q.enqueue(10);
q.enqueue(20);
q.enqueue(30);
q.enqueue(40);
q.enqueue(50);
q.enqueue(60);
q.enqueue(70);
q.enqueue(80);
q.enqueue(90);
q.enqueue(100);
q.enqueue(110);
q.enqueue(120);
q.enqueue(130);
q.enqueue(140);
q.enqueue(150);
q.enqueue(160);
q.enqueue(170);
q.enqueue(180);
q.enqueue(190);
q.enqueue(200);
q.enqueue(210);
q.enqueue(220);
q.enqueue(230);
q.enqueue(240);
q.enqueue(250);
q.enqueue(260);
q.enqueue(270);
q.enqueue(280);
q.enqueue(290);
q.enqueue(300);
System.out.println("All elements");
for(int i=0;i<q.size();i++){
try {
System.out.println(q.dequeue());
} catch (QueueEmptyException e) {
System.out.println("Sorry");
}
}
}
}
My output is not complete. Output is not showing all the elements in my queue. What is the error. Output is only showing until 140 and not beyond that.
Your print method does not work because you decrement the size every time you invoke your dequeue() method in the for loop. If you are going to use a for loop you should be using a fixed size. Basically in this statement ( i < q.size() ) as i grows size decreases. If i = 0 and size = 4 the first loop i would be 1 and size would be 3. Your never going to get to the 0th or 1st element in your queue because by the next loop your already at i = 2 and size = 3.
first you should add a getter for the queue items
public int getElementAt(int index){
return data[index];
}
then you can call the method in the for loop for every index in data
int length = q.size();
for(int i = 0; i < length; i++){
System.out.println(q.getElementAt(i));
}
If it is not mandatory to do an array implementation, I would suggest using the Vector class because it has a better API for a queue. I would also suggest slowly tracing your program every time you have issues and to start with smaller test data sets to make tracing a easier.
public class Queue {
private Vector<String> data ;
Queue(){
data = new Vector();
}
public void enqueue(String item){
data.add(item);
}
public void dequeue(){
data.remove(0);
}
public void printQueueItems(){
int length = data.size();
for(int i = 0; i < length; i++){
System.out.println(data.get(i));
}
}
public static void main(String[] args) {
Queue myQ = new Queue();
myQ.enqueue("hello");
myQ.enqueue("world");
myQ.enqueue("!");
myQ.printQueueItems();
}
}
So i am trying to make an array based generic heap that i can use with my tester class. Much of what i have is based of my understandings of trees and some research online as well as from my textbook; both which have very limited info on what i am looking for. However, i did manage to get all the methods in need and when i run it, i get this error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at q1.Heaps.<init>(Heaps.java:23)
at q1.createGui.<init>(Gui.java:46)
at q1.Gui.main(Gui.java:18)
Im guessing it has to do with how i declare and initialize my Comparable array, which i am having trouble figuring out how to.
package q1;
import java.util.Arrays;
public class Heaps<E extends Comparable<E>> {
Comparable[] data;
int size;
/**
* Constructor with s as size
*/
#SuppressWarnings("unchecked")
public Heaps(int s) {
size = 0;
data = (E[]) new Object[s];
}
/**
* Adds a value to the heap
*/
public void add(E value) {
if (full()) // expand array
ensureCapacity(2*size);
size++;
data[size] = value;
if (size > 1)
heapifyUp();
}
/**
* Checks if the array is full
*/
private boolean full()
{
return (size == data.length-1);
}
private void heapifyUp()
{
Comparable<E> temp;
int next = size;
while (next != 1 && data[next].compareTo(data[next/2]) > 0)
{
temp = data[next];
data[next] = data[next/2];
data[next/2] = temp;
next = next/2;
}
}
private void heapifyDown()
{
Comparable<E> temp;
int next = 0;
while (next*2 <= size) // node has a child
{
int child = 2*next; // left child
if (child < size &&
data[child].compareTo(data[child+1]) > 0)//left smaller than right
child++; // right child instead
if (data[next].compareTo(data[child]) > 0)
{
temp = data[next];
data[next] = data[child];
data[child] = temp;
next = child;
}
else;
next = size; // stop loop
}//end while
}
/**
* Removes all occurrence of element
*/
public boolean removeAll(E element) {
if (contains(element) && !(isEmpty())){
for (int i = 0; i < size; i++){
if(element.equals(data[i])){
data[i] = data[size-1];
}
heapifyDown();
}
return true;
}
return false;
}
/**
* Removes 1st occurrence of element
*/
public boolean remove(E element) {
if (contains(element) && !(isEmpty())){
for (int i = 0; i < size; i++){
if(element.equals(data[i])){
data[i] = data[size-1];
heapifyDown();
return true;
}
}
}
return false;
}
public boolean isEmpty() {
return size == 0;
}
public Comparable<E>[] ensureCapacity(int s) {
return Arrays.copyOf(data, 2*s);
}
/**
* Converts the heap into its String representation.
* #return the String representation
*/
public Comparable<E>[] iteratorPreOrder()
{
Comparable<E>[] temp = (E[]) new Object[size];
temp[0] = data[0];
int i = 1;
int count = 1;
while(data[2*i] != null){
temp[count] = data[2*i];
++i;
++count;
}
i = 1;
while(data[(2*i) +1] != null){
temp[count] = data[(2*i) +1];
++i;
++count;
}
return temp;
}
public int countOccurance(E element){
int count = 0;
for (int i =0; i < size; i++){
if(element.equals(data[i])){
count++;
}
}
return count;
}
public boolean contains (E element)
{
for (int i=0; i<size; i++){
if (element.equals(data[i])){
return true;
}
}
return false;
}
}
If you could please show me how i would solve this problem, i would greatly appreciate it. Thanks
EDIT: SO i edited the my class and now it works when i do data = (E[]) new Comparable[s]. So why does java not allow generic Array types, what makes it different from Arraylist, Stacks, Queues, and/or LinkedList which can be generic?
You are creating an Object[] and then trying to cast it to a Comprable[]. The compiler was telling you what you did wrong with the unchecked cast error.
You want data to be E[] data and the line to be:
data = new E[s];
Note: this could run into issues with how Java handles generics.
There seems to be a problem in add method of the class I have written.. I want to make a SortedList using an array, but I can't figure out what the problem is. This is my code:
public class SortedList {
private Integer[] elements;
private int size;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
cap = capacity;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el)
{
if(this.isEmpty())
{
elements[0] = el;
size++;
}
else if(this.isFull())
{
this.doubleCapacity();
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
else
{
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
}
public String toString()
{
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public static void main(String[] args)
{
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(4);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
}
}
My code works if I only add 2 Integers to my list, but when I try to add the numbers 3,4,5 then I get 3,5,5...
What can be the problem? Thanks..
public class SortedList {
private Integer[] elements;
private int size=0;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
capacity = cap;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el) throws Exception{
elements[size] = el;
size++;
if(size>capacity){
throw new Exception("Size Exceeded");
}
}
public String toString()
{
sort();
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public void sort(){
for (int i=0; i <size()-1; i++) {
if (elements[i] > elements[i+1]) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}
}
public static void main(String[] args)
{
try {
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(6);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
} catch (Exception ex) {
Logger.getLogger(SortedList.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Your insertion code doesn't work.
elements[i+1] = elements[i];
elements[i] = el;
What happens to the old value of elements[i+1]?
I'd recommend the following changes to the previous solution. If you're only calling sort in toString(), your list is going to get out of order quickly in cases where you have multiple unsorted elements in a row (Now you could remove sort() from toString()). It's essentially a quick insertion sort that dies as soon as it can't make any more swaps down the list. Again, as dty suggested, a faster choice would be a binary search to find the insertion point.
public void doubleCapacity(){
capacity = capacity * 2;
Integer temp[] = new Integer[capacity];
for (int i = 0; i < size; i++){
temp[i] = elements[i];
}
elements = temp;
}
public void add(Integer el){
if(size+1>capacity){
doubleCapacity();
}
elements[size] = el;
size++;
sort();
}
public void sort(){
//Iterates down the list until it's sorted.
for (int i=size()-2; i >= 0 && (elements[i] < elements[i+1]); i--) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}