永发信息网

函数的迭代

答案:2  悬赏:40  手机版
解决时间 2021-02-14 22:46
教一下,详细点,谢谢!
最佳答案
迭代相当于其他语言中的循环,由于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的返回值。
全部回答
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程序一样
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
脑筋急转弯 不翼而飞(猜一字)
欧泰卫浴地址在什么地方,想过去办事
cf购买蓝天白云名片不需要qq号吗
国际贸易公司名称大全
小涧寺山在什么地方啊,我要过去处理事情
从金华到台州的汽车都有几点发车的?
一个容量为502.4升的圆柱形铁桶
【家蚕.蝗虫家蚕和蝗虫的生殖发育流程图....
美食美客酒店地址在哪,我要去那里办事
有个小的汽油机水泵拉不着火
求个沙盘3.442版!!别搞错了 是3.442版!!
怎么用鸡肝钓鱼 鸡肝做饵料钓鱼
斗里在哪里啊,我有事要去这个地方
真铜门和仿铜门 你知道怎么分辨吗
贝肉和什么搭配包饺子好吃
推荐资讯
永诚汽车装潢地址在什么地方,我要处理点事
洛克公园(折扣店)怎么去啊,我要去那办事
葫芦岛连山区炼油第一中学地址在哪,我要去那
汇峰广场停车场(出口)地址好找么,我有些事要
生活在横断山区的傈傈族同胞为在大山上发明了
妆点佳人怎么去啊,我要去那办事
一只毛笔和一张黄纸,打一成语疯狂
慧鱼创新学院和凤凰机器人是一家的吗?
为什么手机网易彩票上的彩种都是暂停销售的。
十八子美容美发地址在什么地方,想过去办事
请问,头皮很痒怎么办?,勤洗头,也用不同的来
老字号李怀马林薄饼卷肉在哪里啊,我有事要去
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?