永发信息网

函数的迭代

答案:2  悬赏:40  手机版
解决时间 2021-02-14 22:46
  • 提问者网友:疯子也有疯子的情调
  • 2021-02-14 15:26
教一下,详细点,谢谢!
最佳答案
  • 五星知识达人网友:上分大魔王
  • 2021-02-14 16:29
迭代相当于其他语言中的循环,由于LISP语言一切均为函数,所以其迭代也是通过函数实现的。

迭代也是一种主要的函数定义手段,尤其是熟悉象PASCAL这样的过程型语言的用户,可能更习惯于使用迭代而不是递归。使用迭代往往比使用递归效率高和节省内存,但有些问题使用递归要比使用迭代简单、明了。如上面定义过的COUNTATOMS函数,若只单纯地使用迭代,其定义要复杂得多。而且递归是"纯"的LISP定义手法,迭代只是为了增加更多的定义手段才增加到LISP中来的。
最常用到的迭代,是通过PROG函数实现的,PROG函数本身没有什么具体的含义,它只起到一种可以进行迭代的媒介作用。在PROG函数内,可以使用GO函数转到某个给定的标号,也可以通过RETURN函数退出PROG,并使得PROG的返回值为RETURN的参量值。
例如,使用PROG迭代定义阶乘函数:
这里给出的是使用迭代方法,而非递归方法定义的阶乘函数。
(DEFUN N!(n)
通过PROG函数实现迭代,其中的((result 1))定义了一个局部变量result,其初始值为1。该变量只在PROG函数内部有效。在这里变量result用于记录计算的结果。
(PROG((result 1))
LOOP为循环标记,可以通过GO函数返回到这里。LOOP只是一个标记,也可以使用其他的符号表示。这种标记只可以在PROG(或者其他与PROG类似的函数)内部使用。
LOOP
通过条件函数COND定义,当n为0或为1时,回送结果result。其中函数RETURN是跳出PROG的函数。
(COND((= n 0)(RETURN result))
((=n 1)(RETURN result))
其他情况下,将n乘以result,并使得n等于n-1,通过GO函数,跳转到LOOP处,循环执行。
(T(SETQ result(* n result))
(SETQ n(- n 1))
(GO LOOP)))))
紧跟在PROG后面的表,说明了result是一个局部变量,其初始值为1,下面的LOOP是一个标号,当n=0或n=1时,通过RETURN函数,回送result的值,其它情况,将n乘到result上去,并得到n减1,使用GO函数返回到标号LOOP,如此循环往复,直到结束为止。

MAP类函数是LISP语言提供的另一类处理迭代的函数,这类函数的特征是函数名均以MAP开头。当以表的元素为循环主题时,这类函数往往用起来会非常简练和方便。

LISP中还提供了一类隐式迭代函数,这一类函数的函数名均以MAP开头,故称它们为MAP类函数。MAP类函数的一个典型代表是MAPCAR函数。
MAPCAR函数的第一个参量是一个要调用的函数名,其它参量均为表,其它参量的个数等于第一个参量(它是一个函数名)所需要的参量数。MAPCAR的功能是,从第二个参量开始,依次取出各个参量的第i个元素(1≤i≤n,n是各个参量中最短的那个表的长度),然后把它们作为第一个参量的参量进行求值,每次求值的结果形成一张表作为MAPCAR的回送值。

