Chinaunix

标题: EMC小有难度的笔试,撰写仅有一行的语句的函数??? [打印本页]

作者: weckay    时间: 2007-04-02 14:45
标题: EMC小有难度的笔试,撰写仅有一行的语句的函数???
函数原形已经给出:int p(int i, int N);
功能:调用该函数,打印如下格式的输出,例p(1, 7);
1
2
3
4
5
6
7
6
5
4
3
2
1
即每行一个数字。(注意:N只打印一次)
要求:
函数中唯一能够调用的函数就是printf。
只使用一条语句,如果你真的不能用一条语句,每增加一条语句扣1分。
不准使用如下的关键字:typedef, enum, do, while, for, switch, case, break, continue, goto,
until, if,  ..具体很多我也忘了,反正能用的不多。
不能使用逗号表达式和?:表达式。
标准:(总分10分)
1. 每多一条语句扣1分,即每多一个;就扣1分
2. 每使用一次if或?:扣2分
3. 每使用一次for,while, swith各扣4分
大体上就是如上的要求了。

[ 本帖最后由 weckay 于 2007-4-2 15:15 编辑 ]
作者: flw    时间: 2007-04-02 14:57
很明显就是想让递归嘛。不过原型给得不清楚,没有描述参数语义。下面我假设 N 是指数字的个数而不是截止数。
  1. int p( int i, int N ){
  2.     return ( N && printf( "%d\n", i ) && p( i+1, N-1 ) && ( N != 1 && printf( "%d\n", i ) ) ) + 1;
  3. }
复制代码

作者: lenovo    时间: 2007-04-02 15:06
原帖由 flw 于 2007-4-2 14:57 发表
很明显就是想让递归嘛。不过原型给得不清楚,没有描述参数语义。下面我假设 N 是指数字的个数而不是截止数。
[code]int p( int i, int N ){
    return ( N && printf( "%d\n", i ) &&am ...

好牛。
作者: yulc    时间: 2007-04-02 15:11
好久没来,一来又见强贴。
作者: weckay    时间: 2007-04-02 15:11
这个N好像题目中就没有说清楚是上限还是个数,也可能是我忘记了。原题就是给的p(1, 7)这个例子,所以通过给的示例也不能判断出N的具体用意。不过这个应该影响不大吧,可以相互转换的吗
作者: Edengundam    时间: 2007-04-02 15:30
打(i, N)范围的....

  1. return ((N == i) && printf("%d\n", i)) || ((N > i) && printf("%d\n", i) && p(i + 1, N) && printf("%d\n", i)) || (printf("None\n"));
复制代码

作者: weckay    时间: 2007-04-02 15:39
我想起来了,N应该是上限。我记得原题中有一句话是这样的up to N and then down to i.
作者: flw    时间: 2007-04-02 15:42
稍微简化了一下:
  1. int p( int i, int N ){
  2.     return ( printf( "%d\n", i ) && N > 1 && p( i+1, N-1 ) && printf( "%d\n", i ) ) + 1;
  3. }
复制代码


to 6 楼:你那个也可以简化的。
作者: flw    时间: 2007-04-02 15:43
原帖由 weckay 于 2007-4-2 15:39 发表
我想起来了,N应该是上限。我记得原题中有一句话是这样的up to N and then down to i.

如果是这样的话,那这个函数的原型就给得非常恶心。
如果是我,我会给出
  1. int p( int min, int max );
复制代码

作者: Edengundam    时间: 2007-04-02 15:51
原帖由 flw 于 2007-4-2 15:42 发表
稍微简化了一下:
  1. int p( int i, int N ){
  2.     return ( printf( "%d\n", i ) && N > 1 && p( i+1, N-1 ) && printf( "%d\n", i ) ) + 1;
  3. }
复制代码


...



恩.....我只能这样了..

  1. return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) && printf("%d\n", i);
复制代码

作者: weckay    时间: 2007-04-02 15:51
斑竹说的有道理,这还是EMC全国统一考试的最后一题呢。太随便了
作者: cobras    时间: 2007-04-02 17:18

  1. int p(int i, int N) {
  2.         return i <= N && (printf("%d\n", i) && p(i + 1, N) || i < N && printf("%d\n", i)) && 0;
  3. }
复制代码

作者: 飞灰橙    时间: 2007-04-02 17:43

  1. int p (int i, int N)
  2. {
  3.     return i < 2*N && printf ("%d\n", N - (N-i) * (2*(i<N)-1) ) && p (i+1, N);
  4. }
复制代码


修正一下,加個return

[ 本帖最后由 飞灰橙 于 2007-4-2 17:52 编辑 ]
作者: bigapple2008    时间: 2007-04-02 21:05
只能说EMC的人才如用有问题,这种题目个人觉得没啥意思啊
作者: InfoHunter    时间: 2007-04-02 21:47
原帖由 Edengundam 于 2007-4-2 15:51 发表

恩.....我只能这样了..

  1. return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) && printf("%d\n", i);
复制代码


错了,应该是这样:


  1. return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) & printf("%d\n", i);
复制代码


最后一个printf前应该是&,否则每次p(i + 1, N)返回的都是假,这样&&运算符短路,不会执行最后的printf了,也就无法输出6.....1了
作者: Edengundam    时间: 2007-04-02 22:08
原帖由 InfoHunter 于 2007-4-2 21:47 发表


错了,应该是这样:


  1. return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) & printf("%d\n", i);
复制代码


最后一个prin ...


恩, 确实搞错了,我倾向学flw的办法. 比 & 语意稍微明确一点.

  1.     return ((N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) && printf("%d\n", i)) + 1;
复制代码


不过还是最开始写的语意上明确...
作者: doni    时间: 2007-04-02 23:35
递归是想到了,要我一下子做出,恐怕有难度
作者: lee2008    时间: 2007-04-03 08:28
原帖由 InfoHunter 于 2007-4-2 21:47 发表


错了,应该是这样:


  1. return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) & printf("%d\n", i);
复制代码


最后一个prin ...




怎么就是没看懂,后半部分的6 5 4 3 2 1 是怎么生成的啊?




作者: InfoHunter    时间: 2007-04-03 09:15
原帖由 lee2008 于 2007-4-3 08:28 发表




怎么就是没看懂,后半部分的6 5 4 3 2 1 是怎么生成的啊?





典型的递归,还是用p(1,7)来说
当i= 6时,调用p(7,7),递归进入p,这时(N > i)为假,返回假,回到p(6,7),这时i = 6,然后执行最后的printf("%d\n", i),打印出6,类推得到5.....1
流程:
p(1,7)
p(2,7)
  ....
  p(7,7)
p(6,7)
...
p(1,7)
作者: lee2008    时间: 2007-04-03 09:45
原帖由 InfoHunter 于 2007-4-3 09:15 发表


典型的递归,还是用p(1,7)来说
当i= 6时,调用p(7,7),递归进入p,这时(N > i)为假,返回假,回到p(6,7),这时i = 6,然后执行最后的printf("%d\n", i),打印出6,类推得到5.....1
流程:
p( ...




我就是这里没搞明白, 怎么回到p(6,7)的?  i是如何自减的啊?
作者: 臭鸡蛋超人    时间: 2007-04-03 09:57
太强了,学习学习~~~~
作者: lsmup    时间: 2007-04-03 10:00
标题: 回复 20楼 lee2008 的帖子
注意两点:
1最关键的还是递归的特点:压栈的操作
2&&运算符的计算特性:必须是前面的为TRUE,才计算后面的。如果为假,则后面的语句则后面的语句不执行
例子p(1,7);就这一步递归来说,打印的是第一个和最后一个1;中间的递归打印中间的数字;这个是关键
  理解好递归的执行流程就好了。
当是p(1,7),明显剩余操作:打印7,还有p(0,;
执行到p(0,的时候,第一条语句为假后面的语句不执行。。。。。
就是最后的结果,所以递归结束
作者: lee2008    时间: 2007-04-03 10:21
原帖由 lsmup 于 2007-4-3 10:00 发表
注意两点:
1最关键的还是递归的特点:压栈的操作
2&&运算符的计算特性:必须是前面的为TRUE,才计算后面的。如果为假,则后面的语句则后面的语句不执行
例子p(1,7);就这一步递归来说,打印的是第一个 ...




有点明白了,谢谢啊,
作者: xcmissyou    时间: 2007-04-03 10:31
原帖由 flw 于 2007-4-2 14:57 发表
很明显就是想让递归嘛。不过原型给得不清楚,没有描述参数语义。下面我假设 N 是指数字的个数而不是截止数。
  1. int p( int i, int N ){
  2.     return ( N && printf( "%d\n", i ) &&am ...
复制代码


强啊!!
作者: InfoHunter    时间: 2007-04-03 11:03
原帖由 lee2008 于 2007-4-3 09:45 发表




我就是这里没搞明白, 怎么回到p(6,7)的?  i是如何自减的啊?


晕,当然是通过return返回的了,建议你研究一下递归的原理就能明了了
作者: 飞灰橙    时间: 2007-04-03 11:05
其实大家都没做对,包括我上面那个只写一次printf地实现。
题目中有这句,
       函数中唯一能够调用的函数就是printf
不能递归调用本身!!!可能EMC的家伙自己也做不出来:)
作者: flw    时间: 2007-04-03 11:11
原帖由 飞灰橙 于 2007-4-3 11:05 发表
其实大家都没做对,包括我上面那个只写一次printf地实现。
题目中有这句,
       函数中唯一能够调用的函数就是printf
不能递归调用本身!!!可能EMC的家伙自己也做不出来:)

如果不递归的话,能不能做出来呢?
我觉得还是有可能的。
只需要用 flwlibc 不要用 glibc 就可以。
printf( "%*v", N, i );

[ 本帖最后由 flw 于 2007-4-3 11:12 编辑 ]
作者: Edengundam    时间: 2007-04-03 11:11
原帖由 flw 于 2007-4-3 11:11 发表

如果不递归的话,能不能做出来呢?
我觉得还是有可能的。
只需要用 flwlibc 不要用 glibc 就可以。
printf( "%*z", i, N );






就是这样的:em11:

不是flwlibc....

是emc-libc.....
作者: 飞灰橙    时间: 2007-04-03 11:12
原帖由 flw 于 2007-4-3 11:11 发表

如果不递归的话,能不能做出来呢?
我觉得还是有可能的。
只需要用 flwlibc 不要用 glibc 就可以。
printf( "%*z", i, N );


呵呵,创意啊
作者: flw    时间: 2007-04-03 11:12
原帖由 Edengundam 于 2007-4-3 11:11 发表



就是这样的:em11:

我觉得还是 v 字母比较形象一些。

[ 本帖最后由 flw 于 2007-4-3 11:14 编辑 ]
作者: flw    时间: 2007-04-03 11:13
原帖由 Edengundam 于 2007-4-3 11:11 发表



就是这样的:em11:

不是flwlibc....

是emc-libc.....

我做出了这道题之后,EMC 录用我了,然后购买了我的 flwlibc,就可以依照协定改名为 emc-libc 了。
作者: Edengundam    时间: 2007-04-03 11:17
原帖由 flw 于 2007-4-3 11:13 发表

我做出了这道题之后,EMC 录用我了,然后购买了我的 flwlibc,就可以依照协定改名为 emc-libc 了。




哈哈...代码里面是flw license??
作者: 飞灰橙    时间: 2007-04-03 11:25
解决办法,可以利用printf的参数和格式字串不一致,
造出缓冲区溢出漏洞,利用该漏洞变相实现递归。

我不会做 ,估计思一克比较在行。
作者: flw    时间: 2007-04-03 11:42
楼上的,你的签名该改了。
作者: arenxl    时间: 2007-04-03 11:49
int p(int i, int N) {
        return i <= N && (printf("%d\n", i) && p(i + 1, N) || i < N && printf("%d\n", i)) && 0;
}


1
2
3
4
5
4
3
2
1
作者: 飞灰橙    时间: 2007-04-03 11:54
原帖由 flw 于 2007-4-3 11:42 发表
楼上的,你的签名该改了。


在俺的声援下,偶像可能已经达到目的了
改吧,改成 "支持EMC最强考试题"
作者: thinkinnight    时间: 2007-04-03 12:23
看了好久,现在刚明白那个最简单的了,继续看其他的
作者: arenxl    时间: 2007-04-03 12:38
可惜 ,俺的功力太差了,只看懂部分~~
作者: slay78    时间: 2007-04-03 13:14
原帖由 flw 于 2007-4-3 11:12 发表

我觉得还是 v 字母比较形象一些。


嗯,是v比较形象,z的话应该打印3遍:1234567654321234567
作者: zhichiamd    时间: 2007-04-03 13:19
return (N >= i) && printf("%d\n", i) && (N > i) && p(i + 1, N) & printf("%d\n", i);

如果我工作写这样的语句,老伴就要打我PP了-_-!
作者: 飞灰橙    时间: 2007-04-03 13:27
一条语句,只调用printf, 不调用其他函数,包括函数p自身的。
(近在32位pc, gcc或vc试验过,不保证任何环境有效)

  1. int p (int i, int N)
  2. {
  3.         return i < 2*N
  4.                 && printf ("%d\n", N - (N-i) * (2*(i<N)-1))
  5.                 && (*((int volatile *)&i - 1) -= 5) && ++(*(int volatile *)&i);
  6. }

  7. int
  8. main (void)
  9. {
  10.     p (1, 7);
  11.     return 0;
  12. }
复制代码

作者: flw    时间: 2007-04-03 13:32
原帖由 飞灰橙 于 2007-4-3 13:27 发表
一条语句,只调用printf, 不调用其他函数,包括函数p自身的。
(近在32位pc, gcc或vc试验过,不保证任何环境有效)
[code]
int p (int i, int N)
{
        return i < 2*N
                && printf ("%d\n&qu ...

Orz
版主赶紧来设精华。
作者: thinkinnight    时间: 2007-04-03 13:34
原帖由 InfoHunter 于 2007-4-3 09:15 发表


典型的递归,还是用p(1,7)来说
当i= 6时,调用p(7,7),递归进入p,这时(N > i)为假,返回假,回到p(6,7),这时i = 6,然后执行最后的printf("%d\n", i),打印出6,类推得到5.....1
流程:
p( ...



这里对最后一个用&不理解,&在这里是怎么用?无论怎样都执行到?
作者: Edengundam    时间: 2007-04-03 13:39
原帖由 飞灰橙 于 2007-4-3 13:27 发表
一条语句,只调用printf, 不调用其他函数,包括函数p自身的。
(近在32位pc, gcc或vc试验过,不保证任何环境有效)
[code]
int p (int i, int N)
{
        return i < 2*N
                && printf ("%d\n&qu ...






看不明白

不过1-7没有问题. 但是其他的不太行
作者: 飞灰橙    时间: 2007-04-03 13:42
原帖由 Edengundam 于 2007-4-3 13:39 发表






看不明白

不过1-7没有问题. 但是其他的不太行


1-N都可以,但第一个不是1,最后还是会退到1,这个不大好办
作者: 弥敦路九号    时间: 2007-04-03 13:49
return  ((i - N) && p(i +  printf("%d\n", i) - 1, N)) + printf("%d\n", i);
作者: Edengundam    时间: 2007-04-03 14:00
原帖由 飞灰橙 于 2007-4-3 13:42 发表


1-N都可以,但第一个不是1,最后还是会退到1,这个不大好办





好佩服啊
作者: evaspring    时间: 2007-04-03 14:14
我觉得我知道用递归,可是就是不知道怎么做!
作者: slay78    时间: 2007-04-03 14:19
原帖由 飞灰橙 于 2007-4-3 13:27 发表
一条语句,只调用printf, 不调用其他函数,包括函数p自身的。
(近在32位pc, gcc或vc试验过,不保证任何环境有效)
[code]
int p (int i, int N)
{
        return i < 2*N
                && printf ("%d\n&qu ...


是修改函数返回地址到调用之前,并且把压入的参数改了么?
作者: 飞灰橙    时间: 2007-04-03 14:27
原帖由 slay78 于 2007-4-3 14:19 发表


是修改函数返回地址到调用之前,并且把压入的参数改了么?


是的。
作者: slay78    时间: 2007-04-03 14:30
原帖由 飞灰橙 于 2007-4-3 14:27 发表


是的。


看可不可以用N的高位把i存起来,解决后面回到1的问题,不过那样实际支持只有16位了
作者: 飞灰橙    时间: 2007-04-03 15:17
原帖由 slay78 于 2007-4-3 14:30 发表


看可不可以用N的高位把i存起来,解决后面回到1的问题,不过那样实际支持只有16位了


也许有可能利用返回值所占据的空间,就能支持到32位了
作者: yanghs.dgut    时间: 2007-04-03 18:51
int p( int i, int N ){
    return ( N && printf( "%d\n", i ) && p( i+1, N-1 ) && ( N != 1 && printf( "%d\n", i ) ) ) + 1;
}

flw 美女的代码 最尾处为何+ 1, 好像多余的吧,没看明白。
作者: thinkinnight    时间: 2007-04-03 20:05
我也不清楚+1到底是怎么实现的
不过我试过了,加其他的也是一样,比如下面的代码,+100,结果还是一样。

<code>
#include <stdio.h>

int p(int i,int N)
{
return ( N && printf( "%d\n", i ) && p( i+1, N-1 ) && ( N != 1 && printf( "%d\n", i ) ) ) +100;
}

int main()
{
    p(1,7);
}

</code>
作者: zhw19810520    时间: 2007-04-03 20:16
标题: 初学者
很多东西看不明白啊!学的太少了.
作者: lsmup    时间: 2007-04-03 20:46
想象一下,如果没有1的话,递归调用上层的返回值是0的话就不执行最后面的打印语句了,为假!!!!!!!
所以要保持条件为真,只要不是0就可以..
你们试一下,为0的话后面的6,5,4,3,2,1肯定打印不出来,不计算后面的表达式,就是不执行printf
作者: thinkinnight    时间: 2007-04-03 21:23
哦,搞懂了,其实只要非0就可以了,不过这些可真是高级技巧啊,不知道哪里能够学习到?
作者: flw    时间: 2007-04-03 22:23
原帖由 thinkinnight 于 2007-4-3 21:23 发表
哦,搞懂了,其实只要非0就可以了,不过这些可真是高级技巧啊,不知道哪里能够学习到?

多做做脑筋急转弯就行了
作者: lsmup    时间: 2007-04-04 09:07
0040110C   call        @ILT+0(_p) (00401005)
00401111   add         esp,8

经典啊!!!!
编译原理学好很重要  ,恩,调试也很重要
作者: cMEr    时间: 2007-04-04 12:00
原帖由 飞灰橙 于 2007-4-3 13:27 发表
一条语句,只调用printf, 不调用其他函数,包括函数p自身的。
(近在32位pc, gcc或vc试验过,不保证任何环境有效)
[code]
int p (int i, int N)
{
        return i < 2*N
                && printf ("%d\n&qu ...


佩服!

崇拜一下!
作者: weiqiboy    时间: 2007-04-04 13:17
return ((i < n) && (printf("%d\n",i) && p(++i,n)))||((i>0)&&(printf("%d\n",i) && p(--i,--n))||1);
作者: HAMMER    时间: 2007-04-04 13:46
不得不出来崇拜下拉
作者: nully    时间: 2007-04-04 14:14
我的是最清析的:

int p(int a, int b) {
   a < b ? printf("%d\n", a),p(a + 1, b),printf("%d\n",a):printf("%d\n",b);
}
作者: Edengundam    时间: 2007-04-04 14:15
原帖由 nully 于 2007-4-4 14:14 发表
我的是最清析的:

int p(int a, int b) {
   a < b ? printf("%d\n", a),p(a + 1, b),printf("%d\n",a):printf("%d\n",b);
}



题目要求用?:..扣分
所以我们都选择了 && 呵呵
作者: nully    时间: 2007-04-04 14:16
晕。。。没看条件。。。(怕看到大牛的解。。。)
作者: nully    时间: 2007-04-04 14:22
int p(int a, int b) {
  return (a<b && printf("%d\n", a) && p(a + 1, b) && printf("%d\n",a)) || printf("%d\n",b);
}
换一个,仍然是最易懂的

[ 本帖最后由 nully 于 2007-4-4 14:24 编辑 ]
作者: cqpp    时间: 2007-04-04 14:55
  1.     return printf( "%d\n", i )
  2.         && ( i != N )
  3.         && ( p( i + 1, N ) + 1 )
  4.         && printf( "%d\n", i ) ;
复制代码

这样不知道清晰不?
作者: co63    时间: 2007-04-04 15:50
强!
作者: openq    时间: 2007-04-04 17:52
zhe jiu shi xian zai ruan jian hang ye de yi ge wu qu,hao xiang zhi you dai ma xie de yue qiao miao jiu yue li hai,ke shi ta you mei you xiang guo zhe yang de dai ma hui gei hou qi de ruan jian wei hu dai lai duo da de kun nan?shi xiang yi xia,zhe yang de dai ma mei ge ren dou xie de chu lai ma? ru guo zai ji qian hang dai ma zhong you zhe me jihang ru ci de dai ma,bu shi bian xie zhe ge dai ma de ren you duo shao ren yi yan neng kan chu lai? ru guo xie zhe dai ma de ren li kai gong si le,ni shi wei hu ren yuan ni hui pei fu zhe ge cheng xu yuan hai shi tong hen zhe ge cheng xu yuan?
作者: flw    时间: 2007-04-04 18:10
原帖由 openq 于 2007-4-4 17:52 发表
zhe jiu shi xian zai ruan jian hang ye de yi ge wu qu,hao xiang zhi you dai ma xie de yue qiao miao jiu yue li hai,ke shi ta you mei you xiang guo zhe yang de dai ma hui gei hou qi de ruan jian wei hu dai lai duo da de kun nan?shi xiang yi xia,zhe yang de dai ma mei ge ren dou xie de chu lai ma? ru guo zai ji qian hang dai ma zhong you zhe me jihang ru ci de dai ma,bu shi bian xie zhe ge dai ma de ren you duo shao ren yi yan neng kan chu lai? ru guo xie zhe dai ma de ren li kai gong si le,ni shi wei hu ren yuan ni hui pei fu zhe ge cheng xu yuan hai shi tong hen zhe ge cheng xu yuan?

可怜的兄弟居然没有输入法,帮你翻译一下吧:
  1. 这就是现在软件行业的一个误区,好像只有代码写得越巧妙就越厉害,可是他有没有想过这样的代码会给后期的软件维护带来多大的困难?试想一下,这样的代码每个人都写得出来吗?如果在几千行代码中有这么几行如此的代码,不是编写这个代码的人有多少人一眼能看出来?如果写这代码的人离开公司了,你是维护人员你会佩服这个程序员还是痛恨这个程序员?
复制代码

作者: Edengundam    时间: 2007-04-04 18:51
原帖由 openq 于 2007-4-4 17:52 发表
zhe jiu shi xian zai ruan jian hang ye de yi ge wu qu,hao xiang zhi you dai ma xie de yue qiao miao jiu yue li hai,ke shi ta you mei you xiang guo zhe yang de dai ma hui gei hou qi de ruan jian wei ...


不能用"难以维护"来为自己对语言的不熟悉找借口. 这题作为最后一题的确值得商榷.
这题从某种意义上考察了思维方式, 相信, 凡是想到递归的人, 都已经算成功一半了^_^

相比, 我觉得很多代码, trick更多, 但是这些trick确是为了更好的开发.
作者: openq    时间: 2007-04-04 23:56
原帖由 Edengundam 于 2007-4-4 18:51 发表


不能用"难以维护"来为自己对语言的不熟悉找借口. 这题作为最后一题的确值得商榷.
这题从某种意义上考察了思维方式, 相信, 凡是想到递归的人, 都已经算成功一半了^_^

相比, 我觉得很多代码, tr ...

请问这位大侠,如果让你写一个的到这样结果到程序,你的首选是一半的循环,还递归。
循环实现和递归实现的效率根本就是天壤之别,程序用来完成我们给的任务的,我想这循环和递归之间的效率学过语言的人都应该很清楚。我想如果追求效率的人肯定会选择循环。
作者: 飞灰橙    时间: 2007-04-05 00:17
原帖由 openq 于 2007-4-4 23:56 发表

请问这位大侠,如果让你写一个的到这样结果到程序,你的首选是一半的循环,还递归。
循环实现和递归实现的效率根本就是天壤之别,程序用来完成我们给的任务的,我想这循环和递归之间的效率学过语言的人都应该很 ...


那你就用循环把上面的过程实现一个看看,
到底是递归更清晰呢,还是循环更清晰.
你的上上一贴说的是清晰,上一贴说的是效率.
作者: Edengundam    时间: 2007-04-05 00:19
原帖由 openq 于 2007-4-4 23:56 发表

请问这位大侠,如果让你写一个的到这样结果到程序,你的首选是一半的循环,还递归。
循环实现和递归实现的效率根本就是天壤之别,程序用来完成我们给的任务的,我想这循环和递归之间的效率学过语言的人都应该很 ...



我不是学究, 应该确信, 在一定范围内, 递归算法的简单易懂, 胜于将其转化成非递归形式.

而且转化成非递归形式, 实则是"递归". 所以说, 考察一个人能不能用正确的递归方法求出, 是有必要的. 因为很多算法是透过递归思路设计的...

我说过此题不一定很好. 我的看法是, 对语言的驾驭是必要的. 因为做大工程, 你一定会看到貌似很trick的东西, 如果不信, 你可以看看开源代码, 我相信你能清楚界定什么是好代码, 什么是差代码, 再说用 && ||的时候太多了. 我写脚本还经常用 && , ||这些操作.

至于写成什么代码, 明确说, 大部分时候, 写成递归形式, 比写成非递归形式更快, 简单. 所以考试时候, 写递归代码, 我觉得很好, 除非明确要求, 将递归转化. 当进行开发时候, 可以转化成非递归的循环形式. 并且如果知道一段代码运行概率小, 而且运行的范围较小, 写递归也没有什么问题.

这题的条件, 让我想到递归, 如果没有这些条件, 我还是想递归. 如果要我优化, 我会考虑<i, N>的取值, 决定是否修改.

[ 本帖最后由 Edengundam 于 2007-4-5 00:24 编辑 ]
作者: Edengundam    时间: 2007-04-05 00:21
原帖由 飞灰橙 于 2007-4-5 00:17 发表


那你就用循环把上面的过程实现一个看看,
到底是递归更清晰呢,还是循环更清晰.
你的上上一贴说的是清晰,上一贴说的是效率.



高手还在啊...睡觉了...晚安
作者: 飞灰橙    时间: 2007-04-05 00:31
原帖由 Edengundam 于 2007-4-5 00:21 发表



高手还在啊...睡觉了...晚安


不敢。
晚安
作者: mianganhuang    时间: 2007-04-05 10:35
标题: 看看我的,大家感觉怎么样?
return (i <= N) && ((printf("%d\n",i))  &&  ((i<N)  && p(i+1,N))  && (i==N || (printf("%d\n",i)))) || 1;
作者: yarco3    时间: 2007-04-05 15:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: geba168    时间: 2007-04-05 22:45
晕  肯定是递归啥
作者: lsmup    时间: 2007-04-05 22:54
飞灰橙的答案竟然无视........
作者: wangchacha    时间: 2007-04-05 22:55
小弟处学,代码是搞不出来,不过我想,EMC出题,就一定让你答满分吗?我觉得适当的折中(运用? :..)是很好的选则
作者: ima    时间: 2007-04-06 00:04
标题: 回复 1楼 weckay 的帖子
一个比较笨但直观的方法
int  p(int index,int range)
{
        return  printf("%d\n",index*(range>=index)+(index>range)*(2*range-index)+
               ((index<(2*range-1))&&p(index+1,range))*0);
}
前面是求值,后面是递归控制

[ 本帖最后由 ima 于 2007-4-6 00:05 编辑 ]
作者: yuanchengjun    时间: 2007-04-06 11:47
标题: 贴一个俺的
int p(int i, int N)
{
        return ((i == N) && printf("%d\n", i))
                || (printf("%d\n", i), p(i + 1, N), printf("%d\n", i));
}
作者: linuxcici    时间: 2007-04-06 12:13
原帖由 flw 于 2007-4-2 15:43 发表

如果是这样的话,那这个函数的原型就给得非常恶心。
如果是我,我会给出
  1. int p( int min, int max );
复制代码




姐姐你很牛啊..............哇......利害得不得了啊...
作者: corer    时间: 2007-04-06 14:29
这个是通用的正确的代码:
int p(int i, int n)   
{   
    return i<=n && printf("%d\n", i) &&( !p(i+1, n) || printf("%d\n", i));   
}   
p(1,7),p(2,9)... i<N 任意整数
cqpp
侠客
    return printf( "%d\n", i )
        && ( i != N )
        && ( p( i + 1, N ) + 1 )
        && printf( "%d\n", i ) ;

这个也对
美女市长的代码只适用与p(1,N)型,i!=1就不对了
作者: BenBear    时间: 2007-04-09 11:40
int p(int i, int n)
{
  return printf("%d\n", i)
         && ((i < n)
             && p(i + 1, n)
             && printf ("%d\n", i))
         || true;
}
作者: emacsnw    时间: 2007-04-09 14:39
这贴不错,看到了很多不错的代码。
作者: guanmj    时间: 2007-04-11 16:25
本帖最后由 guanmj 于 2016-08-02 15:55 编辑

dddddddddd
作者: wood2008    时间: 2007-04-12 11:30
强贴,学习-ing...
作者: gta    时间: 2007-04-12 22:54
好帖,留个名
作者: yikaikai    时间: 2007-10-16 13:31
好,不过题目说了只能用printf函数啊,大家都还调用了p和return 函数
作者: 随风缘    时间: 2007-10-16 13:57
return  是函数吗?
作者: iterator    时间: 2007-10-16 16:01
这个题根本没必要用return啊.为什么所有人的代码里都用return........
作者: jlogzl    时间: 2007-10-16 16:06
个人认为这种题完全没有实际意义,程序员不能一天到晚钻这种牛角尖。好的程序在现在的工作要求是:
1。效率高;2。明晰易读(毕竟老板可不想付你钱,写的程序只有你知道)
作者: shangyilong    时间: 2007-10-16 16:19
标题: 回复 #2 flw 的帖子
强人,顶
作者: zxlzys    时间: 2007-10-16 18:55
在提供个思路不用&&

(n-i) ? printf("%d\n",--i,p(++i,n),printf("%d\n",i)) : printf("%d\n",i);
作者: francybright    时间: 2007-10-16 21:59
的确高手!
作者: baoaabao    时间: 2007-10-17 10:39
我觉得题目出得很有新意,
考察的是递归 的使用,
当然原型给的不好....

return (start == end)&&(printf("%d\n",end))
                ||
                (printf("%d\n",start) && loop(start+1, end) && printf("%d\n",start))
                ;
作者: iceviewer    时间: 2007-10-17 11:11
int p(int i, int N){
        return i<N? printf("%d\n", i)&&p(i+1,N) : N>0?printf("%d\n", N)&& p(i,N-1):0;
}

嗬嗬,写得有点复杂,大家慢慢看
作者: fxyxsl    时间: 2007-10-31 17:33
说了不要用?:组合的

这种题虽然不实用,但能部分地体现一个人的基本功. 挺好




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2