一.前言
写这篇博客,主要是想分享一些编程小技巧,可以帮助小伙伴们一起学习一些看起来很骚,又很牛的操作,让你在笔试或者教别人时,快速得到别人的认可,这就是我的目的,让别人听懂你说的,信服你说的,比你自己懂更好^_^。以后会不定期更新,不仅限于C语言,还有其他的语言和算法等。不要错过哦(^_^)!
特别说明:为了特别突出重点,有时可能会出现变量未声明,个别语法错误等,请见谅。
二.正文
(一).编程计算 1+2+3+……+100 的和。
看一般的操作,如下:
#include <stdio.h> int main(void) { int n, sum; sum = 0; printf("请输入n值:"); scanf("%d", &n); //时间复杂度为O(N) for(int i = 1; i<=n; i++) { sum += i; } printf("sum :%d\n", sum); return 0; }
看我的骚操作,如下:
#include <stdio.h>
int main(void)
{
int n, sum;
sum = 0;
printf("请输入n值:");
scanf("%d", &n);
//不建议写成 sum += n/2*(n+1); 当n是奇数时,计算出错
//或者sum += (n+1)/2*n; 当n是偶数时,计算出错
sum += n*(n+1)/2; //采用等差数列求和公式,复杂度为O(1)
printf("sum :%d\n", sum);
return 0;
}
分析
计算1+2+3+……+100的和,很简单的一个题目,对于刚学编程语言里的循环结构时,一般都有这道经典的题目,可以用循环语句写,也可以用数学公式写。如果在笔试题中出了一道这类的题目,一般都是出题人别有用心的,采用数学公式会让你更胜一筹,毕竟时间复杂度更低。可以试试做做鸡兔同笼,可能循环的枚举法不好写,反而公式法更快,更好写。特别在解线性方程的时候,公式法,非常管用。
(二).编写一个函数,不使用strcpy实现字符串复制功能
一般的操作,如下:
#include <stdio.h> #include <string.h> void mystrcpy(char *src,char *dest) { while(*src) { *dest = *src; dest++; src++; } } int main(void) { char src[50] = "hello, world!"; char dest[50] = {0}; printf("复制前\nsrc:%s\ndest: %s\n", src, dest); mystrcpy(src, sizeof(src)/sizeof(char), dest); printf("复制后\nsrc:%s\ndest: %s\n", src, dest); return 0; }
我的骚操作:
#include <stdio.h> #include <string.h> void mystrcpy(char *src, int len, char *dest) { strcpy_s(dest, len, src); } int main(void) { char src[50] = "hello, world!"; char dest[50] = {0}; printf("复制前\nsrc:%s\ndest: %s\n", src, dest); mystrcpy(src, sizeof(src)/sizeof(char), dest); printf("复制后\nsrc:%s\ndest: %s\n", src, dest); return 0; }
分析
编写一个函数,不使用strcpy实现字符串复制功能,出这种题,一般是面试的笔试题,因为实际工作中,基本不会有人想自己去写一个本轮标准库就提供的函数,除非你别有用心。所有,就是人家就是想考你懂不懂标准库函数的原理,但是这里我们可以钻空子。题目说,不使用strcpy,但是没有说,不能使用strcpy_s或者strncpy等函数,所以我们可以直接调用strcpy_s,这种操作,相信在面试时候写这种答案会让人耳目一新,毕竟你也没有错,不过个人建议把一般的操作也写上去,这样才可以让别人服你。
(三).递归与迭代的互相转化
拿计算阶乘的函数来说
一般的操作:
#include <stdio.h> int fun(int n) { if(n<=1) { return 1; } return n*fun(n-1); } int main(void) { int n, sum; printf("请输入阶数:"); scanf("%d", &n); sum = fun(n); printf("%d!= %d", n, sum); return 0; }
我的骚操作:
#include <stdio.h> int fun(int n) { int sum = 1; for(int i = 2; i<=n; i++) { sum *= i; } return sum; } int main(void) { int n, sum; printf("请输入阶数:"); scanf("%d", &n); sum = fun(n); printf("%d!= %d", n, sum); return 0; }
分析
通常来说,写迭代会比写递归,无论在时间还是空间上,程序执行效率会高很多,是不是递归函数就没有用了呢?并不是,递归函数比迭代函数好写,而且更好理解,并且有些场合只能用递归函数,比方说有树或者图这种数据结构等。
迭代一般都可以转写成递归,但是递归很难转写成迭代,这里简单讲讲思路,将递归的出口条件(结束条件)作为迭代的开始条件,比如计算阶乘,递归写法,n*(n-1)*(n-2)……。迭代写法,1*2*3*……*n,当然可以反过来写,不过遇到其他场合还是等从递归的出口条件作为迭代的开始条件,比如说斐波那契数列的迭代写法,只能从这么写,反过来的写法,还没有人写出来过。感兴趣可以试试。
三.总结
这期的骚操作就分享到这里了,以后会不定期更新,不知道你学会了多少^_^。