|
|
|
|
移动端

1.1 本书讨论的内容

《数据结构与算法分析:Java语言描述(原书第3版)》第1章引论,在这一章, 我们阐述本书的目的和目标并简要复习离散数学以及程序设计的一些概念。本节为本书讨论的内容。

作者:冯舜玺/陈越 译来源:机械工业出版社|2016-04-13 10:28

第1章 引论

在这一章, 我们阐述本书的目的和目标并简要复习离散数学以及程序设计的一些概念。我们将要:

看到程序对于合理的大量输入的运行性能与其在适量输入下运行性能的同等重要性。

概括为本书其余部分所需要的基本的数学基础。

简要复习递归。

概括用于本书的Java语言的某些重要特点。

1.1 本书讨论的内容

设有一组N个数而要确定其中第k个最大者,我们称之为选择问题(selection problem)。大多数学习过一两门程序设计课程的学生写一个解决这种问题的程序不会有什么困难。“明显的”解决方法是相当多的。

该问题的一种解法就是将这N个数读进一个数组中, 再通过某种简单的算法, 比如冒泡排序法, 以递减顺序将数组排序, 然后返回位置k上的元素。

稍微好一点的算法可以先把前k个元素读入数组并(以递减的顺序)对其排序。接着, 将剩下的元素再逐个读入。当新元素被读到时, 如果它小于数组中的第k个元素则忽略之, 否则就将其放到数组中正确的位置上, 同时将数组中的一个元素挤出数组。当算法终止时, 位于第k个位置上的元素作为答案返回。

这两种算法编码都很简单, 建议读者试一试。此时我们自然要问: 哪个算法更好?哪个算法更重要?还是两个算法都足够好?使用三千万个元素的随机文件和k=15000000进行模拟将发现, 两个算法在合理的时间量内均不能结束; 每种算法都需要计算机处理若干天才能算完(虽然最后还是给出了正确的答案)。在第7章将讨论另一种算法, 该算法将在一秒钟左右给出问题的解。因此, 虽然我们提出的两个算法都能算出结果, 但是它们不能被认为是好的算法, 因为对于第三种算法能够在合理的时间内处理的输入数据量而言, 这两种算法是完全不切实际的。

第二个问题是解决一个流行的字谜。输入是由一些字母构成的一个二维数组以及一组单词组成。目标是要找出字谜中的单词, 这些单词可能是水平、 垂直或沿对角线上任何方向放置的。作为例子, 图1-1所示的字谜由单词this、two、fat和that组成。单词this从第一行第一列的位置即(1,1)处开始并延伸至(1,4); 单词two从(1,1)到(3,1); fat从(4,1)到(2,3); 而that则从(4,4)到(1,1)。

现在至少也有两种直观的算法来求解这个问题。对单词表中的每个单词, 我们检查每一个有序三元组(行、 列、 方向)验证是否有单词存在。这需要大量嵌套的for循环, 但它基本上是直观的算法。

也可以这样, 对于每一个尚未越出谜板边缘的有序四元组(行、 列、 方向、 字符数)我们可以测试是否所指的单词在单词表中。这也导致使用大量嵌套的for循环。如果在任意单词中的最大字符数已知, 那么该算法有可能节省一些时间。

上述两种方法相对来说都不难编码并可求解通常发表于杂志上的许多现实的字谜游戏。这些字谜通常有16行16列以及40个左右的单词。然而, 假设我们把字谜变成为只给字谜板(puzzle board)而单词表基本上是一本英语词典, 则上面提出的两种解法均需要相当长的时间来解决这个问题, 从而这两种方法都是不可接受的。不过, 这样的问题还是有可能在数秒内解决的, 甚至单词表可以很大。

在许多问题当中, 一个重要的观念是: 写出一个工作程序并不够。如果这个程序在巨大的数据集上运行, 那么运行时间就变成了重要的问题。我们将在本书看到对于大量的输入如何估计程序的运行时间, 尤其是如何在尚未具体编码的情况下比较两个程序的运行时间。我们还将看到彻底改进程序速度以及确定程序瓶颈的方法。这些方法将使我们能够发现需要我们集中精力努力优化的那些代码段。

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:342347198

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

网管员必读—超级网管经验谈(第2版)

本书的第1版获得过“2006年度全行业优秀畅销品种奖”。全书共15章,分别介绍了网管员职责和应具备的工作习惯、共享上网与访问控制方法、子...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