1 符号表基本API
符号表(symbol table)是一种将每一个值(value)和一个特定键(key)匹配的数据结构。这一“键-值”匹配有很广泛的应用。如DNS解析要根据给出URL(键)找出对应IP(值)。
要实现符号表,需要实现两个基本操作:
1 put() 插入一个值和其对应的键
2 get() 找出对应一个键的值
这一点可以类比数组。数组从某种程度上讲就是一个符号表,其中对应的键是从0开始的正整数,我们可以通过访问键获得数组该位置的数值。因此,符号表的查找就类似于 a[key] = value
实现符号表一个遵循几个原则:
1 值不可为null
2 如果get() 给出一个不存在的键作为参数,返回null
3 如果put()给出的参数键已经对应一个值,覆盖其
2 数据类型
实现符号表类,值就是一个泛型变量
键建议继承Comparable类,实现compareTo()方法。这么做可以对键进行排序,提高一些操作的效率,并且支持更多操作。另外,一般来说用户设置符号表的键时一般都会使用有序数值。
键要使用不可修改类型,如基础数据类型封装类(Integer Double), String等
键可以实现equals()方法。equals()是java普遍超类Object类实现的方法, Object类里equals()含义为判断两个引用是否指代同一对象(相当于= =),这里要对其覆盖以实现自定义比较功能。equals()方法编写遵循几个规定:
1 x.equals(x) true
2 x.equals(y) && y.equals(z) -> x.equals(z)
3 x.equals(y) -> y.equals(x)
// 以上这三条说白了就是equals()的对象是全序关系
4 x.equals(null) 恒为false
5 equals()方法的参数必须为Object, 不过可以在方法内部进行向下转换
6 要保证比较对象在同一类,即 y.getClass() == this.getClass()
一般来说,基础数据类型进行比较使用==, 对象使用equals(), 数组则要调用Arrays.equals(a, b)
3 应用示例:频率计数器
输入大量随机词,找出里面长度大于给定值k的出现频率最高的词
在这里,我们使用符号表储存每一个单词作为键,其值对应该字符出现次数。没遇到一个单词访问符号表,如不存在该键新建一个“键-值”对,键为该字符,值为1,否则把该键对应的值加一,最后遍历符号表找出最大值。这样操作可以实现时间复杂度O(N)的查找。