CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  新手乐园

受限制的链表操作,新人们,来练习,200分奖励!

楼主dot99(又来混CSDN来了)2006-03-19 04:08:58 在 C/C++ / 新手乐园 提问

[SICP]中有一个练习,"反向一个list",在Lisp中,一个list是由多个有序对构成,描述如下:  
      list:   (1,   2,   3,   4)  
      为有序对  
      (1   (2   (3   (4,   null))))  
      Lisp提供了有序对的三种操作,  
      cons(a,   b),   以   a,   b构造有序对(a,b)  
      car(t),   取得有序对t的第一个元素,   car(cons(a,b))   ==   a  
      cdr(t),   取得有序对t的第二个元素,   cdr(cons(a,b))   ==   b  
      列表(1,2,3,4)由  
      t   =   cons(1,   cons(2,   cons(3,   cons(4,   NULL))))  
      构成,   car(t)   ==   1,   cdr(t)   ==   (2,   3,   4)。  
   
      假设,在C++中,使用如下代码完成类似Lisp的有序对:  
   
      (代码见后)  
   
  (main函数里面是一个简短的测试代码)  
   
  题目是,只使用如上car,   cdr函数,完成下列函数:  
  1.   int   length(node*   p);   //求list的长度  
  2.   node*   append(node*   p1,   node*   p2);   //将p2附加到p1后,且符合list的定义  
  3.   node*   last_pair(node*   p);   //返回最后一个有序对,   i.e.     (1,   (2,   (3,   null)))   返回   (3,   null)  
  4.   node*   reverse(node*   p);   //将p反向,i.e.   (1,   (2,   (3,   null)))   ->   (3,   (2,   (1,   null)))  
   
  要求,当然是代码精简,思路明确。  
   
  #include   <iostream>  
   
  struct   node  
  {  
      union   {  
          int   car_v;  
          node*   car_p;  
      };  
      int   type_car;  
      union   {  
          int   cdr_v;  
          node*   cdr_p;  
      };  
      int   type_cdr;  
  };  
   
  const   int   type_node   =   1;  
  const   int   type_int   =   2;  
   
  struct   ret  
  {  
      union   {  
                  node*   p;  
                  int   v;  
      };  
      int   type;  
  };  
   
   
  ret   car(const   node*);  
  ret   cdr(const   node*);  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   node&   n);  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   ret&   r)  
  {  
      if   (r.type   ==   type_int)   {  
                  s   <<   r.v;  
      }   else   {  
                  if   (r.p   !=   0)  
                      s   <<   *(r.p);  
                  else  
                      s   <<   "null";  
      }  
      return   s;  
  }  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   node&   n)  
  {  
      s   <<   "("   <<   car(&n)   <<   ",   "   <<   cdr(&n)   <<   ")";  
      return   s;  
  }  
   
   
  node*   cons(int   car,   node*   cdr)  
  {  
      node   n;  
      n.car_v   =   car;  
      n.type_car   =   type_int;  
      n.cdr_p   =   cdr;  
      n.type_cdr   =   type_node;  
      return   new   node(n);  
  }  
  node*   cons(node*   car,   int   cdr)  
  {  
      node   n;  
      n.car_p   =   car;  
      n.type_car   =   type_node;  
      n.cdr_v   =   cdr;  
      n.type_cdr   =   type_int;  
      return   new   node(n);  
  }  
   
  node*   cons(int   car,   int   cdr)  
  {  
      node   n;  
      n.car_v   =   car;  
      n.type_car   =   type_int;  
      n.cdr_v   =   cdr;  
      n.type_cdr   =   type_int;  
      return   new   node(n);  
  }  
  node*   cons(node*   car,   node*   cdr)  
  {  
      node   n;  
      n.car_p   =   car;  
      n.type_car   =   type_node;  
      n.cdr_p   =   cdr;  
      n.type_cdr   =   type_node;  
      return   new   node(n);  
  }  
   
  ret   car(const   node*   p)  
  {  
      ret   r;  
      r.v   =   p->car_v;  
      r.type   =   p->type_car;  
      return   r;  
  }  
   
  ret   cdr(const   node*   p)  
  {  
      ret   r;  
      r.v   =   p->cdr_v;  
      r.type   =   p->type_cdr;  
      return   r;  
  }  
   
  void   rel(node*   p)  
  {  
      if   (p   ==   0)   return;  
      ret   r   =   car(p);  
      if   (r.type   ==   type_node)  
                  rel(r.p);  
      r   =   cdr(p);  
      if   (r.type   ==   type_node)  
                  rel(r.p);  
      delete   p;  
  }  
   
  int   main()  
  {  
      node*   p   =   cons(1,   2);  
      std::cout   <<   *p   <<   std::endl;  
      node*   plist   =   cons(1,   cons(2,   cons(3,   (node*)0)));  
      std::cout   <<   *plist   <<   std::endl;  
      rel(p);  
      rel(plist);  
      return   0;  
  }  
   
  问题点数:200、回复次数:36Top

