package edu.berkeley.nlp.util;
import java.io.Serializable;
import java.util.Arrays;
/**
* Class representing a sparse array. A <code>double[]</code> and <code>int[]</code> arrays
* store a sparse reprsentation of a double array. Arrays are grown behind the scene when necessary.
* Setting/getting a count takes time O(log n), where n is the number of non-zero elements.
*
* @author aria42
*
*/
public class SparseArray<T> implements Serializable {
private static final long serialVersionUID = 42L;
T[] values = (T[]) new Object[0];
int[] indices = new int[0];
int length = 0;
private void grow() {
int curSize = values.length;
int newSize = curSize + 10;
T[] newData = (T[]) new Object[newSize];
System.arraycopy(values, 0, newData, 0, curSize);
values = newData;
int[] newIndices = new int[newSize];
System.arraycopy(indices, 0, newIndices, 0, curSize);
for (int i=curSize; i < newIndices.length; ++i) {
newIndices[i] = Integer.MAX_VALUE;
}
indices = newIndices;
}
public T get(int index) {
int res = Arrays.binarySearch(indices, index);
if (res >= 0 && res < length) {
return values[res];
}
return null;
}
public int size() {
return length;
}
public void put(int index0, T x) {
int res = Arrays.binarySearch(indices, index0);
// Greater than everything
if (res >= 0 && res < length) {
values[res] = x;
return;
}
if (length+1 >= values.length) {
grow();
}
// In the middle
int insertionPoint = -(res+1);
assert insertionPoint >= 0 && insertionPoint <= length : String.format("length: %d insertion: %d",length,insertionPoint);
// Shift The Stuff After
System.arraycopy(values, insertionPoint, values, insertionPoint+1, length-insertionPoint);
System.arraycopy(indices, insertionPoint, indices, insertionPoint+1, length-insertionPoint);
indices[insertionPoint] = index0;
values[insertionPoint] = x;
length++;
}
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("{ ");
for (int i=0; i < length; ++i) {
builder.append(String.format("%d : %.5f",indices[i],values[i]));
builder.append(" ");
}
builder.append(" }");
return builder.toString();
}
public String toString(Indexer<?> indexer) {
StringBuilder builder = new StringBuilder();
builder.append("{ ");
for (int i=0; i < length; ++i) {
builder.append(String.format("%s : %.5f",indexer.getObject(indices[i]),values[i]));
builder.append(" ");
}
builder.append("}");
return builder.toString();
}
public static void main(String[] args) {
SparseArray<Double> sv = new SparseArray<Double>();
sv.put(0, 1.0);
sv.put(1, 2.0);
sv.put(4, -2.0);
System.out.println(sv);
}
}