图5.3给出了(MAPCAR '+ '(1 2 3) '(4 5 6))的操作示意图。该图表示,MAPCAR函数依次从两个表中取出对应位置的元素,对他们实行"+"操作(由MAPCAR函数的第一个参数"'+"指定),并将计算结果组成一个表。

(MAPCAR '+ '(1 2 3) '(4 5 6))==>(5 7 9)
它的作用方式可用图5.3表示。
下面,我们使用MAPCAR函数,给出前面已经定义过的COUNTATOMS函数的更简洁的定义。
该例子重写了前面已经定义过的COUNTATOMS函数。在这里使用MAPCAR函数,并与递归相结合,可以看出定义是多么的简练。
(DEFUN COUNTATOMS(s)
(COND((ATOM s)1)
(T(APPLY '+(MAPCAR 'COUNTATOMS s)))))
这里我们用到了APPLY函数,通常APPLY有两个参量,第一个参量是一个函数名,第二个参量是一张表,APPLY的功能是将表中的所有元素做为函数的参量进行求值,并将函数的返回值作为其自己的返回值。
(SETQ L '(1 2))
(APPLY '+ L)==>3

LAMBDA表达式可以定义匿名函数。匿名函数常与MAPCAR等需要函数名作为参数的函数一起使用。LAMBDA函数以匿名的方式定义了一个函数。

有时为了完成更复杂一些的操作,在MAPCAR函数中经常要用到LAMBDA式子。LAMBDA式子可以定义匿名函数,凡是在要求用函数名作为参量的地方,均可以用LAMBDA式子代替。
LAMBDA式子的格式如下:
(LAMBDA(<形参表>){<函数定义体>})
作为使用LAMBDA的例子,我们把COUNTATOMS重新定义如下:
(DEFUN COUNTATOMS(s)
(APPLY '+(MAPCAR '(LAMBDA(x)
(COND((ATOM x)1)
(T(COUNTATOMS x))))s)))
该定义的思路是:将s中的各个元素交给MAPCAR去处理,若某个元素是原子,就记数1,若不是原子(一定是表)就递归调用COUNTATOMS来处理,然后将计算结果加起来作为COUNTATOMS的返回值。
全部回答
  • 1楼网友:动情书生
  • 2021-02-14 17:21
c生成分形树,比较标准的,turboc 编译 #include "math.h" #include "stdio.h" #include "graphics.h" #define pi 3.1415926 void cayley(int n, float x0, float y0, float len, int th) { float x1, y1, x2, y2, x3, y3; int th1 = 20, th2 = 20; float scale = 0.7, dtor = pi / 180, sl = scale * len; if (n == 1) return; x1 = x0 + len * cos(th * dtor); y1 = y0 - len * sin(th * dtor); x2 = x1 + sl * cos((th + th1) * dtor); y2 = y1 - sl * sin((th + th1) * dtor); x3 = x1 + sl * cos((th - th2) * dtor); y3 = y1 - sl * sin((th - th2) * dtor); line(x0, y0, x1, y1); line(x1, y1, x2, y2); line(x1, y1, x3, y3); cayley(n - 1, x1, y1, sl, th + th1); cayley(n - 1, x1, y1, sl, th - th2); } int main(void) { int i; float x = 320.0, y = 470.0; int th = 90, len = 120; int gdriver = detect, gmode; initgraph(&gdriver, &gmode, ""); setcolor(green); for (i = 2; i < 16; i++) { cayley(i, x, y, len, th); getch(); } getch(); closegraph(); } 这样吧 把 函数cayley改成vc用的 #define pi 3.1415926 void cayley(hdc hdc, int n, float x0, float y0, float len, int th, colorref color) { hpen hpen, hpenold; float x1, y1, x2, y2, x3, y3; int th1 = 20, th2 = 20; float scale = 0.7, dtor = pi / 180, sl = scale * len; if (n == 1) return; hpen = createpen(ps_solid, 1, color); hpenold = (hpen)selectobject(hdc, hpen); x1 = x0 + len * cos(th * dtor); y1 = y0 - len * sin(th * dtor); x2 = x1 + sl * cos((th + th1) * dtor); y2 = y1 - sl * sin((th + th1) * dtor); x3 = x1 + sl * cos((th - th2) * dtor); y3 = y1 - sl * sin((th - th2) * dtor); movetoex(hdc, x0, y0, null); lineto(hdc, x1, y1); lineto(x2, y2); movetoex(hdc, x1, y1, null); lineto(hdc, x3, y3); cayley(n - 1, x1, y1, sl, th + th1); cayley(n - 1, x1, y1, sl, th - th2); selectobject(hdc, hpenold); deleteobject(hpen); } vc里直接调用 cayley 就可以了 cayley(hdc hdc, int n, float x0, float y0, float len, int th, colorref color) hdc 是设备描述符 color 是颜色 其他和上边tc程序一样
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