1 楼dot99(又来混CSDN来了)回复于 2006-03-19 04:27:00 得分 0

修正一下,  
  补充宏定义  
  #define   nil   (node*)0  
   
  由于疏忽,函数node*   cons(int   car,   int   cdr)和node*   cons(node*   car,   int   cdr)有误  
  改为  
  node*   cons(int   car,   int   cdr)  
  {  
        return   cons(car,   cons(cdr,   nil));  
  }  
  node*   cons(node*   car,   int   cdr)  
  {  
      return   cons(car,   cons(cdr,   nil));  
  }  
   
  删除原来的函数后,将以上两个函数添加在main之前cons(node*,   node*)之后(修订后代码见后)  
   
  补充一下  
  length的长度是指一个层上的长度,并不计算子节点  
  也就是  
  (1,   (2,   (3,   null)))   长度为   3;   构造为cons(   1,   cons(2,   3))  
  ((1,   2),   (3,   null))   长度为   2;     构造为cons(   cons(1,   2),   3)  
   
  修订代码:  
   
  #include<iostream>  
   
  struct   node  
  {  
      union   {  
          int   car_v;  
          node*   car_p;  
      };  
      int   type_car;  
      union   {  
          int   cdr_v;  
          node*   cdr_p;  
      };  
      int   type_cdr;  
  };  
   
  const   int   type_node   =   1;  
  const   int   type_int   =   2;  
   
  struct   ret  
  {  
      union   {  
                  node*   p;  
                  int   v;  
      };  
      int   type;  
  };  
   
   
  ret   car(const   node*);  
  ret   cdr(const   node*);  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   node&   n);  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   ret&   r)  
  {  
      if   (r.type   ==   type_int)   {  
                  s   <<   r.v;  
      }   else   {  
                  if   (r.p   !=   0)  
                      s   <<   *(r.p);  
                  else  
                      s   <<   "null";  
      }  
      return   s;  
  }  
   
  std::ostream&   operator   <<   (std::ostream&   s,   const   node&   n)  
  {  
      s   <<   "("   <<   car(&n)   <<   ",   "   <<   cdr(&n)   <<   ")";  
      return   s;  
  }  
   
   
  #define   nil   (node*)0  
   
  node*   cons(int   car,   node*   cdr)  
  {  
      node   n;  
      n.car_v   =   car;  
      n.type_car   =   type_int;  
      n.cdr_p   =   cdr;  
      n.type_cdr   =   type_node;  
      return   new   node(n);  
  }  
   
  node*   cons(node*   car,   node*   cdr)  
  {  
      node   n;  
      n.car_p   =   car;  
      n.type_car   =   type_node;  
      n.cdr_p   =   cdr;  
      n.type_cdr   =   type_node;  
      return   new   node(n);  
  }  
   
  node*   cons(node*   car,   int   cdr)  
  {  
      return   cons(car,   cons(cdr,   nil));  
  }  
   
  node*   cons(int   car,   int   cdr)  
  {  
      return   cons(car,   cons(cdr,   nil));  
  }  
   
  ret   car(const   node*   p)  
  {  
      ret   r;  
      r.v   =   p->car_v;  
      r.type   =   p->type_car;  
      return   r;  
  }  
   
  ret   cdr(const   node*   p)  
  {  
      ret   r;  
      r.v   =   p->cdr_v;  
      r.type   =   p->type_cdr;  
      return   r;  
  }  
   
  void   rel(node*   p)  
  {  
      if   (p   ==   0)   return;  
      ret   r   =   car(p);  
      if   (r.type   ==   type_node)  
                  rel(r.p);  
      r   =   cdr(p);  
      if   (r.type   ==   type_node)  
                  rel(r.p);  
      delete   p;  
  }  
   
  int   main()  
  {  
      node*   p   =   cons(1,   2);  
      std::cout   <<   *p   <<   std::endl;  
      node*   plist   =   cons(1,   cons(2,   cons(3,   nil)));  
      std::cout   <<   *plist   <<   std::endl;  
      rel(p);  
      rel(plist);  
      return   0;  
  }  
   
  Top

2 楼dot99(又来混CSDN来了)回复于 2006-03-19 04:33:48 得分 0

补充一题  
   
  int   list_ref(node*   p,   int   n);   //返回list第n个元素(0开始)   i.e.   (1,   (2,   (3,   null)))的第2个元素为3,第1个元素为2Top

