《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅲ
3.1.3 用例举例
在学习它的实现之前我们还是应该先看看如何使用它。相应的我们这里考察两个用例:一个用来跟踪算法在小规模输入下的行为测试用例和一个来寻找更高效的实现的性能测试用例。
3.1.3.1 行为测试用例
为了在小规模的的输入下跟踪算法的行为,我们用一下测试用例测试我们对符号表的所有实现。这段代码会从标准输入接受多个字符串,构造一张符号表来将i 和第i 个字符串相关联,然后打印符号表。我们假设所有的字符串都只有一个字母。一般我们会使用”S E A R C H E X A M P L E”。按照我们的约定,用例会将键S和0,键R和3关联起来,等等。但E的值是12(而非1或者6),A的值为8(而非2),因为我们的关联性数组以为着每个键的顺序是不确定的(这和具体实现有关);对于有序符号表,用例应该将键按顺序打印出来。这是一种引索用例,,它是我们将在后面讨论的一种重要的符号表应用的一个特殊情况。
测试用例的实现代码如下所示。测试用例的键、值及输出如下图所示。
3.1.3.2 性能测试用例
FrequencyCounter用例会从标准输入中得到的一列字符串并记录每个(长度至少达到指定的数值)字符串的出现次数,然后遍历所有键并找出出现频率最高的键。这是一种字典。这个用例回答了一个简单的问题:哪个(不小于指定长度的)单词在一段文字中出现的频率最高?在本章中,我们会用这个用例以及三段文字来进行行能呢个测试:狄更斯的《双城记》中的第五行(tinyTale.txt),《双城记》全书(tale.txt),以及一个知名的叫做Leipzig Corpora Collection 的数据库(Leipzig1M.txt)。
public class FrequencyCounter { /**
* Reads in a command-line integer and sequence of words from
* standard input and prints out a word (whose length exceeds
* the threshold) that occurs most frequently to standard output.
* It also prints out the number of words whose length exceeds
* the threshold and the number of distinct such words.
*/
public static void main(String[] args) {
int distinct = 0, words = 0;
int minlen = Integer.parseInt(args[0]);
ST<String, Integer> st = new ST<String, Integer>(); // compute frequency counts
while (!StdIn.isEmpty()) {
String key = StdIn.readString();
if (key.length() < minlen) continue;
words++;
if (st.contains(key)) {
st.put(key, st.get(key) + 1);
}
else {
st.put(key, 1);
distinct++;
}
} // find a key with the highest frequency count
String max = "";
st.put(max, 0);
for (String word : st.keys()) {
if (st.get(word) > st.get(max))
max = word;
} StdOut.println(max + " " + st.get(max));
StdOut.println("distinct = " + distinct);
StdOut.println("words = " + words);
}
}
以上代码为符号表的用例,该用例统计了标准输入中各个单词的出现频率,然后将频率最高的单词打印出来。命令行参数指定了表中的键的最短长度。
研究符号表处理大型文本的性能要考虑来两个方面的因素:首先,每个单吃都会被作为键进行搜索,因此处理性能和输入文本的单词总量必然有关;其次,输入的每个电磁都会被存入符号表(输入中不重复单词的总数也就是所有键都被插入以后符号表的大小),因此输入流中的不同的单词的总数也是相关的。我们需要这两个量来估计FrequencyCounter的运行时间。我们会在学习了一些算法之后再回头说明一些细节,但你应该对类似这样的符号表应用的需求有一个大致的印象。
很多例子都提出了一个简单的问题:我们的实现能够在一张用多次get()和put()方法构造出的巨型符号表中进行大量的get()操作吗?如果我们的查找操作不多,那么任意实现都能够满足需要。但没有一个高效的符号表作为基础是无法使用FrequencyCounter这样的程序来处理大型问题的。FrequencyCounter是一种极为常见的应用的代表,它的这些特性也是许多其他符号表应用的共性:
混合使用查找和插入的操作
大量的不同键
查找操作比插入操作多得多
虽然不可预测,但查找和插入操作的使用模式并非随机
我们的目标就是实现一种符号表来满足这些能够解决典型的实际问题的用例需要。
《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅲ的更多相关文章
- 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅳ
3.1.4 无序链表中的顺序查找 符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对,如以下代码所示.get()的实现即为遍历链表,用equals()方法比较需被查找的键和每个节点中的 ...
- 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅱ
3.1.2 有序的符号表 典型的应用程序中,键都是Comparable的对象,因此可以使用a.compare(b)来比较a和b两个键.许多符号表的实现都利用Comparable接口带来的键的有序性来更 ...
- 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅰ
3.1符号表 符号表最主要的目的就是将一个键和一个值联系起来.用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键值姐找到对应的值.要实现符号表,我们首先要定义其背后的数据结构, ...
- 符号表(Symbol Tables)
小时候我们都翻过词典,现在接触过电脑的人大多数都会用文字处理软件(例如微软的word,附带拼写检查).拼写检查本身也是一个词典,只不过容量比较小.现实生活中有许多词典的应用: 拼写检查 数据库管理应用 ...
- C++Primer 4th edition读书笔记-第二章
1 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一个定义.声明用于向程序表明变量的名字和类型.定义也是声明:当定义变量时,我们声明了它的类型和名字.可以通过使用 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅶ(延伸:堆排序的实现)
2.4.5 堆排序 我们可以把任意优先队列变成一种排序方法.将所有元素插入一个查找最小元素的有限队列,然后再重复调用删除最小元素的操作来将他们按顺序删去.用无序数组实现的优先队列这么做相当于进行一次插 ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ
· 学后心得体会与部分习题实现 心得体会: 曾经只是了解了优先队列的基本性质,并会调用C++ STL库中的priority_queue以及 java.util.PriorityQueue<E&g ...
- 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ
命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...
- 《C++ Primer 4th》读书笔记 序
注:本系列读书笔记是博主写作于两三年前的,所以是基于<C++ Primer>第四版的,目前该书已更新至第五版,第五版是基于C++11标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...
随机推荐
- python3-day3(函数-参数)
1.参数 函数的核心是参数传值,其次是返回值,熟练这两这个技术即可灵活使用函数. 1>普通参数 def show(name): print(name) show('tom') 2>默认参 ...
- Webservice-Java-Xfire
最近公司最近需要将以前提供出去的接口统一用一个标准来实现,考虑到webservice这个是标 准,因此我花时间大概学习了一下webservice,也对JAVA的几个webservice框架进行了一些小 ...
- Javascript&Jquery获取浏览器和屏幕各种高度宽度方法总结及运用
<js篇> Javascript获取浏览器和屏幕各种高度宽度方法总结 document.body.clientWidth //网页可见区域宽(body) document.bo ...
- .net网站开发(一):1.input表单元素
其实,在半年前我对网站开发还是完全不感冒的,不是没认识,而是只认识到表面.我以为网站模型就那几样,新闻.论坛.博客啥的,仿个站出来有什么意思?但现在我是知道了,大多应用开发还是采用B/S架构的,包括服 ...
- hdu 4666 Hyperspace
曼哈顿距离,两个点设为(x1,y1),(x2,y2),其距离为|x1-x2|+|y1-y2| #include <cstdio> #include <set> #include ...
- VMware vSphere 5.5的12个更新亮点(1)
[IT专家网虚拟化]在VMworld 2013大会上发布的VMware vSphere 5.5版本提供的增强和改进,横跨从hypervisor到管理整个堆栈,提升了VMware的性能.可伸缩性和可用性 ...
- [Node.js] Use "prestart" in scripts
Usually we run : npm start to start an app, then we we might call other script to do something: npm ...
- 使用apktool解包和打包apk
使用apktool解包和打包apk 下载apktool工具 解包 apktool d xxx.apk -f 植入代码 使用apktool解包要植入代码的apk(下面称为A), 使用apktool解包包 ...
- sealed 修饰符
当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承. 在下面的示例中,类 B 从类 A 继承,但是任何类都不能从类 B 继承. class A {} sealed class B ...
- android内存优化之图片压缩和缓存
由于手机内存的限制和网络流量的费用现在,我们在加载图片的时候,必须要做好图片的压缩和缓存. 图片缓存机制一般有2种,软引用和内存缓存技术. 1.压缩图片:压缩图片要既不能模糊,也不能拉伸图片. 图片操 ...