Chinaunix首页 | 论坛 | 博客
  • 博客访问: 137310
  • 博文数量: 22
  • 博客积分: 1326
  • 博客等级: 中尉
  • 技术积分: 258
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-02 00:52
文章分类
文章存档

2012年(1)

2011年(21)

分类: C/C++

2011-08-07 15:49:36

4.有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。
  1. #include <stdio.h>
  2. int main( )
  3. { int a[11]={1,4,6,9,13,15,19,18,40,100};
  4.   int temp1,temp2,number,end,i,j;
  5.   printf("array a:\n");
  6.   for(i=0;i<10;i++)
  7.     printf("%5d",a[ i ]);
  8.   printf("\n");
  9.   printf("insert data:");
  10.   scanf("%d",&number);
  11.   end=a[9];
  12.   if(number>end)
  13.     a[10]=number;
  14.   else
  15.      {for(i=0;i<10;i++)
  16.        {if(a[ i ]>number)
  17.           {temp1=a[ i ];
  18.            a[ i ]=number;
  19.            for(j=i+1;j<11;j++)
  20.               {temp2=a[j];
  21.                a[j]=temp1;
  22.                temp1=temp2;
  23.               }
  24.           break;
  25.           }
  26.        }
  27.      }
  28.   printf("Now array a:\n");
  29.   for(i=0;i<11;i++)
  30.     printf("%5d",a[ i ]);
  31.   printf("\n");
  32.   return 0;
  33. }

——谭浩强 ,《C程序设计(第四版)学习辅导》,清华大学出版社,2010年7月,p57~58

     这个题目很简单,但代码却混乱无比,堪称混乱之集大成者。如果想学习怎样把代码写的混乱无比,从中可以品悟出很多独家秘诀。

秘诀一、无聊

  1. int end ;
  2.   end=a[9];
  3.   if(number>end)
  4. //……
     这段代码堪称无聊之代表作。方法很简单,就是定义一个并不需要的变量(end),毫无意义地对它赋值(end=a[9]),再用这个克隆的变量(end)做“>”运算而不是用原来的数据对象(a[9])进行运算。而使用原来的数据对象做运算,除了可以提高程序效率、使得代码可读性更好之外,实在是一点也不够无聊啊。不无聊的代码写起来很容易很简单,通常酱紫地:
  1. if ( number > a[9] )
  2.    //……

秘诀二、忽左忽右,前后不一

     把一个数插入到一个有序的数组中,通常有两种考虑:或者从前往后先找到待插入数的位置再做打算,或者从后向前逐步调整。但这绝对达不到混乱的目的。样本代码中先是把数据放在了最后

  1. a[10]=number;
