Implemented an efficient integer set class that uses a sorted array of
integers to maintain its contents. git-svn-id: https://samskivert.googlecode.com/svn/trunk@559 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
//
|
||||
// $Id: ArrayIntSet.java,v 1.1 2002/02/03 07:10:16 mdb Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2001 Michael Bayne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Provides an {@link IntSet} implementation using a sorted array of
|
||||
* integers to maintain the contents of the set.
|
||||
*/
|
||||
public class ArrayIntSet extends AbstractSet
|
||||
implements IntSet
|
||||
{
|
||||
// documentation inherited from interface
|
||||
public int size ()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean isEmpty ()
|
||||
{
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean contains (Object o)
|
||||
{
|
||||
return contains(((Integer)o).intValue());
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean contains (int value)
|
||||
{
|
||||
return (binarySearch(value) >= 0);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Iterator iterator ()
|
||||
{
|
||||
return new Iterator() {
|
||||
public boolean hasNext () {
|
||||
return (_pos < _size);
|
||||
}
|
||||
|
||||
public Object next () {
|
||||
if (_pos == _size) {
|
||||
throw new NoSuchElementException();
|
||||
} else {
|
||||
return new Integer(_values[_pos++]);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove () {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
protected int _pos;
|
||||
};
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Object[] toArray ()
|
||||
{
|
||||
return toArray(new Integer[_size]);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Object[] toArray (Object[] a)
|
||||
{
|
||||
for (int i = 0; i < _size; i++) {
|
||||
a[i] = new Integer(_values[i]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int[] toIntArray ()
|
||||
{
|
||||
int[] values = new int[_size];
|
||||
System.arraycopy(_values, 0, values, 0, _size);
|
||||
return values;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean add (Object o)
|
||||
{
|
||||
return add(((Integer)o).intValue());
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean add (int value)
|
||||
{
|
||||
int index = binarySearch(value);
|
||||
if (index >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert the return value into the insertion point
|
||||
index += 1;
|
||||
index *= -1;
|
||||
|
||||
// expand the values array if necessary, leaving room for the
|
||||
// newly added element
|
||||
int valen = _values.length;
|
||||
int[] source = _values;
|
||||
if (valen == _size) {
|
||||
_values = new int[valen*2];
|
||||
System.arraycopy(source, 0, _values, 0, index);
|
||||
}
|
||||
|
||||
// shift and insert
|
||||
if (_size > index) {
|
||||
System.arraycopy(source, index,
|
||||
_values, index+1, _size-index);
|
||||
}
|
||||
_values[index] = value;
|
||||
|
||||
// increment our size
|
||||
_size += 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all of the values in the supplied array to the set.
|
||||
*
|
||||
* @param values elements to be added to this set.
|
||||
*
|
||||
* @return <tt>true</tt> if this set did not already contain all of
|
||||
* the specified elements.
|
||||
*/
|
||||
public boolean add (int[] values)
|
||||
{
|
||||
boolean modified = false;
|
||||
int vlength = values.length;
|
||||
for (int i = 0; i < vlength; i++) {
|
||||
modified = (add(values[i]) || modified);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean remove (Object o)
|
||||
{
|
||||
return remove(((Integer)o).intValue());
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean remove (int value)
|
||||
{
|
||||
int index = binarySearch(value);
|
||||
if (index > 0) {
|
||||
System.arraycopy(_values, index, _values, index+1, --_size-index);
|
||||
_values[_size] = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean containsAll (Collection c)
|
||||
{
|
||||
Iterator iter = c.iterator();
|
||||
while (iter.hasNext()) {
|
||||
if (!contains(iter.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean addAll (Collection c)
|
||||
{
|
||||
boolean modified = false;
|
||||
Iterator iter = c.iterator();
|
||||
while (iter.hasNext()) {
|
||||
modified = (add(iter.next()) || modified);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean retainAll (Collection c)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clear ()
|
||||
{
|
||||
Arrays.fill(_values, 0);
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean equals (Object o)
|
||||
{
|
||||
if (o instanceof ArrayIntSet) {
|
||||
ArrayIntSet other = (ArrayIntSet)o;
|
||||
if (other._size == _size) {
|
||||
return Arrays.equals(_values, other._values);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int hashCode ()
|
||||
{
|
||||
int hashCode = 0;
|
||||
for (int i = 0; i < _size; i++) {
|
||||
hashCode ^= _values[i];
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a binary search on our values array, looking for the
|
||||
* specified value. Swiped from <code>java.util.Arrays</code> because
|
||||
* those wankers didn't provide a means by which to perform a binary
|
||||
* search on a subset of an array.
|
||||
*/
|
||||
protected int binarySearch (int key)
|
||||
{
|
||||
int low = 0;
|
||||
int high = _size-1;
|
||||
|
||||
while (low <= high) {
|
||||
int mid = (low + high) >> 1;
|
||||
int midVal = _values[mid];
|
||||
|
||||
if (midVal < key) {
|
||||
low = mid + 1;
|
||||
} else if (midVal > key) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return mid; // key found
|
||||
}
|
||||
}
|
||||
|
||||
return -(low + 1); // key not found.
|
||||
}
|
||||
|
||||
/** An array containing the values in this set. */
|
||||
protected int[] _values = new int[16];
|
||||
|
||||
/** The number of elements in this set. */
|
||||
protected int _size;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// $Id: IntSet.java,v 1.1 2002/02/03 07:10:16 mdb Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2001 Michael Bayne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A set that holds integers and provides accessors that eliminate the
|
||||
* need to create and manipulate superfluous <code>Integer</code>
|
||||
* objects. It extends the <code>Set</code> interface and therefore
|
||||
* provides all of the standard methods (in which <code>Integer</code>
|
||||
* objects will be converted to ints).
|
||||
*/
|
||||
public interface IntSet extends Set
|
||||
{
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
*
|
||||
* @param value element whose presence in this set is to be tested.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains the specified element.
|
||||
*/
|
||||
public boolean contains (int value);
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present
|
||||
* (optional operation). If this set already contains the specified
|
||||
* element, the call leaves this set unchanged and returns
|
||||
* <tt>false</tt>. In combination with the restriction on
|
||||
* constructors, this ensures that sets never contain duplicate
|
||||
* elements.
|
||||
*
|
||||
* @param value element to be added to this set.
|
||||
*
|
||||
* @return <tt>true</tt> if this set did not already contain the
|
||||
* specified element.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>add</tt> method is
|
||||
* not supported by this set.
|
||||
*/
|
||||
public boolean add (int value);
|
||||
|
||||
/**
|
||||
* Removes the specified element from this set if it is present
|
||||
* (optional operation). Returns <tt>true</tt> if the set contained
|
||||
* the specified element (or equivalently, if the set changed as a
|
||||
* result of the call). (The set will not contain the specified
|
||||
* element once the call returns.)
|
||||
*
|
||||
* @param value element to be removed from this set, if present.
|
||||
*
|
||||
* @return true if the set contained the specified element.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the <tt>remove</tt> method
|
||||
* is not supported by this set.
|
||||
*/
|
||||
public boolean remove (int value);
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this set. Obeys
|
||||
* the general contract of the <tt>Collection.toArray</tt> method.
|
||||
*
|
||||
* @return an array containing all of the elements in this set.
|
||||
*/
|
||||
public int[] toIntArray ();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// $Id: ArrayIntSetTest.java,v 1.1 2002/02/03 07:10:16 mdb Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2001 Michael Bayne
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.samskivert.Log;
|
||||
|
||||
public class ArrayIntSetTest extends TestCase
|
||||
{
|
||||
public ArrayIntSetTest ()
|
||||
{
|
||||
super(ArrayIntSetTest.class.getName());
|
||||
}
|
||||
|
||||
public void runTest ()
|
||||
{
|
||||
ArrayIntSet set = new ArrayIntSet();
|
||||
set.add(3);
|
||||
set.add(5);
|
||||
set.add(5);
|
||||
set.add(9);
|
||||
set.add(5);
|
||||
set.add(7);
|
||||
set.add(1);
|
||||
|
||||
int[] values = { 1, 3, 5, 7, 9 };
|
||||
int[] setvals = set.toIntArray();
|
||||
|
||||
assert("values equal", Arrays.equals(values, setvals));
|
||||
}
|
||||
|
||||
public static Test suite ()
|
||||
{
|
||||
return new ArrayIntSetTest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user