package com.shekhargulati.tadm.ch03;
import java.util.Arrays;
import java.util.stream.IntStream;
/**
* We have seen how dynamic arrays enable arrays to grow while still achieving constant-time amortized performance.
* This problem concerns extending dynamic arrays to let them both grow and shrink on demand.
* (a) Consider an underflow strategy that cuts the array size in half whenever the array falls below half full.
* Give an example sequence of insertions and deletions where this strategy gives a bad amortized cost.
* (b) Then, give a better underflow strategy than that suggested above, one that achieves constant amortized cost per deletion.
*/
public class Problem3_3 {
public static void main(String[] args) {
DynamicArray arr = new DynamicArray();
IntStream.rangeClosed(1, 5).forEach(arr::add);
arr.remove1(1);
arr.add(1);
arr.remove1(3);
arr.add(2);
}
}
class DynamicArray {
int[] arr;
int size;
public DynamicArray() {
this.arr = new int[1];
}
public void add(int el) {
if (this.arr.length == this.size) {
this.arr = Arrays.copyOf(this.arr, this.size * 2);
}
this.arr[this.size++] = el;
}
public boolean remove1(int el) {
int found = -1;
for (int i = 0; i < this.size; i++) {
if (this.arr[i] == el) {
found = i;
break;
}
}
if (found == -1) {
return false;
}
this.size--;
System.arraycopy(this.arr, found + 1, this.arr, found, this.size - found);
for (int i = this.size; i < this.arr.length; i++) {
this.arr[i] = 0;
}
if (this.size == this.arr.length / 2) {
int[] copy = new int[this.arr.length / 2];
System.arraycopy(arr, 0, copy, 0, copy.length);
this.arr = copy;
}
return true;
}
public boolean remove2(int el) {
/*
Search the first occurrence of the element in the array. Iterate only till size
If element is not found return false
Else move all the elements up by one place
-> and decrement size by 1
*/
int found = -1;
for (int i = 0; i < this.size; i++) {
if (this.arr[i] == el) {
found = i;
break;
}
}
if (found == -1) {
return false;
}
size--;
int[] copy = new int[size];
System.arraycopy(arr, 0, copy, 0, found);
System.arraycopy(this.arr, found + 1, copy, found, this.size - found);
this.arr = copy;
return true;
}
public int getSize() {
return size;
}
}