I know this question has asked many times but after seaching for an hour i still have problem.
I want to use a lifo stack which has a max number of elements it can store.After it reach the max number is deletes the element at first place and replace it with the new so in first pop i can get this element and in second i have to get the element at size-1.
What i tried:
1) Using a modified Stack ,as described here .The problem is that it always returning the first 5 elements(if the size is 5) i added.
class StackSizable<E> extends Stack<E>{
int maxSize;
StackSizable(int size)
{
super();
this.maxSize=size;
}
#Override
public E push(E elt) {
super.push(elt);
while (this.size() > this.maxSize) {
this.removeElementAt(this.size() - 1);
}
return null;
}
}
2)Using an ArrayDeque ,i dont see any diference from a simple Stack , its not setting any limit(am i using it wrong?)
ArrayDeque<State> lifo = new ArrayDeque<State>(5);
lifo.pop();
lifo.push(state);
I want to use this in a puzzle game for undo-redo functionality
Solved: I ended using a fixed size stack as tom said ,mainly for the performance
public class FixedStack<T> {
private T[] stack;
private int size;
private int top;
private int popBalance = 0;//its used to see if all the elements have been popped
public FixedStack(T[] stack) {
this.stack = stack;
this.top = 0;
this.size = stack.length;
}
public void push(T obj) {
if (top == stack.length)top = 0;
stack[top] = obj;
top++;
if (popBalance < size - 1)popBalance++;
}
public T pop() {
if (top - 1 < 0)top = size;
top--;
T ob = stack[top];
popBalance--;
return ob;
}
public void clear() {
top = 0;
}
public int size() {
return size;
}
public boolean poppedAll() {
if (popBalance == -1)return true;
return false;
}
}
I think the most efficient way to this is with a fixed array, with size equal to your max # of elements, and an index that points to the element that is currently the 'top' of the queue.
When you add a new element you add it at index+1 (wrapping back to element 0 if necessary) and possibly overwriting an element that no longer fits. When you pop an element you do the reverse.
This way your data structure never has to be re-ordered, and you can use an array which is more light-weight then a collection.
When the maximum size has been reached, your line
this.removeElementAt(this.size() - 1);
then immediately removes the last pushed element (which you just pushed), which is the top of the stack. You need to remove the first element instead (bottom of the stack):
this.removeElementAt(0);
Related
I have a streaming time series, of which I am interested in keeping the last 4 elements, which means I want to be able to pop the first, and add to the end. Essentially what I need is a ring buffer.
Which Java Collection is the best for this? Vector?
Consider CircularFifoBuffer from Apache Common.Collections. Unlike Queue you don't have to maintain the limited size of underlying collection and wrap it once you hit the limit.
Buffer buf = new CircularFifoBuffer(4);
buf.add("A");
buf.add("B");
buf.add("C");
buf.add("D"); //ABCD
buf.add("E"); //BCDE
CircularFifoBuffer will do this for you because of the following properties:
CircularFifoBuffer is a first in first out buffer with a fixed
size that replaces its oldest element if full.
The removal order of a CircularFifoBuffer is based on the insertion
order; elements are removed in the same order in which they were
added. The iteration order is the same as the removal order.
The add(Object), BoundedFifoBuffer.remove() and
BoundedFifoBuffer.get() operations all perform in constant time.
All other operations perform in linear time or worse.
However you should consider it's limitations as well - for example, you can't add missing timeseries to this collection because it doens't allow nulls.
NOTE: When using current Common Collections (4.*), you have to use Queue. Like this:
Queue buf = new CircularFifoQueue(4);
Since Guava 15.0 (released September 2013) there's EvictingQueue:
A non-blocking queue which automatically evicts elements from the head
of the queue when attempting to add new elements onto the queue and it
is full. An evicting queue must be configured with a maximum size.
Each time an element is added to a full queue, the queue automatically
removes its head element. This is different from conventional bounded
queues, which either block or reject new elements when full.
This class is not thread-safe, and does not accept null elements.
Example use:
EvictingQueue<String> queue = EvictingQueue.create(2);
queue.add("a");
queue.add("b");
queue.add("c");
queue.add("d");
System.out.print(queue); //outputs [c, d]
Since Java 1.6, there is ArrayDeque, which implements Queue and seems to be faster and more memory efficient than a LinkedList and doesn't have the thread synchronization overhead of the ArrayBlockingQueue: from the API docs: "This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue."
final Queue<Object> q = new ArrayDeque<Object>();
q.add(new Object()); //insert element
q.poll(); //remove element
If you need
O(1) insertion and removal
O(1) indexing to interior elements
access from a single thread only
generic element type
then you can use this CircularArrayList for Java in this way (for example):
CircularArrayList<String> buf = new CircularArrayList<String>(4);
buf.add("A");
buf.add("B");
buf.add("C");
buf.add("D"); // ABCD
String pop = buf.remove(0); // A <- BCD
buf.add("E"); // BCDE
String interiorElement = buf.get(i);
All these methods run in O(1).
I had the same problem some time ago and was disappointed because I couldn't find any solution that suites my needs so I wrote my own class.
Honestly, I did found some code back then, but even that wasn't what I was searching for so I adapted it and now I'm sharing it, just like the author of that piece of code did.
EDIT: This is the original (although slightly different) code: CircularArrayList for java
I don't have the link of the source because it was time ago, but here's the code:
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
public class CircularArrayList<E> extends AbstractList<E> implements RandomAccess {
private final int n; // buffer length
private final List<E> buf; // a List implementing RandomAccess
private int leader = 0;
private int size = 0;
public CircularArrayList(int capacity) {
n = capacity + 1;
buf = new ArrayList<E>(Collections.nCopies(n, (E) null));
}
public int capacity() {
return n - 1;
}
private int wrapIndex(int i) {
int m = i % n;
if (m < 0) { // modulus can be negative
m += n;
}
return m;
}
#Override
public int size() {
return this.size;
}
#Override
public E get(int i) {
if (i < 0 || i >= n-1) throw new IndexOutOfBoundsException();
if(i > size()) throw new NullPointerException("Index is greater than size.");
return buf.get(wrapIndex(leader + i));
}
#Override
public E set(int i, E e) {
if (i < 0 || i >= n-1) {
throw new IndexOutOfBoundsException();
}
if(i == size()) // assume leader's position as invalid (should use insert(e))
throw new IndexOutOfBoundsException("The size of the list is " + size() + " while the index was " + i
+". Please use insert(e) method to fill the list.");
return buf.set(wrapIndex(leader - size + i), e);
}
public void insert(E e)
{
int s = size();
buf.set(wrapIndex(leader), e);
leader = wrapIndex(++leader);
buf.set(leader, null);
if(s == n-1)
return; // we have replaced the eldest element.
this.size++;
}
#Override
public void clear()
{
int cnt = wrapIndex(leader-size());
for(; cnt != leader; cnt = wrapIndex(++cnt))
this.buf.set(cnt, null);
this.size = 0;
}
public E removeOldest() {
int i = wrapIndex(leader+1);
for(;;i = wrapIndex(++i)) {
if(buf.get(i) != null) break;
if(i == leader)
throw new IllegalStateException("Cannot remove element."
+ " CircularArrayList is empty.");
}
this.size--;
return buf.set(i, null);
}
#Override
public String toString()
{
int i = wrapIndex(leader - size());
StringBuilder str = new StringBuilder(size());
for(; i != leader; i = wrapIndex(++i)){
str.append(buf.get(i));
}
return str.toString();
}
public E getOldest(){
int i = wrapIndex(leader+1);
for(;;i = wrapIndex(++i)) {
if(buf.get(i) != null) break;
if(i == leader)
throw new IllegalStateException("Cannot remove element."
+ " CircularArrayList is empty.");
}
return buf.get(i);
}
public E getNewest(){
int i = wrapIndex(leader-1);
if(buf.get(i) == null)
throw new IndexOutOfBoundsException("Error while retrieving the newest element. The Circular Array list is empty.");
return buf.get(i);
}
}
A very interesting project is disruptor. It has a ringbuffer and is used from what I know in financial applications.
See here: code of ringbuffer
I checked both Guava's EvictingQueue and ArrayDeque.
ArrayDeque does not limit growth if it's full it will double size and hence is not precisely acting like a ringbuffer.
EvictingQueue does what it promises but internally uses a Deque to store things and just bounds memory.
Hence, if you care about memory being bounded ArrayDeque is not fullfilling your promise. If you care about object count EvictingQueue uses internal composition (bigger object size).
A simple and memory efficient one can be stolen from jmonkeyengine.
verbatim copy
import java.util.Iterator;
import java.util.NoSuchElementException;
public class RingBuffer<T> implements Iterable<T> {
private T[] buffer; // queue elements
private int count = 0; // number of elements on queue
private int indexOut = 0; // index of first element of queue
private int indexIn = 0; // index of next available slot
// cast needed since no generic array creation in Java
public RingBuffer(int capacity) {
buffer = (T[]) new Object[capacity];
}
public boolean isEmpty() {
return count == 0;
}
public int size() {
return count;
}
public void push(T item) {
if (count == buffer.length) {
throw new RuntimeException("Ring buffer overflow");
}
buffer[indexIn] = item;
indexIn = (indexIn + 1) % buffer.length; // wrap-around
count++;
}
public T pop() {
if (isEmpty()) {
throw new RuntimeException("Ring buffer underflow");
}
T item = buffer[indexOut];
buffer[indexOut] = null; // to help with garbage collection
count--;
indexOut = (indexOut + 1) % buffer.length; // wrap-around
return item;
}
public Iterator<T> iterator() {
return new RingBufferIterator();
}
// an iterator, doesn't implement remove() since it's optional
private class RingBufferIterator implements Iterator<T> {
private int i = 0;
public boolean hasNext() {
return i < count;
}
public void remove() {
throw new UnsupportedOperationException();
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return buffer[i++];
}
}
}
None of the previously given examples were meeting my needs completely, so I wrote my own queue that allows following functionality: iteration, index access, indexOf, lastIndexOf, get first, get last, offer, remaining capacity, expand capacity, dequeue last, dequeue first, enqueue / add element, dequeue / remove element, subQueueCopy, subArrayCopy, toArray, snapshot, basics like size, remove or contains.
EjectingQueue
EjectingIntQueue
Use a Queue
Queue<String> qe=new LinkedList<String>();
qe.add("a");
qe.add("b");
qe.add("c");
qe.add("d");
System.out.println(qe.poll()); //returns a
System.out.println(qe.poll()); //returns b
System.out.println(qe.poll()); //returns c
System.out.println(qe.poll()); //returns d
There's five simple methods of a Queue
element() -- Retrieves, but does not remove, the head of this
queue.
offer(E o) -- Inserts the specified element into this queue, if
possible.
peek() -- Retrieves, but does not remove, the head of this
queue, returning null if this queue is empty.
poll() -- Retrieves and removes the head of this queue, or
null if this queue is empty.
remove() -- Retrieves and removes the head of this queue.
Currently working on my home assignment, a simulation code to make stack with a support of dynamic array.
The method pop() is not working to it is function, I wrote some of the code but I need a completion. My stack should be simulates like this, you insert a numbers to be called top then remove that number(top).
import java.util.NoSuchElementException;
public class MyStack implements IntStack {
int[] heltal;
public MyStack() {
heltal = new int[0];
}
public void push(int tal) {
int[] temp = new int[heltal.length + 1];
for (int x = 0; x < heltal.length; x++) {
temp[x] = heltal[x] + tal;
}
heltal = temp;
for (int i = 0; i < heltal.length; i++) {
heltal[i] = tal;
}
}
#Override
public int pop() {
if (Isempty()) {
throw new NoSuchElementException("The stack is empty, there is nothing to pop");
} else {
int[] temp = new int[heltal.length - 1];
for (int x = 0; x < heltal.length - 1; x++) {
temp[x] = heltal[x];
}
int etttal = heltal[0];
heltal = temp;
return etttal;
}
}
#Override
public int peek() {
if (Isempty()) {
throw new NoSuchElementException("The stack is empty");
} else {
return heltal[0];
}
}
public boolean Isempty() {
return heltal.length == 0;
}
}
You appear to be making this more difficult than required. For a stack implementation, push, pop, peek, and others are nothing more than index manipulators that return or store a value. The stack can be backed by an array or a list. And pushing et al are abstract terms. So when you push a value, you do not need to copy everything down by one. Just add it to the end of your data structure.
pop - check the index and if valid, return the element at the current index, update the index.
push - store the value at the next location. Probably index + 1 but it depends on how you implement it.
peek - return the top value (at the index) but don't update the index.
If you are using an array, you need to add method(s) to increase it's capacity.
For more information, check out Stack
Here is a simple push method, backed by an array called stack and an index field. It presumes ints are being used.
public void push(int v) {
if (index == stack.length-1) {
// no more room, increase array size
// while retaining current values.
}
stack[++index] = v;
}
I'm working on recreating the ArrayList class. I have a problem with the add method. I want my add method to return the new table and to affect it to my element. But when I want to get into the element of my table element it's always null.
And another question..I wanna Create the constructor that takes objects as the elements of the Arraylist like ArrayListBis(1,2,3)..what's gonna be the parameter of the contractor is it ArrayListBis(Object... args) ?
public class ArrayListBis {
final static int DEFAULTSIZE=50;
private int indexCourant,dernierElement,size;
private Object [] elements;
public ArrayListBis(int size){
elements=creatList(size);
indexCourant=0;
dernierElement=size-1;
this.size=size;
}
public void add(Object o){
add(o,size());
}
public void add(Object o, int index){
Object[] temp;
if(index <0 || index > size())
throw new IndexOutOfBoundsException();
else{
temp=creatList(size()+1);
for(int i=0;i!=size()+1;i++){
if(i<index)
temp[i]=elements[i];
else if(i==index)
temp[i]=elements[index];
else
temp[i]=elements[i+1];
}
this.size++;
elements=temp;
}
}
There a couple issues with your add method. First, you do not need to recreate your list every time a new element is added. The reason is that your list will not start out full, hence this line
add(o,size());
should only be done on the condition that this.size == elements.length. However, I believe you should use size or some variable to reflect the actual count of how many elements were inserted so far into your arraylist. So in your constructor, I would set this.size = 0 instead since it starts out with zero elements. Now in your original add method, only create a new array if you're adding to an array that's full. And like others have said, you weren't adding the new element to begin with. So with those changes it should now look like this,
public void add(Object o, int index){
Object[] temp;
if(index >= 0 && index < elements.length)
temp[index] = o;
size++;
else{
temp=creatList(elements.length * 2);
for(int i=0;i < elements.length;i++){
if(i<index)
temp[i]=elements[i];
else if(i==index)
temp[i]=o;
else
temp[i]=elements[i+1];
}
temp[index] = 0;
size++;
this.elements = temp;
}
}
Only other thing I changed was how much the new list's size should be. I changed it to be double the original array's size because you don't want to make a new array of a size that's only one more bigger than the original because making new arrays and copying all the elements from the old one to the new one is a costly operation that shouldn't be done too often.
I have an assignment to push Strings into a stack. I created a program that will store numbers but I cannot figure out the correct way to define the array to take a string. Here is my code. My Java is rusty so I am trying to remember all this from my first java class 2 years ago. I am sure it is super simple but I cannot find anything online where strings are stored in a stack for me to see how to do it. Thanks for the help!
public class stackx {
private int maxSize; //number of items in stack
private int[] stackArray;
private int top; // top of stack
public stackx(int arraySize) {
maxSize = arraySize;
stackArray = new int[maxSize];
top = -1;
}
public void push(int a) { //put value on top of stack
if (top == maxSize - 1)
{
System.out.println("Stack is full");
} else {
top = top + 1;
stackArray[top] = a;
}
}
public int pop() { //take item from top of stack
if (!isEmpty())
return stackArray[top--]; // access item, decrement top
else {
System.out.println("Stack is Empty");
}
}
public int peek() //peek at the top of the stack
{
return stackArray[top];
}
public boolean isEmpty() { //true if stack is empty
return top == -1;
}
public void display() {
for (int i = 0; i <= top; i++) {
System.out.print(stackArray[i] + " ");
}
System.out.println();
}
} // End class stackx
**Driver class Here**
public class practicestack {
public static void main(String[] args) {
stackx newStack = new stackx(5);
newStack.push(redShirt);
newStack.push(greenShirt);
newStack.push(yellowPants);
newStack.push(purpleSocks);
newStack.push(pinkSocks);
stackx.peek();
//Display the Full Stack
newStack.display();
//Test removing a value using pop method
newStack.pop();
newStack.display();
}
}
This should be easy, I will provide you a small hint, if you still can't figure it out, I will post entire code
when you declare something like this
private int[] stackArray;
and use this array to push and pop your items, as this is Integer array you can only use this implementation for Integers.
Now your requirement is to push and pop Strings, so essentially you should do something like this.
private String[] stackArray;
Note : Your Push and pop method will change likewise, those will be small changes
Hope this helps!
Good luck.
Your stack only takes ints. You need it to take Objects if you want to store anything at all. Java doesn't let you manipulate pointers, so you can't just use int like in C/C++. You could also use generics, e.g. public class stackx<T>, which would give you something like stackx<String> newStack = new stackx<>(5);.
Just modify int to String.Here is the Demo.
Debugging on some solutions for this problem, and for the following code snippet, I think the logic is wrong in method pop(), since when executing "indexUsed--", spaces are removed continuously, but when deleting elements, it is not necessarily to be continuous.
Please feel free to correct me if I am wrong.
int stackSize = 300;
int indexUsed = 0;
int[] stackPointer = { -1, -1, -1 };
StackNode[] buffer = new StackNode[stackSize * 3];
void push(int stackNum, int value) {
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = indexUsed;
indexUsed++;
buffer[stackPointer[stackNum]] = new StackNode(lastIndex, value);
}
int pop(int stackNum) {
int value = buffer[stackPointer[stackNum]].value;
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous;
buffer[lastIndex] = null;
indexUsed--;
return value;
}
int peek(int stack) { return buffer[stackPointer[stack]].value; }
boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; }
class StackNode {
public int previous;
public int value;
public StackNode(int p, int v) {
value = v;
previous = p;
}
}
You are right, this approach is not only ridiculously inefficient and overcomplicated, but also incorrect.
Here is the simple test to prove:
StackArray stack = new StackArray();
stack.push(0, 0);
stack.push(1, 10);
System.out.println(stack.pop(0));
stack.push(1, 20);
System.out.println(stack.pop(1));
System.out.println(stack.pop(1));
Produces:
Exception in thread "main" java.lang.NullPointerException
at StackArray.pop(StackArray.java:18)
Stack data structure is usually implemented as array or single-linked list. Linked list is less efficient, because its elements are scattered across the heap, also its elements have memory overhead (node object with pointers). Array, on the other hand, is faster, but it has fixed size, so it can't be used for all tasks.
Each of these approaches has its pros and cons, but there is absolutely no point in creating mixed approach that has only disadvantages of both approaches (has fixed capacity and memory overhead).
If this is a synthetic task with the restriction of using only one array to store elements of all three stacks, then following approach can be used.
Logically split elements of array in pairs. Each pair will represent one node of single-linked list. First element of the pair will hold the value, while second element will be the pointer to the next node.
It's clear that array can hold any number of independent single-linked lists (as long as it has sufficient capacity) and you know the indices of the heads.
The idea is similar to the approach given in description, to hold the pointers to the heads of three lists, but (!) in addition hold the pointer to the list that represent "free memory" and includes all non-occupied elements of the array. Initially this "heap" list will contain all elements of the array. When you push element into one of the stacks, you need to pop element from the heap and use it to create element of the desired stack. When element is popped from the stack, this element is pushed back to heap.
You can start one of the stacks from one end of the array. You can start the other stack from the other end of the array. You can put the third stack in the middle. When, one of the side stacks need space, you need to shift the middle stack. However, I have another implementation by help of free list. You can try this implementation also:
public class ThreeStacksWithOneArray {
//This is the stack node class
class StackNode {
//This is the value of the node
int value;
//This is showing the previous node
int prev;
//This is the constructor of the class
StackNode(int value, int prev) {
this.value = value;
this.prev = prev;
}
}
//This keeps the stack nodes
private StackNode[] stackNodes = null;
private static int CAPACITY = 10;
//This keeps the top of free list
private int freeListTop = 0;
//This is the variable for the size
private int size = 0;
//These are the pointers to the three stacks
private int[] stackPointers = { -1, -1, -1 };
//This is the constructor of the main class
ThreeStacksWithOneArray() {
//Initialize the stack nodes
stackNodes = new StackNode[CAPACITY];
//initialize the free list
initFreeList();
}
//Initialize the free list
private void initFreeList() {
for (int i = 0; i < CAPACITY; i++) {
//The value of each node is 0 and it points to the next node
stackNodes[i] = new StackNode(0, i + 1);
}
}
//This is the push procedure
public void push(int stackNum, int value) throws Exception {
//Print the push information
System.out.println("Push to stack "+stackNum+" value "+value);
int freeIndex;
int currentStackTop = stackPointers[stackNum - 1];
//Find the free node
freeIndex = getFreeNodeIndex();
//Make a new node in the free index
StackNode n = stackNodes[freeIndex];
//Setting the previous node
n.prev = currentStackTop;
//Setting the value
n.value = value;
stackPointers[stackNum - 1] = freeIndex;
}
//This is the pop method
public StackNode pop(int stackNum) throws Exception {
//From which stack you want to pop. -1, since it starts from 0
int currentStackTop = stackPointers[stackNum - 1];
//This checks for stack underflow
if (currentStackTop == -1) {
throw new Exception("UNDERFLOW");
}
//Get the node as a temp node
StackNode temp = stackNodes[currentStackTop];
//Remove the node from stack
stackPointers[stackNum - 1] = temp.prev;
//Put this node as free node
freeStackNode(currentStackTop);
//Print the pop information
System.out.println("Pop from stack "+stackNum+" value: "+temp.value);
//Return the value
return temp;
}
//Get a free node index
private int getFreeNodeIndex() throws Exception {
int temp = freeListTop;
//Overflow
if (size >= CAPACITY)
throw new Exception("OVERFLOW");
freeListTop = stackNodes[temp].prev;
size++;
//return the free node index
return temp;
}
//Make one index free after a pop
private void freeStackNode(int index) {
stackNodes[index].prev = freeListTop;
//Put the index in free list
freeListTop = index;
//Decrease the size by one
size--;
}
public static void main(String args[]) {
// Test Driver
ThreeStacksWithOneArray mulStack = new ThreeStacksWithOneArray();
try {
//Adding to those three stacks
mulStack.push(1, 11);
mulStack.push(1, 12);
mulStack.push(1, 13);
mulStack.push(1, 14);
mulStack.push(2, 21);
mulStack.push(2, 22);
mulStack.push(3, 31);
mulStack.push(3, 32);
//Popping from those three stacks
mulStack.pop(1);
mulStack.pop(2);
mulStack.pop(3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
For more information, visit this: https://github.com/m-vahidalizadeh/foundations/blob/master/src/data_structures/ThreeStacksWithOneArray.java. I hope it helps.