貌似要从后向前,然而这只是一个虚招。紧接着又
  1. for(i=0;i<10;i++)
  2.        {if(a[ i ]>number)
这又是前向后的招数了。
     这里,制造混乱的要诀在于忽前忽后,忽左忽右,任何一个招数都不使老,任何一个思路都不贯彻始终,这样才能让人捉摸不透,制造混乱,之后方可在乱中取胜。
     而寻常的招数则是无条件地先把待插入的数放在数组的最后,例如
  1. scanf("%d",&a[10]);
然后再对数组元素的次序逐步调整以到达有序的状态。
     或者,先从前面找到待插入数据的正确位置,例如
  1. int insert_pos ;
  2.   scanf("%d",&number);
  3. for(insert_pos=0; insert_pos < 10 && number > a[insert_pos]; insert_pos++)
  4.   ;

待找到应该插入的位置之后再做进一步的处理。
     寻常的招数固然思路清晰且简洁易懂,然而主要的缺点就是达不到天下大乱之奇功。

秘诀三、颠三倒四,手忙脚乱
     如果按照从前向后的思路,在找到待插入的位置后,首先考虑的应该是把这个位置上和以后位置上的数组元素向后移动,空出待插入元素的位置,然后插入:

  1. for( i = 11 – 1 ; i > insert_pos ; i--)
  2.   a[i]=a[i-1];
  3. a[insert_pos]= number;
之后数组成为新的有序状态。然而,这种简单的做法实在是属于乱而无术。究竟怎样才能达到乱而有术的境界呢?样本代码给我们做出了极出色的示范。
     首先,在找到待插入的位置后,并不等安排好其他数组元素的位置再插入,而是迫不及待,把数据插入进去
  1. {for(i=0;i<10;i++)
  2.        {if(a[ i ]>number)
  3.           {temp1=a[ i ];
  4.            a[ i ]=number;
这样,temp1这样多余的变量就顺理成章地成了必不可少的变量,因为总不能把被排挤出的原来的a[i]给摔掉啊。紧接着
  1. for(j=i+1;j<11;j++)
  2.     {temp2=a[j];
  3.      a[j]=temp1;
  4.      temp1=temp2;
  5.     }
就如同马戏团小丑表演的抛球杂耍一样——不停地把球抛起(temp2=a[j];)、接住(a[j]=temp1;),同时忙里抽闲地还要不停地从一只手倒入另一只手中(temp1=temp2;),颠三倒四手忙脚乱得让人眼花缭乱目不暇接。这种把几件事搅和在一起忙活的方法实乃制造混乱秘笈中之秘笈。
     忙完之后,发现寻找插入位置的循环竟然还没结束,于是,赶紧刹车——
  1. break;
仿佛马戏表演进入高潮之后戛然而止。幸好制动及时,没有照成追尾。后面再像没事人一样按平常的方式输出——大乱之后的大治。实在是乱出了风格乱出了水平,乱的让人高山仰止。相比之下,下面这种写法
  1. #include <stdio.h>

  2. int main( )
  3. {
  4.   int a[11] = {1,4,6,9,13,15,19,18,40,100};
  5.   int number , i , insert_pos ;

  6.   printf("array a:\n");
  7.   for( i = 0 ; i < 11 - 1 ;i++)
  8.     printf("%d ",a[i]);
  9.   putchar('\n');

  10.   printf("insert data:");
  11.   scanf("%d",&number);

  12.   //寻找正确的插入位置
  13.   for( insert_pos = 0 ;
  14.        ( insert_pos < 11 -1 ) && (number > a[insert_pos]) ;
  15.        insert_pos++ )
  16.       ;
  17.   
  18.   //插入位置及后面的元素后移
  19.   for( i = 11 - 1 ; i > insert_pos ; i-- )
  20.     a[i]=a[i-1];
  21.     
  22.   //插入
  23.   a[insert_pos]= number;

  24.   //输出
  25.   printf("Now array a:\n");
  26.   for( i = 0 ; i < 11 ; i++ )
  27.     printf("%d " , a[i] );
  28.   putchar('\n');
  29.    
  30.   return 0;
  31. }
就显得太过于井井有条昆乱不挡了。貌似一副怎么也乱不起来的样子。更有甚者
  1. #include <stdio.h>

  2. int main( )
  3. {
  4.   int a[11] = {1,4,6,9,13,15,19,18,40,100};
  5.   int i ;

  6.   printf("array a:\n");
  7.   for( i = 0 ; i < 11 - 1 ;i++)
  8.     printf("%d ",a[i]);
  9.   putchar('\n');

  10.   printf("insert data:");
  11.   scanf("%d",&a[ 11 - 1 ] );

  12.   for( i = 11 - 1 ; (i > 0) && ( a[i] < a[i-1] ) ; i-- )
  13.     {
  14.       int temp ;
  15.       temp = a[ i ] ;
  16.       a[ i ] = a[ i - 1] ;
  17.       a[ i - 1 ] = temp ;
  18.     }

  19.   //输出
  20.   printf("Now array a:\n");
  21.   for( i = 0 ; i < 11 ; i++ )
  22.     printf("%d " , a[i] );
  23.   putchar('\n');
  24.    
  25.   return 0;
  26. }
则非但不忙不乱,简直称得上是有些游手好闲了。
阅读(1538) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~