I want to shift the elements in the array in a queue style.
I did this code:
public class Queue {
private int[] elements;
private int size;
public static final int DefCap = 8;
public Queue() {
this(DefCap);
}
public Queue(int capacity) {
elements = new int[capacity];
}
public int[] enqueue(int v) {
if (size >= elements.length) {
int[] a = new int[elements.length * 2];
System.arraycopy(elements, 0, a, 0, elements.length);
elements = a;
}
elements[size++] = v;
return elements;
}
public int dequeue() {
return elements[--size];
}
public boolean empty() {
return size == 0;
}
public int getSize() {
return size;
}
}
How can I shift the numbers in the array where the next number added pushes the last one?
because all it does now is removes the last one added (Stacking).
First, remember that it doesn't matter at all how you add or retrieve the elements as long as it appears that the operation reflects that of a queue (i.e. FIFO). The internals of your implementation are of no concern to the user(s). The easiest method (imo) is to add them normally to the end and "remove" them from the beginning.
When you add the new element, do it like you are already doing it.
When you remove the first element, do it virtually by using an index.
int nextIdx = 0; // initialize start of queue
...
...
public int next() {
if (nextIdx < elements.length) {
return elements[nextIdx--];
}
// indicate an error by throwing an exception
}
At some point you are going to want to reclaim the "non-existent" elements at the beginning of the queue and then reset nextIdx. You can do this when you need to resize the array. You can use System.arraycopy and make use of both the value of nextIdx and the new desired new size to resize the array and copy the remaining elements.
Note: In your enqueue method I'm not certain why you want to return the entire element array when you add an element. I would expect something like returning the element just added, a boolean indicating success, or not return anything.
Related
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 4 years ago.
I am running into conversion errors with Generics. I can provide the full code if needed but I feel like I am missing something really simple. I am attempting to use a method inside of my class to add all elements of input list to current list, but I am getting conversion errors for E.
Can somebody please point me in the right direction as to what I need to be doing? - I am not new to programming, but Java isn't my first language.
public class ArrayList<E> implements List<E> {
// instance variables
/** Default array capacity. */
public static final int CAPACITY=16; // default array capacity
private E[] data; // generic array used for storage
private int size = 0; // current number of elements
public ArrayList() { this(CAPACITY); } // constructs list with default capacity
#SuppressWarnings({"unchecked"})
public ArrayList(int capacity) { // constructs list with given capacity
data = (E[]) new Object[capacity]; // safe cast; compiler may give warning
}
// public methods
public int size() { return size; }
public boolean isEmpty() { return size == 0; }
public E get(int i) throws IndexOutOfBoundsException {
checkIndex(i, size);
return data[i];
}
public void add(int i, E e) throws IndexOutOfBoundsException {
checkIndex(i, size + 1);
if (size == data.length) // not enough capacity
resize(2 * data.length); // so double the current capacity
for (int k=size-1; k >= i; k--) // start by shifting rightmost
data[k+1] = data[k];
data[i] = e; // ready to place the new element
//print(data[i].getClass());//STRING BASED ON CURRENT TEST CODE
size++;
}
//-------ERROR CODE
public void addAll(ArrayList l){
//Adds all elements in l to the end of this list, in the order that they are in l.
//Input: An ArrayList l.
//Output: None
//Postcondition: All elements in the list l have been added to this list.
//add(int i, E e)
//l IS ALSO AN ARRAY LIST SO SAME METHODS/VARIABLES APPLY...JUST REFERENCE l'S VERSION
//add(0,"hi");//ERROR NOT E
int foundSize = l.size();
//print(foundSize);
print("SIZE:"+size);
print("LENGTH:"+data.length);//TOTAL
for (int i=0; i < foundSize; i++){
//print(data[i]);
this.add(size(), l.get(i));//INCOMPATIBLE TYPES
}
}
//-------ERROR CODE
You are passing a raw ArrayList to your addAll method.
Change
public void addAll(ArrayList l)
to
public void addAll(ArrayList<E> l)
I am creating a class that has an array, and I want to implement methods add, remove, and replace.
But I don't want to use any built-in internals.
public class MySet {
public int set[];
private int size = 0;
public MySet(int size) {
this.set = new int[size];
}
public boolean add(int item) {
for (int i = 0; i < this.size(); i++) {
if (this.set[i] != 0) {
// add to array
}
}
this.size++;
return true;
}
public int size()
{
return this.size;
}
}
When you initialize an array with a fixed size in Java, each item is equal to 0. The part with if this.set[i] != 0 is where I am stuck to add an item.
Should I use a while loop with pointers? Such as:
public boolean add(int item) {
int index = 0;
while (index <= this.size()) {
if (this.set[index] != 0 || index <= ) {
// increase pointer
index++;
}
this.set[index] = item;
}
But if I have an array such as [7, 2, 0 , 1] in the list, it won't get the last item in the loop, which I need.
So, how is this usually done?
You should keep the current index for the size of populated elements which looks like you do. When you add the set[size]= item and increment size. Once size hits the preallocated size of your array you need to create a new array with increased size (can pick double the size for example) and copy old array to the new one.
I have a Point object that just has an x and y, and I have a Heap data structure that looks like so:
class MaxHeap{
public Point[] heap;
public int size;
public int maxsize;
public MaxHeap(int maxsize){
this.maxsize = maxsize;
this.size = 0;
heap = new Point[this.maxsize+1];
heap[0] = new Point(-1,-1); //Heap is empty
}
public int parent(int pos){
return pos /2;
}
public int leftChild(int pos){
return (2 * pos);
}
public int rightChild(int pos){
return (2 * pos) +1;
}
public boolean isLeaf(int pos){
if (pos >= (size / 2) && pos <= size){
return true;
}
return false;
}
public void swap (int fpos, int spos){
Point tmp;
tmp = heap[fpos];
heap[fpos] = heap[spos];
heap[spos] = tmp;
}
public void maxHeapify(int pos){
if (!isLeaf(pos)){
if (heap[pos].getY() < heap[leftChild(pos)].getY() || heap[pos].getY() < heap[rightChild(pos)].getY()){
swap(pos, leftChild(pos));
maxHeapify(leftChild(pos));
}
else{
swap(pos, rightChild(pos));
maxHeapify(rightChild(pos));
}
}
}
public void insert (Point p){
heap[++size] = p;
int current = size;
while (heap[current].getY() > heap[parent(current)].getY()){
swap(current, parent(current));
current = parent(current);
}
}
I am trying to implement a way to remove any Point from the Heap, instead of the traditional remove where it just removes the top. I'm not entirely sure how to go about doing this. I was thinking I could store the index of the Point in the heap inside of the Point. I'm not sure if this would help or not.
Just is case, are you aware that there is standard heap implementation in Java called PriorityQueue? You can use it as the reference of how removeAt(int i) is implemented.
Back to your question.
In order to remove intermediate element from the queue, you need to replace it with the last element of the queue (shrinking the queue by one element) and try to "heapify" this element down. If element is still in place (both children were bigger than the element) you need to "heapify" it up.
Regarding second part of your question. I'd not recommend storing queue indices inside Point class and hence making points queue-aware. The better way is to maintain Map from point to its index inside the queue (this map can be represented by IdentityHashMap[Point, Integer]). Just don't forget to make appropriate changes in this map when you are making changes in the queue, such as inserting, removing elements, swapping them and so on.
this is an anwser :
public void removeSpecificElement(int i) {
heap[i] = heap[size];
size--;
while (getParent(i) < heap[i] && i > 1 ) {
swapElements(heap[i], getParent(i));
i = getParent(i);
}
heapifyUp(i);
}
// Queue.java
// demonstrates queue
// to run this program: C>java QueueApp
class Queue
{
private int maxSize;
private long[] queArray;
private int front;
private int rear;
private int nItems;
public Queue(int s) // constructor
{
maxSize = s;
queArray = new long[maxSize];
front = 0;
rear = -1;
nItems = 0;
}
public void insert(long j)
{
if(rear == maxSize-1)
rear = -1;
queArray[++rear] = j;
nItems++;
}
public long remove()
{
long temp = queArray[front++];
if(front == maxSize)
front = 0;
nItems--;
return temp;
}
public long peekFront()
{
return queArray[front];
}
public boolean isEmpty() // true if queue is empty
{
return (nItems==0);
}
public boolean isFull() // true if queue is full
{
return (nItems==maxSize);
}
public int size() // number of items in queue
{
return nItems;
}
public void display()
{ int startFront = front;
for (int j = front ;j <nItems; j++ )
{
System.out.println(queArray[j]);
if (j == nItems-1 )
{ j=0;
System.out.println(queArray[j]);
}
if (j==startFront-1)
return;
}
}
}
class QueueApp
{
public static void main(String[] args)
{
Queue theQueue = new Queue(5); // queue holds 5 items
theQueue.insert(10); // insert 4 items
theQueue.insert(20);
theQueue.insert(30);
theQueue.insert(40);
theQueue.remove(); // remove 3 items
theQueue.remove(); // (10, 20, 30)
theQueue.remove();
theQueue.insert(50); // insert 4 more items
theQueue.insert(60); // (wraps around)
theQueue.insert(70);
theQueue.insert(80);
theQueue.display();
while( !theQueue.isEmpty() ) // remove and display
{ // all items
long n = theQueue.remove(); // (40, 50, 60, 70, 80)
System.out.print(n);
System.out.print(" ");
}
System.out.println("");
} // end main()
} // end class QueueApp
Okay, this is the basic, out of the book, queue code. I am attempting to create a display method that will show the queue in order, from front to back. (This is an assignment, i know this is not practical....) If i run the program as is, it will display the queue in order from front to rear(at least that is what i believe i did). The problem i am having is if i change the nItems, it ceases to work. For example if you add the line of code, theQueue.remove(); right above the call to the display, the method ceases to work, i know it is because the front is now = to 4, instead of 3,and it will not enter the for method which needs the front to be < nItems, 4<4 is not true so the for loop does not initiate.
Simply use something like:
public void display() {
for (int i = 0; i < nItems; i++) {
System.out.println(queArray[(front + i) % maxSize]);
}
}
In my opinion you're using too many variables which you don't need. You only need the Queue size and its item count.
public Queue(int s) {
size = s;
queArray = new long[s];
nItems = 0;
}
public void insert(long j) {
if(nItems < size) {
queArray[nItems] = j;
nItems++;
}
}
public long remove() {
if(nItems > 0) {
long temp = queArray[nItems];
nItems--;
return temp;
}
}
public void display() {
for(int j = 0; j < nItems; j++) {
System.out.println(queArray[j]);
}
}
So what's happening right now is that j is the position of the element in your array, which is different from the number of elements that you've printed so far.
You need to either use a different index to count how many elements you printed or check whether you're at the end by comparing j to rear.
When the queue is full (rear == maxSize - 1) and you do a insert, it will replace the first
item, so i think the line nItems++ should not be incremented when the queue is already full.
Edit: Avoid modulus operations when you don't need them, they consume a lot of cpu.
The backing store for your queue is :
private long[] queArray;
Why don't you instead use :
private List<Long> queArray
and let List worry about the resizing effort after add/remove operations. Your current queue implementation needs to know exactly how many elements are going into the queue on construction. That's pretty inconvenient for clients using this API.
You can instantiate the queArray as :
queArray = new ArrayList<Long>();
in your constructor. Once you really understand that code, you can then move onto worrying about the re-sizing logic yourself.
Add a method void removeFirst(int newVal) to the IntegerList class that removes the first occurrence of a value from the list. If the value does not appear in the list, it should do nothing (but it's not an error). Removing an item should not change the size of the array, but note that the array values do need to remain contiguous, so when you remove a value you will have to shift everything after it down to fill up its space. Also remember to decrement the variable that keeps track of the number of elements.
Please help, I have tried all of the other solutions listed on this site regarding "removing an element from an array" and none have worked.
This method supports the same functionality as Collection.remove() which is how an ArrayList removes the first matching element.
public boolean remove(int n) {
for (int i = 0; i < size; i++) {
if (array[i] != n) continue;
size--;
System.arraycopy(array, i + 1, array, i, size - i);
return true;
}
return false;
}
Rather than write this code yourself, I suggest you look at Trove4J's TIntArrayList which is a wrapper for int[] You can also read the code for ArrayList to see how it is written.
You could do this:
int count; //No of elements in the array
for(i=0;i<count;i++)
{
if(Array[i]==element )
{
swap(Array,i,count);
if(count)
--count;
break;
}
}
int swap(int Array[],int i,int count)
{
int j;
for(j=i;j<=count-i;j++)
a[i]=a[i+1];
}
This is not the Full Implementation.You have to create a class and do this.
Using the method below
public static <TypeOfObject> TypeOfObject[] removeFirst(TypeOfObject[] array, TypeOfObject valueToRemove) {
TypeOfObject[] result = Arrays.copyOf(array, array.length - 1);
List<TypeOfObject> tempList = new ArrayList<>();
tempList.addAll(Arrays.asList(array));
tempList.remove(valueToRemove);
return tempList.toArray(result);
}
You can remove the first element of any array by calling the method as demonstrated in the below JUnit test.
#Test
public void removeFirstTest() {
// Given
Integer valToRemove = 5;
Integer[] input = {1,2,3,valToRemove,4,valToRemove,6,7,8,9};
Integer[] expected = {1,2,3,4,valToRemove,6,7,8,9};
// When
Integer[] actual = removeFirst(input, valToRemove);
// Then
Assert.assertArrayEquals(expected, actual);
}