2005年03月01日

Setクラス

  
集合を扱うSetクラスを書いてみました。
まだ、十分なテストはしてませんが、基本的な部分は問題なく動くと思います。
演算子 + , - & ^ をオーバーロードしています。

using System;
using System.Collections;

namespace Gushwell.Library {
public interface ISet : ICollection{
bool IsEmpty { get; }
bool Contains(ISet set);
bool Contains(object o);
bool Add(object o);
bool Add(ISet col);
void Remove(object o);
void Remove(ISet set);
void Clear();
object[] ToArray();
ISet Union(ISet set);
ISet Except(ISet set);
ISet Intersect(ISet set);
ISet Xor(ISet set);

}

public class HashSet : ISet, ICloneable {
private Hashtable hash;

public HashSet() {
hash = new Hashtable(16);
}

public HashSet(int capacity) {
hash = new Hashtable(capacity);
}

public HashSet(ISet set) {
hash = new Hashtable(set.Count);
this.Add(set);
}

#region ISet メンバ

public virtual bool IsEmpty {
get { return Count == 0; }
}

public virtual bool Contains(ISet set) {
foreach ( object o in set ) {
if ( !hash.ContainsKey(o) )
return false;
}
return true;
}

public virtual bool Contains(object o) {
return hash.Contains(o);
}

public virtual bool Add(object o) {
if ( !hash.ContainsKey(o) ) {
hash.Add(o,null);
return true;
}
return false;
}

// 一つでも登録できれば true;
public virtual bool Add(ISet col) {
bool result = false;
foreach ( object o in col ) {
if ( Add(o) ) {
result = true;
}
}
return result;
}

public virtual void Remove(object o) {
hash.Remove(o);
}

public virtual void Remove(ISet set) {
foreach ( object o in set ) {
hash.Remove(o);
}
}

public virtual void Clear() {
hash.Clear();
}

public object[] ToArray() {
object[] objs = new object[Count];
int i = 0;
foreach ( object o in this ) {
objs[i] = o;
i++;
}
return objs;
}


public virtual ISet Union(ISet set) {
HashSet hs = new HashSet(this);
hs.Add(set);
return hs;
}

public virtual ISet Except(ISet set) {
HashSet hs = new HashSet(this);
hs.Remove(set);
return hs;
}

public virtual ISet Intersect(ISet set) {
HashSet hs = new HashSet(this);
hs.Remove(set);
HashSet hs2 = new HashSet(this);
hs2.Remove(hs);
return hs2;
}

public virtual ISet Xor(ISet set) {
HashSet union = (HashSet)(this.Union(set));
HashSet and = (HashSet)(this.Intersect(set));
return union.Except(and);
}

#endregion

#region ICollection メンバ

public virtual void CopyTo(Array array, int index) {
foreach ( object o in array )
hash.Add(o,null);
}

public virtual Object SyncRoot {
get { return hash.SyncRoot; }
}

public virtual bool IsSynchronized {
get { return false; }
}

public virtual int Count {
get { return hash.Count; }
}


#endregion

#region IEnumerable メンバ

public virtual IEnumerator GetEnumerator() {
return hash.Keys.GetEnumerator();
}


#endregion

#region ICloneable メンバ

public object Clone() {
HashSet hs = new HashSet(this.Count);
hs.Add(this);
return hs;
}

#endregion

public override string ToString() {
string s = "[";
bool first = true;
IEnumerator en = this.GetEnumerator();
while ( en.MoveNext() ) {
if ( !first ) {
s += ", ";
}
first = false;
s += en.Current.ToString();
}
s += "]";
return s;
}

public static ISet operator +(HashSet a, HashSet b) {
return a.Union(b);
}

public static ISet operator -(HashSet a, HashSet b) {
return a.Except(b);
}

public static ISet operator &(HashSet a, HashSet b) {
return a.Intersect(b);
}

public static ISet operator ^(HashSet a, HashSet b) {
return a.Xor(b);
}
}
}


 

この記事へのトラックバックURL