标签:c#
集合成员是无序的、并且都是只出现一次。
空集合:是不包含任何成员的集合。
全域:是所有可能成员的集合。
联合:两个集合的并集
交叉:两个集合的交集
差异:存在于第一个集合,但不存在于第二个集合,也就是相对补集,A相对B的补集。
集合与空集合的交叉是空集合。集合与空集合的联合是集合本身。
集合与自身的交叉是自身,与自身的联合还是联合。
联合、交叉满足交换律、结合律、分配律。
吸收定律:
集合A联合另一集合B再交叉自身集合A,结果还是集合A。
德摩根定律:
集合A差异(集合B交叉集合C)等于(集合A差异集合B)联合(集合A差异集合B)。
集合A差异(集合B联合集合C)等于(集合A差异集合B) 交叉 (集合A差异集合B)。
实例1:
用散列表可以存储任何类型的数据项。
散列表/哈希表: 它使用键来访问集合中的元素。
当您使用键访问元素时,则使用哈希表,而且您可以识别一个有用的键值。哈希表中的每一项都有一个键/值对。键用于访问集合中的项目。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HashSet
{
public class HashCSet
{
private Hashtable data;
public HashCSet() { data = new Hashtable(); }
///<summary>
///添加一个数据项。Hashtable的值为item,键为item根据内部散列函数计算的散列值。
///</summary>
///<param name="item"></param>
public void Add(Object item)
{
if (!data.ContainsValue(item))
{ data.Add(item, item); }
}
///<summary>
///散列函数,数据项字符的ASCII码值来计算散列值
///</summary>
///<param name="item"></param>
///<returns></returns>
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();
}
public void Remove(object item)
{
data.Remove(Hash(item));
}
public int Size
{
get { return data.Count; }
}
///<summary>
///联合
///</summary>
///<param name="aSet"></param>
///<returns></returns>
public HashCSet Union(HashCSet aSet)
{
HashCSet tempSet = new HashCSet();
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;
}
///<summary>
///返回一个和指定集合交叉的集合
///</summary>
///<param name="aSet"></param>
///<returns></returns>
public HashCSet Intersection(HashCSet aSet)
{
HashCSet tempSet = new HashCSet();
foreach (Object hashObject in data.Keys)
{
if (aSet.data.Contains(hashObject))
tempSet.Add(aSet.data[hashObject]);
}
return tempSet;
}
///<summary>
///是否全部包含在一个集合内。判断当前集合是否是指定集合的一个子集
///</summary>
///<param name="aSet"></param>
///<returns></returns>
public bool Subset(HashCSet aSet)
{
if (this.Size > aSet.Size)
return false;
else
foreach (Object key in this.data.Keys)
if (!(aSet.data.Contains(key)))
return false;
return true;
}
///<summary>
///差异。返回一个和指定集合的差异集合
///</summary>
///<param name="aSet"></param>
///<returns></returns>
public HashCSet Difference(HashCSet aSet)
{
HashCSet tempSet = new HashCSet();
foreach (Object hashObject in data.Keys)
if (!(aSet.data.Contains(hashObject)))
tempSet.Add(data[hashObject]);
return tempSet;
}
public override string ToString()
{
string s = "";
foreach (Object key in data.Keys)
s += data[key] + " ";
return s;
}
}
class Program
{
static void Main(string[] args)
{
//使用实现
//调用:
HashCSet setA = new HashCSet();
HashCSet setB = new HashCSet();
//A
setA.Add("milk");
setA.Add("eggs");
setA.Add("bacon");
setA.Add("cereal");
//B
setB.Add("bacon");
setB.Add("eggs");
setB.Add("bread");
HashCSet setC = new HashCSet();
setC = setA.Union(setB);
Console.WriteLine("A:" + setA.ToString());
Console.WriteLine("B:" + setB.ToString());
Console.WriteLine("A union B:" + setC.ToString());
setC = setA.Intersection(setB);
Console.WriteLine("A intersect B: " + setC.ToString());
setC = setA.Difference(setB);
Console.WriteLine("A diff B:" + setC.ToString());
setC = setB.Difference(setA);
Console.WriteLine("B diff 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");
///A:eggs milkcereal bacon
///B:eggsbacon bread
///A unionB:eggs milk cereal bread bacon
///A intersectB: eggs bacon
///A diffB:cereal milk
///B diffA:bread
///b is not asubset of a
Console.ReadLine();
}
}
}实例2:
BitArray : 它代表了一个使用值 1 和 0 来表示的二进制数组。
当您需要存储位,但是事先不知道位数时,则使用点阵列。您可以使用整型索引从点阵列集合中访问各项,索引从零开始。
当集合存储的数据是整数时,使用BitArray内部实现的Set类,能有更好的性能。
BitArray只存储布尔数值,并且集合的四个操作(联合、交叉、差异、求子集)都可以利用布尔运算符(And、Or和Not)来实现。这些实现比散列表要快许多。
用BitArray来创建整数集合的存储策略如下:
1. 添加数据1到集合中,即为索引位置为1的数组元素为true。
2. 判断数据1是否在集合内,即判断索引位置为1的数组元素是否为true。
3. 两个集合的联合,即两个BitArray的对应索引位置的两个布尔值的”a||b”。(A与B的并集)
4. 两个集合的交叉,即两个BitArray的对应索引位置的两个布尔值的”a&&b”。(A与B的交集)
5. 两个集合的差异,即两个BitArray的对应索引位置的两个布尔值的”a && !b”。(A与B补集的交集)
6. 判断集合A是否是集合B的子集,即两个BitArray的对应索引位置的两个布尔值的”a && !b”有存在ture。(A与B补集的交集为空)
内部实现:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BitArraySet
{
public class BitArraySet
{
private BitArray data;
public BitArraySet()
{
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 BitArraySet SetUnion(BitArraySet aSet)
{
BitArraySet tempSet = new BitArraySet();
for (int i = 0; i <= data.Count - 1; i++)
tempSet.data[i] = (this.data[i] ||aSet.data[i]);
return tempSet;
}
public BitArraySet SetIntersection(BitArraySet aSet)
{
BitArraySet tempSet = new BitArraySet();
for (int i = 0; i <= data.Count - 1; i++)
tempSet.data[i] = (this.data[i] &&aSet.data[i]);
return tempSet;
}
public BitArraySet SetDifference(BitArraySet aSet)
{
BitArraySet tempSet = new BitArraySet();
for (int i = 0; i <= data.Count - 1; i++)
tempSet.data[i] = (this.data[i] &&(!(aSet.data[i])));
return tempSet;
}
public bool IsSubset(BitArraySet aSet)
{
BitArraySet tempSet = new BitArraySet();
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;
}
}
class Program
{
static void Main(string[] args)
{
//使用实现:
//调用:
BitArraySet BsetA = new BitArraySet();
BitArraySet BsetB = new BitArraySet();
///A
BsetA.Add(1);
BsetA.Add(2);
BsetA.Add(3);
///B
BsetB.Add(2);
BsetB.Add(3);
BitArraySet BsetC = new BitArraySet();
BsetC = BsetA.SetUnion(BsetB);
Console.WriteLine();
Console.WriteLine("A:" + BsetA.ToString());
Console.WriteLine("B:" + BsetB.ToString());
Console.WriteLine("A Union B:" + BsetC.ToString());
BsetC = BsetA.SetIntersection(BsetB);
Console.WriteLine("A Intersection B:" + BsetC.ToString());
BsetC = BsetA.SetDifference(BsetB);
Console.WriteLine("A Difference B:" + BsetC.ToString());
bool flag = BsetB.IsSubset(BsetA);
if (flag)
Console.WriteLine("b is a subset of a");
else
Console.WriteLine("b is not a subset of a");
////A:1 2 3
////B:2 3
////A Union B:1 2 3
////A Intersection B:2 3
////A Difference B:1
////b is a subset of a
Console.ReadLine();
}
}
}参考:
https://msdn.microsoft.com/zh-cn/library/7y3x785f
http://blog.csdn.net/maths_bai/article/details/8046590#t16
http://blog.csdn.net/maths_bai/article/details/8046493#_Toc337377703
http://outofmemory.cn/csharp/tutorial/csharp-collection.html
本文出自 “Ricky's Blog” 博客,请务必保留此出处http://57388.blog.51cto.com/47388/1658466
标签:c#
原文地址:http://57388.blog.51cto.com/47388/1658466