设为首页 加入收藏

TOP

2.1 递归解决方案(2)
2014-03-11 13:05:27 来源: 作者: 【 】 浏览:177
Tags:2.1 解决方案

2.1  递归解决方案(2)

上面的查找策略将使查找单词的问题范围缩减到半本词典,如图2-1所示。此处要注意两个要点。首先,一旦将词典分成两部分,就会知道怎样继续在其中一半查找:使用与查找整本词典相同的策略,再查找下一个中间页。其次,要注意存在特殊情况:经过多次折半查找,最后只剩一页未查,无法继续分割。在此情况下,问题的规模非常小,可以直接在所余单页中查找单词。这种特殊情况就是所谓的基例(base case,也称基本实例或退化实例)。

注释:基例是一种特殊情况,其解决方案已知

这是一种分而治之的策略。首先将词典分成两半,然后操作正确的一半,从而解决词典查找问题。通过相同的分而治之策略解决更小的问题,划分将一直进行,直至到达基例。您将会看到,这是很多递归解决方案的固有策略。

注释:折半查找使用分而治之的策略

为进一步探讨词典问题解决方案的本质,请看下面稍微严格一些的描述:
 

  1. search(aDictionary: Dictionary, word: string)  
  2. if (aDictionary is one page in size)  
  3. Scan the page for word  
  4. else  
  5. {  
  6. Open aDictionary to a point near the middle  
  7. Determine which half of aDictionary contains word  
  8. if (word is in the first half of aDictionary)  
  9. search(first half of aDictionary, word)  
  10. else  
  11. search(second half of aDictionary, word)  
  12. }  

把这个解决方案编写成一个函数,可观察到几个非常重要的问题:

1. 这个函数的一个操作是调用自身。也就是说,函数search调用函数search。这个操作就形成了递归。该方案的策略是将aDictionary分成两半,并确定哪一半包含单词word,再将相同策略应用于包含单词的一半。

2. 每次在函数search中递归调用函数search时传递的词典范围是上次递归的一半。换句话说,每调用函数search(aDictionary, word)一次,aDictionary的大小就减半。该函数通过解决另一个本质相同但规模更小的查找问题,解决了初始的问题。

3. 有一个查找问题的处理方式不同于其他所有问题。当aDictionary仅含一页时,就使用另一种技术:在该页直接查找单词。查找单页是查找问题的基例。当到达基例时,递归调用停止并直接解决问题。

4. 问题规模不断减小的方式确保了最终能到达基例。

注释:递归函数调用自身

每次递归调用都会解决一个同类但是规模较小的问题

测试基例使得递归调用能够停止

最后,某个较小的问题必然是基例

上面描述了递归解决方案的一般形式。并不是所有递归解决方案都如上例一样完全符合这些标准,但是相似性远大于差异性。当试图创建递归解决方案时,要牢记以下4个问题。

提示:创建递归解决方案的4个问题

1. 怎样根据同类型的更小问题来定义问题?

2. 每次递归调用是如何减小问题规模的?

3. 哪个问题实例可用作基例?

4. 随着问题规模的减小,最终能否到达基例?

现在来看两个相对简单的问题:计算数字的阶乘和逆置字符串。这些递归解决方案进一步阐明了词典查找问题所引出的要点,同时演示了返回值的递归值函数和递归void函数之间的区别。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2.1 递归解决方案(1) 下一篇2.2.1 递归值函数:n的阶乘(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·HTTPS 详解一:附带 (2025-12-26 02:20:37)
·TCP/IP协议到底在讲 (2025-12-26 02:20:34)
·TCP和UDP在socket编 (2025-12-26 02:20:32)
·有没有适合新手练习 (2025-12-26 01:48:47)
·用清华镜像网怎么下 (2025-12-26 01:48:44)