Dynamic Array
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Satire.Common
{
public class DynamicArray<T> where T : struct, IComparable<T>, IEquatable<T>
{
public const int DefaultCapacity = 10;
public const int DefaultDelta = 10;
public DynamicArray(int length, int capacity, int delta)
{
_initializeBuffer(length, capacity, delta);
}
public DynamicArray(int length, int capacity)
{
_initializeBuffer(length, capacity, DefaultCapacity);
}
public DynamicArray(int length)
{
_initializeBuffer(length, DefaultCapacity, DefaultDelta);
}
public DynamicArray()
{
_initializeBuffer(0, DefaultCapacity, DefaultDelta);
}
public T this[int i]
{
get { return _value[i]; }
set { _value[i] = value; }
}
public int Length { get { return _length; } }
public int Capacity { get { if (_value == null) { return 0; } else { return _value.Length; } } }
public int Delta { get { return _delta; } }
public int Add(T ele)
{
int i = _length;
_grow(1);
_value[i] = ele;
return i;
}
public int AddInSequence(T ele, bool duplicatesAllowed)
{
int x = Array.BinarySearch<T>(_value, 0, _length, ele);
if (x > 0)
{
if (!duplicatesAllowed) { return x; }
}
else
{
x = ~x;
}
Insert(x, ele);
return x;
}
public int Insert(int at, T ele)
{
at = _insert(at, 1);
_value[at] = ele;
return at + 1;
}
public void Reset()
{
_shrink(_length);
}
public void Union(DynamicArray<T> arr)
{
_union(arr._value, arr._length);
}
public void Union(T[] arr)
{
_union(arr, arr.Length);
}
#region private
private int _insert(int idx, int count)
{
if (idx < 0) { idx = 0; }
if (idx > _length) { idx = _length; }
if (count < 0) { count = 0; }
if (count == 0) { return idx; }
_grow(count);
_copy(_value, idx, _value, idx + count, _length - idx - count);
return idx;
}
private void _initializeBuffer(int length, int capacity, int delta)
{
if (length < 0) { length = 0; }
if (delta < 0) { delta = 0; }
if (capacity < 0) { capacity = 0; }
if (capacity < length) { capacity = length; }
_setCapacity(capacity);
_length = length;
_delta = delta;
}
private void _shrink(int s)
{
if (s <= 0)
{
return;
}
if (s >= _length)
{
s = _length;
}
_length -= s;
if (_value != null)
{
if (_value.Length - _length <= _delta)
{
return;
}
}
_setCapacity(_length + _delta);
}
private void _grow(int s)
{
if (s <= 0)
{
return;
}
_length += s;
if (_value != null)
{
if (_length <= _value.Length)
{
return;
}
}
_setCapacity(_length + _delta);
}
private void _setCapacity(int size)
{
if (size < 0)
{
return;
}
if (size == 0)
{
_value = null;
return;
}
if (_value == null)
{
_value = new T[size];
return;
}
T[] tempValue = new T[size];
_copy(_value, 0, tempValue, 0, _min(_value.Length, tempValue.Length));
_value = tempValue;
}
private void _copy(T[] arr1, int offset1, T[] arr2, int offset2, int count)
{
int bytes = (Buffer.ByteLength(arr1) / arr1.Length);
Buffer.BlockCopy(arr1, offset1 * bytes, arr2, offset2 * bytes, count * bytes);
}
private int _min(int i1, int i2)
{
if (i1 < i2) { return i1; }
return i2;
}
public void _union(T[] arr, int len)
{
int mIdx = 0;
int cIdx = 0;
while (cIdx < len)
{
int cv = -1;
if (mIdx < _length)
{
cv = arr[cIdx].CompareTo(_value[mIdx]);
}
if (cv < 0)
{
mIdx = this.Insert(mIdx, arr[cIdx]);
cIdx++;
}
else
{
if (cv == 0)
{
mIdx++;
cIdx++;
}
else
{
mIdx++;
}
}
}
}
private T[] _value;
private int _delta;
private int _length;
#endregion
}
}
Related examples in the same category