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)-Ⅲ的更多相关文章

  1. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅳ

    3.1.4 无序链表中的顺序查找 符号表中使用的数据结构的一个简单选择是链表,每个结点存储一个键值对,如以下代码所示.get()的实现即为遍历链表,用equals()方法比较需被查找的键和每个节点中的 ...

  2. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅱ

    3.1.2 有序的符号表 典型的应用程序中,键都是Comparable的对象,因此可以使用a.compare(b)来比较a和b两个键.许多符号表的实现都利用Comparable接口带来的键的有序性来更 ...

  3. 《Algorithms 4th Edition》读书笔记——3.1 符号表(Elementary Symbol Tables)-Ⅰ

    3.1符号表 符号表最主要的目的就是将一个键和一个值联系起来.用例能够将一个键值对插入符号表并希望在之后能够从符号表的所有键值对中按照键值姐找到对应的值.要实现符号表,我们首先要定义其背后的数据结构, ...

  4. 符号表(Symbol Tables)

    小时候我们都翻过词典,现在接触过电脑的人大多数都会用文字处理软件(例如微软的word,附带拼写检查).拼写检查本身也是一个词典,只不过容量比较小.现实生活中有许多词典的应用: 拼写检查 数据库管理应用 ...

  5. C++Primer 4th edition读书笔记-第二章

    1 变量的定义用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一个定义.声明用于向程序表明变量的名字和类型.定义也是声明:当定义变量时,我们声明了它的类型和名字.可以通过使用 ...

  6. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅶ(延伸:堆排序的实现)

    2.4.5 堆排序 我们可以把任意优先队列变成一种排序方法.将所有元素插入一个查找最小元素的有限队列,然后再重复调用删除最小元素的操作来将他们按顺序删去.用无序数组实现的优先队列这么做相当于进行一次插 ...

  7. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅵ

    · 学后心得体会与部分习题实现 心得体会: 曾经只是了解了优先队列的基本性质,并会调用C++ STL库中的priority_queue以及 java.util.PriorityQueue<E&g ...

  8. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ

    命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...

  9. 《C++ Primer 4th》读书笔记 序

    注:本系列读书笔记是博主写作于两三年前的,所以是基于<C++ Primer>第四版的,目前该书已更新至第五版,第五版是基于C++11标准的,貌似更新挺多的.博主今年应届硕士毕业,如若过阵子 ...

随机推荐

  1. pyglet: a cross-platform windowing and multimedia

    pyglet pyglet: a cross-platform windowing and multimedia library for Python.

  2. H5页面音频自动播放问题

        最近有这么一个需求,需要在手机加载一个页面的时候,自动播放音乐资源.一般情况下,这个问题也就解决了,但是要保证各种手机上表现一致,那就相当困难了,至少要费点儿周折.       下面有三种常规 ...

  3. Linux一个简单的读写文件

    (1)linux中的文件描述符fd的合法范围是或者一个正正数,不可能是一个负数. (2)open返回的fd程序必须记录好,以后向这个文件的所有操作都要靠这个fd去对应这个文件,最后关闭文件时也需要fd ...

  4. art.dialog

    关闭指定弹出窗: art.dialog({ id: 'hetong' }).close(); 关闭所有的iframe弹出窗,art.dia.close();

  5. C++ Primer 学习笔记_77_模板与泛型编程 --实例化

    模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实 ...

  6. C#使用checked关键字处理"溢出"错误

    代码如下: private void btnCalculate_Click(object sender, EventArgs e) { byte num1, num2;//定义两个byte变量 if( ...

  7. SQL函数简述

    数字函数ABS 取绝对值 POWER 乘方 LN 10为底数取幂SQRT 平方根 EXP e的n次乘方 LOG(m,n) m为底数n取幂数学运算函数:ACOS ATAN ATAN2 COS COSH ...

  8. python - 类的字段

    一.静态字段:保存在类里面 1.创建静态字段: class Foo: CC = 123 # 字段(静态字段),保存在类里 def __init__(self): self.name = 'alex' ...

  9. oracle 的服务器进程(PMON, SMON,CKPT,DBWn,LGWR,ARCn)

    来着TOM的<oracle 编程艺术 9i,10g,11g> PMON PMON,进程监视.PMON主要有3个用途: 1,在进程非正常中断后,做清理工作.例如:dedicated serv ...

  10. 【mac osx安装opencv,python总结】

    在macosx下安装opencv,最大的困难在于协调python版本.由于在opencv官网上,强烈建议安装完整版的python(不建议使用mac 内置的python),所以会碰到这个多个python ...