概念:
集合特殊元素们的一种聚合。其元素被称为“成员”。
属性:
-
集合成员都是无序的
-
集合的成员只能出现一次
定义:
-
空集合:不包含任何成员的集合
-
集合相等:两个集合包含完全一样的成员
-
子集:第一个集合的全部成员都包含在第二个集合内,就认为第一个集合是第二个集合的子集
集合操作:
-
联合:把一个集合的成员与另一个集合的成员合并从而获得新的集合
-
交叉:把既存在于第一个集合也存在于第二个集合的所有成员添加给一个集合从而获得新的集合
-
差异:把存在于第一个集合但不存在于第二个集合的所有成员添加给一个集合从而获得新的集合
属性:
-
与空集合的交叉式空集合。与空集合的联合是集合本身。
-
与自身的交叉是集合本身。与自身的联合还是集合本身
-
交叉与联合是可交换的
-
集合1交叉集合2等价于集合2交叉集合1
-
集合1联合集合2等价于集合2联合集合1
-
-
交叉与联合是可结合的
-
集合1交叉(集合2交叉集合3)等价于(集合1交叉集合2)交叉集合3
-
集合1联合(集合2联合集合3)等价于(集合1联合集合2)联合集合3
-
-
两个集合联合后与集合交叉是可分配的
-
集合1交叉(集合2联合集合3)等价于(集合1交叉集合2)联合(集合1交叉集合3)
-
-
两个集合交叉后与集合联合是可分配的
-
集合1联合(集合2交叉集合3)等价于(集合1联合集合2)交叉(集合1联合集合3)
-
-
集合本身与另一个集合联合后再与自身交叉产生的结果还是集合本身(吸收定律)
-
集合本身与另一个集交叉合后再与自身联合产生的结果还是集合本身(吸收定律)
-
两个集合联合或交叉后与另一个集合进行差异操作,下列等式成立
-
集合1差异(集合2联合集合3)等价于(集合1差异集合2)交叉(集合1差异集合3)
-
集合1差异(集合2交叉集合3)等价于(集合1差异集合2)联合(集合1差异集合3)
-
这一次我用2种方法实现集合类CSet。对于非数值数据采用散列表存储底层数据,对于数值类型数据采用位数组来存储。
CSet类
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Chapter13
{
public class CSet
{
private Hashtable data;
public CSet()
{
data = new Hashtable();
}
public void Add(Object item)
{
if ( ! data.ContainsValue(item))
{
data.Add(Hash(item), item);
}
}
public void Remove(Object item)
{
data.Remove(Hash(item));
}
public int Size()
{
return data.Count;
}
public CSet Union(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
tempSet.Add( this .data[hashObject]);
}
foreach (Object hashObject in aSet.data.Keys)
{
if ( ! ( this .data.ContainsKey(hashObject)))
{
tempSet.Add(aSet.data[hashObject]);
}
}
return tempSet;
}
public CSet Intersection(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
if (aSet.data.Contains(hashObject))
{
tempSet.Add(aSet.data[hashObject]);
}
}
return tempSet;
}
public bool SubSet(CSet aSet)
{
if ( this .Size() > aSet.Size())
{
return false ;
}
else
{
foreach (Object key in this .data.Keys)
{
if ( ! (aSet.data.ContainsKey(key)))
{
return false ;
}
}
}
return true ;
}
public CSet Difference(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
if ( ! (aSet.data.ContainsKey(hashObject)))
{
tempSet.Add(data[hashObject]);
}
}
return tempSet;
}
public override string ToString()
{
string s = "" ;
foreach (Object key in data.Keys)
{
s += data[key] + " " ;
}
return s;
}
private string Hash(Object item)
{
char [] chars;
string s = item.ToString();
int hashValue = 0 ;
chars = s.ToCharArray();
for ( int i = 0 ; i < chars.GetUpperBound( 0 ); i ++ )
{
hashValue += ( int )chars[i];
}
return hashValue.ToString();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Chapter13
{
public class CSet
{
private Hashtable data;
public CSet()
{
data = new Hashtable();
}
public void Add(Object item)
{
if ( ! data.ContainsValue(item))
{
data.Add(Hash(item), item);
}
}
public void Remove(Object item)
{
data.Remove(Hash(item));
}
public int Size()
{
return data.Count;
}
public CSet Union(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
tempSet.Add( this .data[hashObject]);
}
foreach (Object hashObject in aSet.data.Keys)
{
if ( ! ( this .data.ContainsKey(hashObject)))
{
tempSet.Add(aSet.data[hashObject]);
}
}
return tempSet;
}
public CSet Intersection(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
if (aSet.data.Contains(hashObject))
{
tempSet.Add(aSet.data[hashObject]);
}
}
return tempSet;
}
public bool SubSet(CSet aSet)
{
if ( this .Size() > aSet.Size())
{
return false ;
}
else
{
foreach (Object key in this .data.Keys)
{
if ( ! (aSet.data.ContainsKey(key)))
{
return false ;
}
}
}
return true ;
}
public CSet Difference(CSet aSet)
{
CSet tempSet = new CSet();
foreach (Object hashObject in data.Keys)
{
if ( ! (aSet.data.ContainsKey(hashObject)))
{
tempSet.Add(data[hashObject]);
}
}
return tempSet;
}
public override string ToString()
{
string s = "" ;
foreach (Object key in data.Keys)
{
s += data[key] + " " ;
}
return s;
}
private string Hash(Object item)
{
char [] chars;
string s = item.ToString();
int hashValue = 0 ;
chars = s.ToCharArray();
for ( int i = 0 ; i < chars.GetUpperBound( 0 ); i ++ )
{
hashValue += ( int )chars[i];
}
return hashValue.ToString();
}
}
}
使用位数组
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Chapter13
{
public class CSetBitArray
{
private BitArray data;
public CSetBitArray()
{
data = new BitArray( 5 );
}
public void Add( int item)
{
data[item] = true ;
}
public bool IsMember( int item)
{
return data[item];
}
public void Remove( int item)
{
data[item] = false ;
}
public CSetBitArray Union(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] || aSet.data[i]);
}
return tempSet;
}
public CSetBitArray Intersection(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] && aSet.data[i]);
}
return tempSet;
}
public CSetBitArray Difference(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] && ( ! (aSet.data[i])));
}
return tempSet;
}
public bool IsSubset(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
if ( this .data[i] && ( ! (aSet.data[i])))
{
return false ;
}
}
return true ;
}
public override string ToString()
{
string s = " " ;
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
if (data[i])
{
s += i;
}
}
return s;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Chapter13
{
public class CSetBitArray
{
private BitArray data;
public CSetBitArray()
{
data = new BitArray( 5 );
}
public void Add( int item)
{
data[item] = true ;
}
public bool IsMember( int item)
{
return data[item];
}
public void Remove( int item)
{
data[item] = false ;
}
public CSetBitArray Union(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] || aSet.data[i]);
}
return tempSet;
}
public CSetBitArray Intersection(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] && aSet.data[i]);
}
return tempSet;
}
public CSetBitArray Difference(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
tempSet.data[i] = ( this .data[i] && ( ! (aSet.data[i])));
}
return tempSet;
}
public bool IsSubset(CSetBitArray aSet)
{
CSetBitArray tempSet = new CSetBitArray();
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
if ( this .data[i] && ( ! (aSet.data[i])))
{
return false ;
}
}
return true ;
}
public override string ToString()
{
string s = " " ;
for ( int i = 0 ; i < data.Count - 1 ; i ++ )
{
if (data[i])
{
s += i;
}
}
return s;
}
}
}
测试:
测试
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Chapter13
{
class Program
{
static void Main( string [] args)
{
CSet();
CSetBitArray();
}
private static void CSetBitArray()
{
CSetBitArray setA = new CSetBitArray();
CSetBitArray setB = new CSetBitArray();
setA.Add( 1 );
setA.Add( 2 );
setA.Add( 3 );
setB.Add( 2 );
setB.Add( 3 );
CSetBitArray setC = new CSetBitArray();
setC = setA.Union(setB);
Console.WriteLine();
Console.WriteLine(setA.ToString());
Console.WriteLine(setC.ToString());
setC = setA.Intersection(setB);
Console.WriteLine(setC.ToString());
setC = setA.Difference(setB);
Console.WriteLine(setC.ToString());
bool flag = setB.IsSubset(setA);
if (flag)
{
Console.WriteLine( " b is a subset of a " );
}
else
{
Console.WriteLine( " b is not a subset of a " );
}
Console.ReadLine();
}
private static void CSet()
{
CSet setA = new CSet();
CSet setB = new CSet();
setA.Add( " milk " );
setA.Add( " eggs " );
setA.Add( " bacon " );
setA.Add( " cereal " );
setB.Add( " bacon " );
setB.Add( " eggs " );
// setB.Add("Bread");
CSet setC = new CSet();
setC = setA.Union(setB);
Console.WriteLine();
Console.WriteLine( " A: " + setA.ToString());
Console.WriteLine( " B: " + setB.ToString());
Console.WriteLine( " A Union B: " + setC.ToString());
setC = setA.Intersection(setB);
Console.WriteLine( " A Intersection B: " + setC.ToString());
setC = setA.Difference(setB);
Console.WriteLine( " A Diff B: " + setC.ToString());
setC = setB.Difference(setA);
Console.WriteLine( " B Intersection A: " + setC.ToString());
if (setB.SubSet(setA))
{
Console.WriteLine( " b is a subset of a " );
}
else
{
Console.WriteLine( " b is not a subset of a " );
}
Console.ReadLine();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Chapter13
{
class Program
{
static void Main( string [] args)
{
CSet();
CSetBitArray();
}
private static void CSetBitArray()
{
CSetBitArray setA = new CSetBitArray();
CSetBitArray setB = new CSetBitArray();
setA.Add( 1 );
setA.Add( 2 );
setA.Add( 3 );
setB.Add( 2 );
setB.Add( 3 );
CSetBitArray setC = new CSetBitArray();
setC = setA.Union(setB);
Console.WriteLine();
Console.WriteLine(setA.ToString());
Console.WriteLine(setC.ToString());
setC = setA.Intersection(setB);
Console.WriteLine(setC.ToString());
setC = setA.Difference(setB);
Console.WriteLine(setC.ToString());
bool flag = setB.IsSubset(setA);
if (flag)
{
Console.WriteLine( " b is a subset of a " );
}
else
{
Console.WriteLine( " b is not a subset of a " );
}
Console.ReadLine();
}
private static void CSet()
{
CSet setA = new CSet();
CSet setB = new CSet();
setA.Add( " milk " );
setA.Add( " eggs " );
setA.Add( " bacon " );
setA.Add( " cereal " );
setB.Add( " bacon " );
setB.Add( " eggs " );
// setB.Add("Bread");
CSet setC = new CSet();
setC = setA.Union(setB);
Console.WriteLine();
Console.WriteLine( " A: " + setA.ToString());
Console.WriteLine( " B: " + setB.ToString());
Console.WriteLine( " A Union B: " + setC.ToString());
setC = setA.Intersection(setB);
Console.WriteLine( " A Intersection B: " + setC.ToString());
setC = setA.Difference(setB);
Console.WriteLine( " A Diff B: " + setC.ToString());
setC = setB.Difference(setA);
Console.WriteLine( " B Intersection A: " + setC.ToString());
if (setB.SubSet(setA))
{
Console.WriteLine( " b is a subset of a " );
}
else
{
Console.WriteLine( " b is not a subset of a " );
}
Console.ReadLine();
}
}
}