草庐IT

递归

大龙10 2023-03-28 原文

书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
第8章目录

8.2 递归

1、康托尔集

  • 1883年,德国数学家格奥尔格·康托尔开发了一套用于构建无穷集合的简单规则。


2、有限递归

  • 这套规则有一个反馈回路。把一条线段分成两条线段,把得到的线段再分成两条,最终将得到4条线段。再将同样的规则作用在这4条线段上,你会得到8条线段。
  • 这种连续地在结果上重复应用某个规则的过程就称为递归。
  • 康托尔十分关心无数次作用规则后产生的结果。
    但我们只关心有限的像素空间,通常会忽略无限递归的问题。
  • 因此我们应该用代码建立一套有限递归机制,而不是无限地在结果上运用规则(这会让程序崩溃)。

3、代码实现

  • 以下代码是我们常做的事——在一个函数中调用另一个函数。
void someFunction() {
    background(0); 在函数someFunction()中调用background()函数
}
  • 如果我们在函数中调用自身,会发生什么?
    调用自身的函数称为递归函数,它能有效地解决某些特定问题。
  • 某些数学计算就是用递归实现的,最常见的例子就是阶乘。
    用更一般的方式表示,对任意正整数n,都有:
  • n的阶乘被定义为n乘以n-1的阶乘。阶乘的定义中也包含阶乘
int factorial(int n) {
      if (n == 1){
          return 1;
      } else {
          return n * factorial(n-1);
      }
}

4、示例

示例代码8-2 两次递归
用更复杂的方式实现drawCircle()函数:对于任意圆圈,在它的左右两边分别画一个半径减半的圆圈。

void setup() {
  size(640,360);  
}

void draw() {
  background(255);
  drawCircle(width/2,height/2,400); 
  noLoop();
}

// Recursive function
void drawCircle(float x, float y, float r) {
  stroke(0);
  noFill();
  ellipse(x, y, r, r);
  if(r > 2) {
    // Now we draw two more circles, one to the left
    // and one to the right
    drawCircle(x + r/2, y, r/2);
    drawCircle(x - r/2, y, r/2);
  }
}

5、运行结果

有关递归的更多相关文章

  1. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

  2. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  3. ruby - 为什么我用递归得到 "stack level too deep"? - 2

    我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大

  4. ruby - 构建网络蜘蛛时,应该使用递归吗? - 2

    构建一个深度优先的网络蜘蛛,这意味着它将访问第一页上的所有链接,然后转到每个链接,并访问所有第二页上的链接...你应该使用递归吗?我发现这是CPU密集型的。defrecursion()linkz_on_first_page.eachdo|link|recursion(link)endendrecursion(firstpage) 最佳答案 绝对不是,由于万维网的实际性质,您很快就会遇到问题。当您访问带有主导航部分的网站时,每个页面都链接到其他页面,您就进入了一个无限循环。您可以跟踪您处理了哪些链接,但即便如此,递归循环并不真正适合万

  5. ruby-on-rails - 如何以递归方式将 YAML 文件扁平化为 JSON 对象,其中键是点分隔的字符串? - 2

    例如,如果我有YAML文件en:questions:new:'NewQuestion'other:recent:'Recent'old:'Old'这最终会变成一个json对象,例如{'questions.new':'NewQuestion','questions.other.recent':'Recent','questions.other.old':'Old'} 最佳答案 由于问题是关于在Rails应用程序上使用YAML文件进行i18n,因此值得注意i18ngem提供了一个辅助模块I18n::Backend::Flatten完全像

  6. ruby - 为什么尾递归 gcd 比 rubinius 的 while 循环更快 - 2

    我有这两个gcd函数的实现:defgcd1(a,b)ifa==baelsifa>bif(a%b)==0belsegcd1(a%b,b)endelseif(b%a)==0aelsegcd1(a,b%a)endendenddefgcd2(a,b)if(a==b)returnaelsifb>amin,max=a,belsemin,max=b,aendwhile(max%min)!=0min,max=max%min,minendminend函数gcd1是尾递归的,而gcd2使用while循环。我已经验证rubinius通过对阶乘函数进行基准测试来执行TCO,只有阶乘函数基准测试显示递归版本和迭

  7. ruby-on-rails - 为什么我的 helper 递归方法不返回每个值? - 2

    我想显示一个由gem祖先管理的类别树。我想使用一个助手,它会递归地遍历树并一个一个地返回类别,暂时没有html标签或内容。moduleCategoriesHelperdefdisplay_tree(category)ifcategory.has_children?category.children.eachdo|sub_category|display_tree(sub_category)puts(sub_category.name)#tocheckifitgoeshereendendcategory.nameendendcategory参数是根类别之一。它应该返回什么?在网页中:它仅

  8. ruby - 如何处理树顶左递归 - 2

    我有一个grammarfile对于我正在尝试构建的一种新的通用编程语言。我正在努力使该语言健壮且易于使用(它深受Ruby等启发),为此我引入了一些左递归规则。我看到一些例子似乎表明了以下左递归规则:rulel_recursel_recurse/'somethingelse'end可以通过将其更改为非左递归:ruler_recurse'somethingelse'/r_recurseend对我来说,这看起来会有不同的问题并且仍然会失败。我是对的,还是这会“奏效”?我试图(查找和)消除的特定左递归可以在这个grammarfile中找到.我不确定哪些规则受到影响,但至少somewerepoi

  9. ruby - 如何递归 rake ? -- 或合适的替代品 - 2

    我希望我的项目的顶级Rakefile使用树中更深的rakefile来构建东西;即顶层rakefile说明如何构建项目(大图),而较低层的rakefile说明如何构建特定模块(本map片)。当然有一组共享的配置,用于在任务之间共享时执行的详细信息:所以它主要是关于保持对需要构建的内容的描述,尽可能接近正在构建的源。例如。/Source/Module/code.foo和cie应该使用/Source/Module/Rakefile中的指令构建;并且/Rakefile了解模块之间的依赖关系。我不关心它是否使用多个rake进程(ala递归make),或者只是创建单独的构建环境。无论哪种方式,它都

  10. Ruby 递归问题 - 2

    我想知道为什么第一种阶乘方法在ruby​​中不起作用(无限循环)而第二种方法却起作用。deffac(x)ifx==0return1elsereturn(fac(x-1)*x)endenddeffact(num)return1ifnum==0fact(num-1)*numend 最佳答案 区别在于方法名称后的空格,而不是您构造if-else的方式。fac(x-1)*x被解析为fac((x-1)*x)。基本上,如果方法名称后跟一个空格(或任何不是左括号的标记),ruby会假定您调用的方法不带括号。因此它将x-1周围的括号解释为分组,而不

随机推荐