算法与数据结构是在讨论什么

来源:互联网 发布:茵曼淘宝网店 编辑:程序博客网 时间:2024/06/09 22:57

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

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

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

这两种算法编码都很简单,建议读者试一试。此时,我们自然要问,哪个算法更好?哪个算法更有价值?还是两个算法都足够好?使用含有100万个元素的随机文件,在k=500000的条件下进行模拟发现,两个算法在合理的时间量内均不能结束;每种算法都需要计算机处理若干天才能完成。其实还有一种算法(以后的博文应该会提及)可以在一秒钟左右就给出问题的解。因此,虽然我们提出的两个算法都能算出结果,但是它们不能被认为是好的算法,因为对于第三种算法在合理的时间内能够处理的输入数据量而言,这两种算法都是完全不切实际的。

第二个问题是解决一个流行的字谜。输入是由一些字母和单词的二维数组组成。目标是要找出字谜中的单词,这些单词可能是水平、垂直或沿对角线以任何方向放置的。可以以下表作为案例,所示的字谜由单词this、two、fat和what组成。

 12341this2wats3oahg4fgdt

单词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个左右的单词。然而,假设我们把字谜编程为只给出谜板而单词表基本上是一本英语词典,则上面提出的两种解法需要相当可观的时间来解决这个问题,故这两种方法都是不可接受的。不过,这样的问题还是有可能在数秒内解决的,即使单词表很大也可以。

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

0 0
原创粉丝点击