集合的主要操作包括:并集、交集、判断是否为子集、取差异集合。
C# 中没有提供集合数据类型或集合数据结构,用散列表作为基本数据存储是设计集合类型的比较有效的方式。
其中,设计的一个关键就就,要先创造一个临时存储数据的实例,在本代码中,用命名为 temp。
public class CSet
{
Hashtable data;
public CSet() // 实例化一个集合类
{
data = new Hashtable();
}
public void Add(object n) // 向集合中添加元素
{
if (!data.ContainsValue(n))
data.Add(Hash(n), n);
}
public string Hash(object item) // 用来计算向集合中添加的元素的哈希地址
{
char[] c = item.ToString().ToCharArray();
int tot = 0;
for(int i = 0; i < c.Count(); i++)
{
tot += (int)c[i]; // 哈希函数:元素的各个字符的ASCII码值之和
}
return tot.ToString(); // 返回哈希地址
}
public int Size() // 集合的大小
{
return data.Count;
}
public void Remove(object item) // 移除集合中元素
{
if (data.ContainsValue(item))
data.Remove(Hash(item));
}
public CSet Union(CSet cs) // 并集操作
{
CSet temp = new CSet(); // 用 temp 作时候存储,下同
foreach (var item in data.Keys) // 这里要注意一下做判断时,用的都是 key,而不是 value,因
temp.Add(data[item]); // 为散列表的主要就是对 key 进行操作,而不是 value。
foreach (var item in cs.data.Keys)
if (!data.ContainsKey(item))
temp.Add(cs.data[item]);
return temp;
}
public CSet Intersection(CSet cs) // 交集操作
{
CSet temp = new CSet();
foreach(var item in cs.data.Keys)
{
if (data.ContainsKey(item))
temp.Add(cs.data[item]);
}
return temp;
}
public bool Subset(CSet cs) // 判断是否为子集
{
if (cs.Size() < this.Size())
return false;
else
foreach (var item in data.Keys)
if (!cs.data.ContainsKey(item))
return false;
return true;
}
public CSet Different(CSet cs) // 取差异,是本集合中的元素,同时不是用来比较的集合中的元素
{
CSet temp = new CSet();
foreach(var item in data.Keys)
{
if (!cs.data.ContainsKey(item))
temp.Add(data[item]);
}
return temp;
}
public override string ToString() // 覆写 ToString() 方法
{
string s = "";
foreach(var item in data.Keys)
{
s += data[item] + " ";
}
return s;
}
}
class Program
{
static void Main(string[] args)
{
CSet setA = new CSet();
CSet setB = new CSet();
setA.Add("milk");
setA.Add("bacon");
setA.Add("cereal");
setB.Add("bacon");
setB.Add("cereal");
setB.Add("bread");
Console.WriteLine("A: " + setA.ToString());
Console.WriteLine("B: " + setB.ToString());
CSet setC = new CSet();
Console.WriteLine("A union B: " + setA.Union(setB).ToString());
Console.WriteLine("A intersect B: " + setA.Intersection(setB).ToString());
Console.WriteLine("A is a subset of B: " + setA.Subset(setB).ToString());
Console.WriteLine("B diff A: " + setA.Different(setB).ToString());
Console.Read();
}
}
运行结果:
A: bacon cereal milk
B: bread bacon cereal
A union B: bread bacon cereal milk
A intersect B: bacon cereal
A is a subset of B: False
B diff A: milk