3 楼BFG_10K(dot99马甲)回复于 2006-03-19 04:43:20 得分 0

半夜..精神恍惚,最后一次更正题目:  
  ret   list_ref(node*   p,   int   n);   //返回list第n个元素(0开始)   i.e.   (1,   (2,   (3,   null)))的第2个元素为3,第1个元素为2Top

4 楼ugg(逸学堂(exuetang.net))回复于 2006-03-19 10:21:13 得分 0

MarkTop

5 楼cunsh(村少)回复于 2006-03-19 12:06:56 得分 0

upTop

6 楼linuxchenyy(阿雨(linux,c/c++初学者,大虾们:抱拳~~久仰~))回复于 2006-03-19 12:11:38 得分 0

不错.强.  
  学习中Top

7 楼bjstcm(快毕业了~~~)回复于 2006-03-19 13:07:19 得分 0

markTop

8 楼MagicCarmack(MagiC++)回复于 2006-03-19 14:43:39 得分 0

不错不错  
   
  Top

9 楼atgjplh(永远的C/C++(unix/liunx))回复于 2006-03-19 15:14:29 得分 0

接分!学习Top

10 楼fiftymetre(50米深蓝)回复于 2006-03-19 16:58:51 得分 0

搞什么啊,在这里自说自画的,演唱还演讲?t   =   cons(1,   cons(2,   cons(3,   cons(4,   NULL))))看到这种东西,偶就晕了。。。。。。。:(  
   
  楼主我认为你还是应该把注释都写明了,不要怕麻烦了。既然做好事就做到底吧。不然换来一堆一堆的mark没意思的。  
   
  Top

11 楼dot99(又来混CSDN来了)回复于 2006-03-19 17:45:59 得分 0

50米阿...注释写清楚了  
  提供的代码只是辅助测试用,要是用Lisp也没关系  
   
  我已经写清楚了,只使用car,   cdr,   cons完成题目  
   
  car,   cdr,   cons的语义也写得明明白白,要我还怎么注释....Top

12 楼dot99(又来混CSDN来了)回复于 2006-03-19 18:54:55 得分 0

cons:   construct  
  car:   Contents   of   Address   part   of   Register  
  cdr:   Contents   of   Decrement   part   of   Register  
   
  由于历史的原因,car   cdr就沿用下来,表示有序对的第一个元素和后一个元素Top

13 楼popoxx(我笑)回复于 2006-03-20 08:04:21 得分 0

正好在学习数据结构,谢谢lzTop

14 楼xiaohuoma7620(小火马)回复于 2006-03-20 09:43:17 得分 0

3xTop

15 楼iambic()回复于 2006-03-20 10:04:46 得分 0

不大想看,拿个分吧。Top

16 楼bugouku(不够酷)回复于 2006-03-20 12:02:31 得分 0

up  
  Top

17 楼Ninstein(www.Ninstein.Com)回复于 2006-03-20 12:31:18 得分 0

JF   精神上支持LZ   LZ就物质上支持俺Top

18 楼shaobolovelinglijun(邵波一生一世爱凌丽君)回复于 2006-03-20 13:17:54 得分 0

顶贴。不需要理由。Top

19 楼chrisboyer(ChrisBoyer)回复于 2006-03-20 20:51:06 得分 0

 
  跟据你二楼修正的  
  node*   cons(int   car,   int   cdr)  
  {  
        return   cons(car,   cons(cdr,   nil));  
  }  
  函数,不会出现这样的list:((1,   2),   (3,   null))   。  
   
  cons(   cons(1,   2),   3)构造出的list为((1,   (2,   null)),   (3,   null))。那它的长度是2还3呢?你说的“length的长度是指一个层上的长度,并不计算子节点”我有些不明白是什么意思。  
   
   
   
  Top

20 楼manplus(魅力加加)回复于 2006-03-20 21:17:20 得分 0

搞什么   mark先Top

21 楼vincent_yuen(石班)回复于 2006-03-20 21:56:35 得分 0

just   UP   UPTop

22 楼dot99(又来混CSDN来了)回复于 2006-03-20 22:01:30 得分 0

to   chrisboyer(ChrisBoyer)   :  
  看了一下,二楼的修正的确出现了麻烦,你说的无法构建(1,   2),谢谢提醒,更正如下:  
  代码维持原状(顶楼),cons(1,   2)构造出的有序对为(1,2)。  
  现添加一个操作  
  node*   list_iter(va_list   v);  
  node*   list(int   m,   ...)     //这个是添加的操作,   m表示后面的参数个数  
  {  
        va_list   v;  
        va_start(v,   m);  
        node*   p   =     cons(   va_arg(v,   int)   ,   list_iter(m-1,   v));  
        va_end(v);  
        return   p;  
  }  
  node*   list_iter(int   m,   va_list   v)  
  {  
        if   (m   ==   0)  
              return   nil;  
        return   cons(va_arg(v,   int),   list_iter(m-1,   v));  
  }  
   
  我原来的目的是为了让cons更容易构造list,   所以简化,   这样反而出现无法构建(1,   2)的情况  
  是我的错误,谢谢提醒。  
  现在使用list构造表,而不是原来的cons  
  那么要构造表(   (1,   2)   3)  
  应该使用代码  
  node*   p   =   list(2,   cons(1,   2),   3);  
  也就是  
  cons(   cons(1,   2),   cons(3,   nil));  
  而length(p)   ==   2  
   
  注意(1,   2)是一个有序对,而(1   2)是一个列表,相应的有序对为(1,   (2,   nil))  
  列表(3)的有序对为(3,   nil)  
   
  下面的代码  
  list(2,   list(2,   1,   2),   3);  
  构造出的表为  
  ((1   2)   3)  
  相应的有序对表示为((1,   (2,   nil)),   (3,   nil))  
  length为2  
  car为(1   2)   //这个是表  
  cdr为(3,   nil)   //这个是有序对  
   
  我在表述Lisp的语义时太不谨慎了,无意的简化,带来更多的麻烦。  
  Top

23 楼dot99(又来混CSDN来了)回复于 2006-03-20 22:05:09 得分 0

对于列表,可以把它看作是链表,而有序对看作是链表的node,car(list)得到的是元素的内容,cdr(list)得到的是后继指针。  
  Top

24 楼dot99(又来混CSDN来了)回复于 2006-03-20 22:16:09 得分 0

补充一个错误类型  
  const   int   type_error   =   0;  
  并在ret的operator   <<中  
  加入  
  if(r.type   ==   type_error)   return   s   <<   "error";  
   
  避免做题时遇到问题。  
   
  上面的代码未经过严格测试,欢迎指出错误。  
  Top

25 楼sftk(星海传说)回复于 2006-03-20 22:39:57 得分 0

dingTop

26 楼dot99(又来混CSDN来了)回复于 2006-03-20 22:40:08 得分 0

上面的list有仔细看了,有严重问题:  
  编译器不会保证参数的求值顺序,且宏va_arg(v,   int)带有副作用  
  所以,应该些  
  int   n   =   va_arg(v,   int);  
  cons(n,   list_iter(m-1,   v));  
   
  对不住大家了。Top

27 楼lei001(太极)回复于 2006-03-20 23:20:38 得分 0

markTop

28 楼dot99(又来混CSDN来了)回复于 2006-03-20 23:28:38 得分 0

另外list的处理有限,对于元素为node*的情况没有写进去,请大家完成。  
   
  Top

29 楼nipcdll()回复于 2006-03-21 09:37:20 得分 0

学习Top

30 楼dream_forever(小龙)回复于 2006-03-21 16:49:16 得分 0

我刚刚入门     第一次看到这么长的程序    
  感觉:晕   晕     晕  
  俺不行了     打发点分吧,或许可以医好我Top

31 楼bohlee(我心澎湃)回复于 2006-03-21 16:55:40 得分 0

markTop

32 楼jinjiajie(leorio)回复于 2006-03-21 17:46:54 得分 0

.........MARK,有空看,没空就不看了Top

33 楼Xy4Ever(邪恶漫步者)回复于 2006-03-22 17:05:18 得分 0

同楼上的Top

34 楼dot99(又来混CSDN来了)回复于 2006-03-24 10:39:29 得分 0

这题很难么?Top

35 楼liangkai12(智多星)回复于 2006-03-25 22:50:57 得分 0

题目没看懂Top

36 楼hhhrrrsss(十五维)回复于 2006-03-25 23:25:41 得分 0

饶了我们吧楼主,干脆一次性给齐吧,我快崩溃了。  
  Top

相关问题

  • 哪有CCDOS下载 (东快2000中的受限制)
  • 把CPU升级可以吗?会受限制吗?
  • 关于创建原始套接字在nt下受限制问题
  • 客户端连接服务器的个数受限制????急急急.....
  • 关于linux下进程资源受限制的问题,请高手指点
  • 奖励
  • 给刚出生的小表弟起名字,奖励100分!!
  • 给基础版前几名的少许奖励以表彰
  • 急问:wave文件是否有4G左右的大小限制,能否不受限制
  • applet 要处理通过URL获得得图片,远程图片访问受限制的问题,在线等

关键词

  • 函数
  • 代码
  • null
  • cdr
  • car
  • node
  • ret
  • 有序
  • cons
  • rel

得分解答快速导航

  • 帖主:dot99

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo