无界递归是指我们无法预测递归的次数。例如,很难预测网络爬虫要浏览和下载多少网页。它每发现一个新页面,就会获取更多的链接。我们不是网页的所有者,无法预测每个网页有多少链接。因此网络爬虫的任务可能不减反增。网络爬虫还要留心已经访问过的页面,这样才能避免循环引用和无限递归。网络爬虫面对的这些问题都属无界递归的情况。下图说明了引发无界递归的数据的特点。
图4-3 引发无界递归的数据的特点
我们无法预测完成无界递归所需的步骤。计算机的文件系统与网络环境很相似,也会出现类似的问题。每一个目录都可能包含更多目录。让我们来创建一个检索给定系统目录的程序。创建一个名为Navigator的模块:
函数navigate是入口。假如传入参数..,Path.expand/1会把它转换为完整路径。然后调用go_through函数,用列表的形式传递目录。来看看这个函数:
在go_through/1函数中有一个空目录的终止子句和另一个遍历目录内容的子句。程序会打印目录下每一项的路径,并尝试浏览其子目录。然后进行递归调用,继续浏览其余目录项。让我们详细看看print_and_navigate/2:
此函数子句检查目录标志。如果遇到的不是目录,就停止迭代。否则,会使File.ls!/1列出所有内容。列出目录内容的函数仅返回文件的名称和目录的名称。要检查某些内容是否是目录,还需要该目录的完整路径。然后我们用自定义函数expand_dirs/2对其进行转换。有了完整的路径,就可以用go_through/1函数发现它的内容。这可能需要很长时间。如果您不想等待,请准备好终止程序。让我们试一试:
我们尝试遍历当前目录的父目录的父目录。由于每台计算机的文件系统都不相同,遍历时间会有很大差异。接下来,我们将用两种策略提高递归的可预测性:一种侧重于限制迭代次数,另一种侧重于避免无限循环。(www.xing528.com)
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。