概述
- 集合ADT,表示一种非顺序容器,且容器内的元素不重复。
- 其实就是将数学里的概念应用到计算机。
复习一下数学里的集合概念。
- 并操作:
- 交操作:
- 差操作:
其实数据结构中的set,也是类似的,求两个集合的并,交,差等,它的重头是在它的那些方法,结构本身没有多少特点,我们不用把它想的太复杂。
实现
实现集合的方式有很多种,数组,链表等。《数据结构与算法分析》那本书里实现的是不相交集(并查集),我会在下一篇文章讲它。
这里我们用链表来实现,先看类的声明:
template<typename T>
class set {
public:
set();
virtual ~set();
public:
// public interface
void insert( const T& data );
void remove( const T& data );
bool find( const T& data );
bool isSubset( const set<T> &a );
bool isEqual( const set<T> &a );
bool isEmpty();
const T traversal();
public:
list<T> container_;
}
template<typename T>
const set<T> set_union( set<T> &a, set<T> &b )...
template<typename T>
const set<T> set_difference( set<T> &a, set<T> &b )...
template<typename T>
const set<T> set_intersection( set<T> &a, set<T> &b )...
每个函数都很简单,因为用了STL和泛型算法,看一个set_union
函数吧。思路就是建一个新集合,将a复制过去,然后将b中的元素插进去,insert函数会检测插入的值是否重复,所以不用担心破坏了集合规则。
template<typename T>
const set<T> set_union( set<T> &a, set<T> &b ) {
set<T> result;
result = a;
for(auto i : b.container_) {
result.insert(i);
}
return result;
}
其他的函数都大同小异,都是在这个list
上的操作,就不一一展开讲了。
应用
Spell Checker。我们写Word的时候,会有拼写错误提示,你有没有想过它是怎么实现的呢。简单的来想一下,就是两份文件,一份是代表单词字典的文件,一份是我们的输入文件,它们都被加载到各自的hash表里,然后求它们的交集,再把交集和输入文件去比较,把错的单词找出来。当然,实际的实现绝对很复杂,因为还要考虑语法等因素。
参考
http://blog.csdn.net/ab198604/article/details/8473709
http://www.slideshare.net/Tech_MX/set-data-structure-i
https://en.wikipedia.org/wiki/Set_(abstract_data_type)#Dynamic_sets
https://en.wikipedia.org/wiki/Spell_checker#Design