zoukankan      html  css  js  c++  java
  • awk的递归

      版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址
    
      http://www.cnblogs.com/Colin-Cai/p/9082551.html 
    
      作者:窗户
    
      QQ:6679072
    
      E-mail:6679072@qq.com
    

      想来惭愧,之前写的一篇文章《用awk写递归》里多少是传递了错误的信息。虽然那篇文章目的上是为了给出一种思路,但实际上awk是可以支持函数局部变量的。

      awk对于局部变量的支持比起大多数过程式语言来说很是怪异,它只在函数的参数里支持。所以如果想用局部变量,多少需要改变我们以前的一些习惯。

      于是我们使用这一点,就可以直接写出一个awk下面的递归。举个简单的例子,比如我们想输入一个数n,就算出1+2+...n的值。写法如下:

      

    awk '
            function sum(n, other_sum)
            {
                    return n==0?other_sum:sum(n-1, other_sum+n)
            }
            {
                    print sum($1,0)
            }'
    

      sum在这里作为一个递归,接受两个参数,一个是n,一个是之前的累和结果。这种用法很像函数式编程,比如lisp系。

      以Scheme为例

      

    (define (sum n)
       (define (_sum n other_sum)
        (if (= n 0) other_sum (_sum (- n 1) (+ other_sum n))))
       (_sum n 0)
       )

      为了忏悔,我还是用awk写个函数式风格的汉诺塔程序吧。

    #!/usr/bin/awk -f
    function connect(a, b)
    {
            return a "" b
    }function other_pos(a, b)
    {
            return 6-a-b;
    }
    
    function sub1(a)
    {
            return a-1;
    }
    
    function eq(a, b)
    {
            return a==b;
    }
    
    function hanoi2(n, from, to)
    {
            return eq(n,0)? "": connect(connect(connect(hanoi2(sub1(n), from, other_pos(from,to)), " "),connect(from, "->")),connect(connect(to, " "),hanoi2(sub1(n), other_pos(from,to), to)))
    }
    function hanoi(n)
    {
            return hanoi2(n, 1, 3)
    }
    {
            print hanoi($1)
    }

      运行一下,尝试一下8块饼的汉诺塔怎么移动。

      

    $ echo 8 | ./hanoi.awk
    1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 3->1 2->3 2->1 3->1 3->2 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3 2->1 3->1 3->2 1->2 3->1 2->3 2->1 3->1 2->3 1->2 1->3 2->3 1->2 3->1 3->2 1->2 1->3 2->3 2->1 3->1 2->3 1->2 1->3 2->3

      注意,前面写函数式风格的时候,我最终还是使用了三目条件运算符,而没有搭建一个函数 

      function cond_op(cond, a, b)
      {
        return cond?a:b;
      }

      因为如果这样搭建,必然会死循环,想想为什么?

  • 相关阅读:
    Power of Cryptography
    Radar Installation
    Emag eht htiw Em Pleh
    Help Me with the Game
    89. Gray Code
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    82. Remove Duplicates from Sorted List II
  • 原文地址:https://www.cnblogs.com/Colin-Cai/p/9082551.html
Copyright © 2011-2022 走看看