原帖地址: http://blog.csdn.net/memoleak/article/details/6578606
写程序难,看程序更难,看欠抽的程序那是难上加难。。。
怎么样写一段程序,只有自己能懂?
怎么样写一段程序,让别人看了抓狂?
看看这个程序:
void popo(int *array, int num)
{
int i,j,temp;
for(i=0;i<num-1;i++) {
for(j=i+1;j<num;j++) {
if(array[i]>array[j]) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
这段代码不用解释,大家都能明白是什么意思:泡泡排序。
现在看看怎么样让这段代码变得晦涩难懂。
第一步:消除循环
消除循环的最好方法是使用递归,递归可以让一个复杂的问题简单化,也能让一个简单的问题复杂化。
void popo(int *array, int num)
{
int i;
for(i=0;i<num-1;i++) {
if(array[0]>array[i+1]) {
array[0] = array[i+1] + array[0];
array[i+1] = array[0] - array[i+1];
array[0] = array[0] - array[i+1];
}
}
if(i != 0)
popo(array+1, num-1);
}
上面的代码中还存在不容易变成递归的循环,没问题,我们将这个循环单独写成函数,这样就可以使用递归了。
void func(int *array, int index)
{
if(index > 0) {
if(array[0]>array[index]) {
array[0] = array[index] + array[0];
array[index] = array[0] - array[index];
array[0] = array[0] - array[index];
}
func(array, index-1);
}
}
void popo(int *array, int num)
{
func(array, num-1);
if(num != 0)
popo(array+1, num-1);
}
第二步:合并函数
将不含循环的多个函数合并成一个函数,可以通过增大参数的取值范围来实现。
我们知道:上面func函数的参数index和popo函数的参数num都是正数,那么我们可以将func函数的参数index改成负数,这样就可以实现合并了,具体看下面合并好的函数:
void popo(int *array, int num)
{
if(num > 1) {
popo(array, 1-num);
popo(array+1, num-1);
}
else if(num < 0){
if(*array>array[-num]) {
array[0] = array[-num] + array[0];
array[-num] = array[0] - array[-num];
array[0] = array[0] - array[-num];
}
popo(array, num+1);
}
}
第三步:消除常量和临时变量
临时变量可以通过增加函数参数或者增加函数参数的范围或者使用重复的表达式来实现,常量可以通过移位和加减运算转换成0和1来表示,而0和1又可以通过参数的逻辑运算来获得,这样转换后的结果将不会包含任何常量。代码如下:
void popo(int *a, int n)
{
if(n > !!a) {
popo(a, !!a-n);
popo(a+!!a, n-!!a);
}
else if(n < !a){
if(*a>a[-n])
a[-n]=(*a+=a[-n])-a[-n],*a-=a[-n];
popo(a, n+!!a);
}
}
第四步:使用?:运算符
对于一个不含循环的函数,很容易将其控制逻辑用if-else来表示,而if-else又可以用?:运算符来实现。为了让代码更难懂,可以用_,__,___作为变量名;将数组a[3]写成3[a]等等方法来混淆视听。看看最终完成以后的结果吧:
void ___(int *__, int _)
{
_>!__?(___(__,!!__-_),___(__+!!__,_-!!__)):_<!__?(*__>__[-_]?__[-_]=(*__+=(!__)[__-_])-(-_)[__],*__-=__[-_]:_,___(__,_+!!__)):___;
}
这样即便是一个有经验的程序员,也很难迅速理解上面的代码了。
最后,来测试一下我们的代码:
#include <stdio.h>
void ___(int *__, int _)
{
_>!__?(___(__,!!__-_),___(__+!!__,_-!!__)):_<!__?(*__>__[-_]?__[-_]=(*__+=(!__)[__-_])-(-_)[__],*__-=__[-_]:_,___(__,_+!!__)):___;
}
int main()
{
int test[] = {2,23,3453,1,32,32,563,546,238,345,454,646,5634,24,564,35,4,-3,-45,-5};
int size = sizeof(test)/sizeof(test[0]);
int i;
printf("before: ");
for(i = 0; i<size; i++)
printf("%d/t",test[i]);
___(test, size);
printf("/nafter: ");
for(i = 0; i<size; i++)
printf("%d/t",test[i]);
printf("/n");
return 0;
}
chen@chen-desktop:/opt$ gcc -Wall -Werror sort.c -o sort
chen@chen-desktop:/opt$ ./sort
before: 2 23 3453 1 32 32 563 546 238 345 454 646 5634 24 564 35 4 -3 -45 -5
after: -45 -5 -3 1 2 4 23 24 32 32 35 238 345 454 546 563 564 646 3453 5634
下次面试的时候,谁再让你写排序算法,你可以反问对方:不用循环,你能用一条语句实现排序算法吗?