1-2+3-4+5-6+7......+n的几种实现
本文的内容本身来自一个名校计算机生的一次面试经历,呵呵,没错,你猜对了,肯定 不是我
个人很喜欢这两道题,可能题目原本不止两道,当然,我这里这分析我很喜欢的两道。
1.写一个函数计算当参数为n(n很大)时的值 1-2+3-4+5-6+7......+n
当我看了面试经过后,我觉得很有代表性,于是,我就拿着这个题目去问我的一些同学,我想看看大家拿到这个题目的第一实现方式。大家给我的反应也在意料之中,说是直接写个for循环。自此,大家都犯了一个程序员最爱犯的错误,那就是把所有的工作都交给cpu去做。或许大家会说,现在的计算机,运行速度那么快,根本不用考虑执行这种程序给cpu带来的效率问题。对于这个问题,我们下面在讨论。
看这位名校生第一次给出的答案:
- long fn(long n)
- {
- long temp=0;
- int i,flag=1;
- if(n<=0)
- {
- printf("error: n must > 0);
- exit(1);
- }
- for(i=1;i<=n;i++)
- {
- temp=temp+flag*i;
- flag=(-1)*flag;
- }
- return temp;
- }
此答案面试官并不满意,后来他又给出了第二个答案:
- long fn(long n)
- {
- long temp=0;
- int j=1,i=1,flag=1;
- if(n<=0)
- {
- printf("error: n must > 0);
- exit(1);
- }
- while(j<=n)
- {
- temp=temp+i;
- i=-i;
- i>0?i++:i--;
- j++;
- }
- return temp;
- }
我个人觉得对于一个刚毕业的大四面试者来说,已经很不容易,当然肯定有人能做的比这些更好,他把原代码中用乘除的地方换成了加减法,我们知道计算机做加减比做乘除效率更高,因为很多计算机乘除会最终转换成加减法来做。
面试官仍不满意,但此时这名大四面试着着急之下想不到最佳方案了。只能求最优答案。
- long fn(long n)
- {
- if(n<=0)
- {
- printf("error: n must > 0);
- exit(1);
- }
- if(0==n%2)
- return (n/2)*(-1);
- else
- return (n/2)*(-1)+n;
- }
呵呵,我也很惊奇,的确,在n很大的时候,此算法不知要比上面的两种算法强多少倍。
这就是为什么上面提到的,程序员不能把所有的工作都丢给计算机,计算机的cpu是给用户用的,而不是给程序员用的。
"不要认为CPU运算速度快就 把所有的问题都推给它去做,程序员应该将代码优化再优化,我们自己能做的决不要让CPU做 ,因为CPU是为用户服务的,不是为我们程序员服务的!”多么精辟的语言,我已经不想再说 什么了!
上面的算法我觉得已经很优了,但是我的一个同学给出了在上面算法的基础上我认为更优的方法。
- long fn(long n)
- {
- if(n<=0)
- {
- printf("error: n must > 0);
- exit(1);
- }
- if(0==n%2)
- return (n>>1)*(-1);
- else
- return (n>>1)*(-1)+n;
- }
我们知道加减法效率比乘除的效率高,而移位运算在大多数情况下也是比加减的效率更高。
2.用一种技巧性的编程方法来用一个函数实现两个函数的功能n为如:
fn1(n)=n/2!+n/3!+n/4!+n/5!+n/6!
fn2(n)=n/5!+n/6!+n/7!+n/8!+n/9!
现在用一个函数fn(int n,int flag)实现,当flag为0时 ,实现fn1功能,如果flag为1时实现fn2功能!要求还是效率,效率,效率!
给出的答案是:
定义一个二维数组 float t[2][5]存入[2!,3!,4!,5!,6!},{5! ,6! ,7!,8!,9!]然后给出一个循环:
for(i=0;i<6;i++)
{
temp=temp+n/t[flag][i];
}
呵呵,是不是很巧妙?典型的空间换时间的算法!
1-2+3-4+5-6+7......+n的几种实现的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
- .net点选验证码实现思路分享
哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- H5实现摇一摇技术总结
摇一摇遇到的问题 一.如何对摇晃效果进行反馈 刚开始的处理方式是,摇晃过程中不做任何处理,但后来反馈说这种效果不好,好像就没有摇动一样,如果声音也不响的话,就真的和什么都没发生一样. 后来想了想,加入 ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- 【AR实验室】mulberryAR : ORBSLAM2+VVSION
本文转载请注明出处 —— polobymulberry-博客园 0x00 - 前言 mulberryAR是我业余时间弄的一个AR引擎,目前主要支持单目视觉SLAM+3D渲染,并且支持iOS端,但是该引 ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
随机推荐
- iOS--隐藏和显示TabBar的方法
1.隐藏TabBar: - (void)hideTabBar { if (self.tabBarController.tabBar.hidden == YES) { return; } UIView ...
- Java web 学习之旅
java web学习之旅 来公司十天了,感觉已经慢慢地融入了这个环境中,几个学长人都很好,都是在他们帮助下,我才能比较顺利的开始了学习java web的旅途. 来这里学习的第一个阶段是做一个简单的用户 ...
- 转-JS中document对象详解
对象属性 document.title //设置文档标题等价于HTML的<title>标签 document.bgColor //设置页面背景色 document.fgColor //设置 ...
- 石子合并 区间DP (经典)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1021 设sum[i][j]为从第i为开始,长度为j的区间的值得和.dp[ ...
- ASP.NET MVC3 局部页面@RENDERBODY @RENDERPAGE@RENDERSECTION使用方法详细说明
转载自:http://blog.163.com/wenchangqing_live/blog/static/173722309201211299817278/ asp.net mvc3局部页面使用方法 ...
- 【UESTC 482】Charitable Exchange(优先队列+bfs)
给你n个物品交换,每个交换用r,v,t描述,代表需要用r元的东西花费t时间交换得v元的东西.一开始只有1元的东西,让你求出交换到价值至少为m的最少时间代价.相当于每个交换是一条边,时间为边权,求走到价 ...
- 思维导图XMiand
XMiand: 异常强大的国产思维导图工具,还能将图同步到服务器上.做思维导图和头脑风暴必备软件,还能转换绘制鱼骨图.二维图.树形图.逻辑图.组织结构图.
- Java线程之间通信
用多线程的目的:更好的利用CPU的资源.因为所有的多线程代码都可以用单线程来实现. 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程. 并行:多个CPU实例或者多台机器同时执行一段处理逻辑, ...
- ExtJS入门教程04,这是一个超级好用的grid
今天进行extjs入门教程的第四篇:grid. 来一份grid尝尝 小伙伴们都知道extjs的grid功能强大,更清楚功能强大的东西用起来必然会复杂.今天我们就从最简单的grid开始讲解. 先来一个最 ...
- MySQL的表分区详解
这篇文章主要介绍了MySQL的表分区,例如什么是表分区.为什么要对表进行分区.表分区的4种类型详解等,需要的朋友可以参考下 一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysq ...