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