如何做这一道面试.net程序员面试题题

2068人阅读
algorithm(5)
一道听说挺考验基本功的淘汰85%的面试者的题目,自己也来试试。
题目描述:
依序遍历0到100闭区间内所有的正整数,如果该数字能被3整除,则输出该数字及‘*’标记;如果该数字能被5整除,则输出该数字及‘#’标记;如果该数字既能被3整除又能被5整除,则输出该数字及‘*#’标记。
之前被考过一个类似的题,不过那个是看一个数是3的多少次幂。就是因为没有提纲,临时想法太多,老变,又多嘴问了一句要不要把具体几次幂输出,彻底扰乱了原来的思路。最后当成3的倍数了。。。还想加输入非法判断,还想什么fgetc什么getchar,什么if( ! ( '0' & c && c & '9' ) )之类的,乱七八糟,没弄对~!其实直接在代码里边int x,然后判断x就完事了。。。。
回到题目来,这种最好是有了一个思路就先做出来,先做个最无脑的,然后再想办法改进,这样做的目的主要还是为了理清思路,迭代开发应该会保险点(这叫迭代么?我自己胡乱定义的~),毕竟没有别的地方做提纲。
本来想迭代,先写一个三次循环再写一个单次循环,或者先写一个什么判断方式,再改进,吸取“步子迈太大一下扯到蛋”的教训。但是也没多少东西,干脆一个循环完成吧,三个循环太慢,又不好协调三种情况出现重复时的输出控制。至于一个循环怎么区分三种情况,直接加多条判断语句。
想先输出数字本身,然后根据判断结果再跟上符号&*&和&#&。不过问题也来了,不是所有数字都要输出~~~
直接采用简单粗暴的方法完成,一个小细节就是优先级,3和5的公倍数判断应该在最前,其余两个无区别~!否则,15的倍数会被3或者5的if判断为真。。。
代码如下:
#include&stdio.h&
int main(){
&&&&&&& for(i = 1;i &= 100;i++){
//&&&&&&&&&&&&& printf(&%d&,i);//先输出数字本身的做法不是很好,不是所有数字都应该输出!
//根据优先级,应该先判断是否同时被3和5整除,再看单独的3和5的情况。
&&&&&&&&&&&&&&& if(0 == i % 3 && 0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&%d*#\t&,i);
&&&&&&&&&&&&&&& else if(0 == i % 3)
&&&&&&&&&&&&&&&&&&&&&&& printf(&%d*\t&,i);
&&&&&&&&&&&&&&& //最后这种,不能一&else&以蔽之,因为else包括了既不能被三整除也不能被五整除的
&&&&&&&&&&&&&&& else if(0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&%d#\t&,i);
//&&&&&&&&&&&&& else//这是测试将判断5整除的else if 写成else的后果
//&&&&&&&&&&&&&&&&&&&&& printf(&test:shouldn't output~!\n&);
这是输出结果:
3*&& &5#&& &6*&& &9*&& &10#&& &12*&& &15*#&& &18*&& &20#&& &21*&& &24*&& &25# 27*&& &30*#&& &33*&& &35#&& &36*&& &39*&& &40#&& &42*&& &45*#&& &48*&& &50#&& &51* 54*&& &55#&& &57*&& &60*#&& &63*&& &65#&& &66*&& &69*&& &70#&& &72*&& &75*#&& &78* 80#&& &81*&&
&84*&& &85#&& &87*&& &90*#&& &93*&& &95#&& &96*&& &99*&& &100#&&&
那么,如果先判断数字是否应该显示出来,再判断该添加哪个符号呢?似乎更“智能”!但是如果在互斥的ifelse语句中,会导致后边的“跟不上”——不输出,例如:
&&&&&&&&&&&&&&& if(0 == i % 3 || 0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&%d\t&,i);
&&&&&&&&&&&&&&& else if(0 == i % 3)
&&&&&&&&&&&&&&&&&&&&&&& printf(&*\t&);
&&&&&&&&&&&&&&& else if(0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&#\t&);
那就行不通了?其实很好解决,不在同一层互斥就完了:
&&&&&&&&&&&&&&& if(0 == i % 3 || 0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&%d\t&,i);
&&&&&&&&&&&&&&& if(0 == i % 3)
&&&&&&&&&&&&&&&&&&&&&&& printf(&*\t&);
&&&&&&&&&&&&&&& else if(0 == i % 5)
&&&&&&&&&&&&&&&&&&&&&&& printf(&#\t&);
哈哈,这么小的技巧也有成就感,复习ing。。。。
那么说到效率等问题,这个代码到底有没有优化的余地呢?
优化思路:
1.for循环的判断,记得用“等于零”当循环结束条件比“和非零值对比”更快,例如:
for(i = 100 ; i != 0 ; i--)
但是我记得这是ARM架构的特性吧?!
2.判断次数,感觉这样顺次判断三回很蠢,不知道if语句判断次数还能不能优化
吐槽:说一千道一万,到底哪个快,还要看编译器的吧?同样都是循环,你知道是while循环快还是for循环快啊~!只是一般情况下,从算法角度似乎认为,按次数来评定时间复杂度。。。
这题今天才看到的东西,但是已经十来天了,而且已经结束了,在如下网址有了几个“导师筛选”的参考答案:
http://student.csdn.net/mcd/topic/698
想不出来也不能干耗着,既然已经结束了,看看人家“参考答案”吧
我的答案和第一个第四个第五个雷同!说明这样做至少没错,或者说大家差不多都是这个思路(这也是很正常不过的一个思路了)~~同时也说明可能没有太大的优化空间了,至少在编译器之上的语言层面是吧!
同时也说明,所谓淘汰85%的面试者的百度题,本身并不难,也许是因为应试者太多,或都准备不充分吧?不过看回帖,确实很多人连这么简单的逻辑都没写完整,或者每个人都有那么个阶段——我之前不也是被一道很简单的题淘汰了么。
第二段是java的
public static void test(){
& &for(int i = 1; i &= 100; i++){
&& & & int a3 = i % 3;
&& & & int a5 = i % 5;
&& & & if(a3 == 0 && a5 == 0){
&& & & & &System.out.println(i+&*#&);
&& & & }else if(a3 == 0){
&& & & & &System.out.println(i+&*&);
&& & & }else if(a5 == 0){
&& & & & &System.out.println(i+&#&);
整体运行思路区别不大,不过把变量初始化和赋值感觉上”重复执行了100遍!“
不好评价这个事,好比下边这个
for(int i = 0;i &= 100; i++)
感觉也给i初始化定义了100遍(我会告诉你第一个是初始化,只执行一次么)
一般C习惯用:
for(.....){
a3 = i % 3;
a5 = i % 5;
然后把上边这位同学的代码改成C程序以后,我的gdb查看,两种情况编成一样的汇编代码了~~gcc把这弱智代码优化了吧
引入一个比较另类的答案,尝试对其进行解析:
#include&iostream&
#include&string&
int main()
&& &int add[7] = {3,2,1,3,1,2,3};
&& &char c[6] = {'*','#','*','*','#','*'};
&& &string all = &*#&;
&& &int i = 0;
&& &int index = 0;
&& &while((i += add[index]) &= 100)
&& &&& &if(index != 6)
&& &&& &&& &cout && i && c[index] &&
&& &&& &&& &index++;
&& &&& &else
&& &&& &&& &cout && i && all &&
&& &&& &&& &index = 0;
&& &return 0;
这个答案,乍一看有点抽象,甚至感觉额外用了不少存储空间,两个数组、一个字符串、一个数组索引、一个被判断的整数变量i。。。。
不过抓住了数字的一些小规律,比如3和5的最大公约数是15,那15就是一次循环,也就是那个add数组的意义,加一圈正好15,下次从头来,还是一样的规律。
确实应该向人家学习,过程很巧妙。不过给人的感觉是在程序之外动了很多脑筋,进行很多人工“预处理”,对于这个数字小、规律性强的还不错,如果是规律性不强的很大的数字,不知道该同学到时候又能想起来什么技巧。
总的来说,套路应该是对的,宁愿人多动点脑筋,也要增加实际运行的效率么,因为当资源消耗量大的惊人时,这样做还是非常值得的。
至于效率:一个大循环,循环包括一个边界判断,循环内部两个判断语句,只需搞定是不是公约数。看起来是不错的~!
但是具体到底好不好,有没有缺陷?老师也看到他的答案了,也说正确了,但是5个参考答案里没有他,他也跟贴申诉了,说他的不用都遍历,比其他人都快,这么一个“鹤立鸡群”的答案,为什么不被采用呢?不清楚了,非高手。。。
粗略的设计一个验证方法——就是把数据放大,看谁运行时间短(要是把3和5变了,这种又得重新设计半天吧?直接把i改大点就行了):
先看他这种:
严谨起见,起始和终止之间应该把初始化各种变量的操作时间也算上(不过小到可以忽略了)。
一百万次循环的多次耗时测量:5.63秒、5.25秒、5.17秒、5.16秒、5.34秒等等。
(”秒“从实际个人感官来评定,不是很准确,可能是duration式子出了问题,或者虚拟机的特性?不过把这个数字单纯作为参考还是可以的。。。)
换我那种做法:
多次测试一百万次耗时分别为:2.12秒、1.86秒、1.96秒、1.86秒。。。
多次取平均,可以看到有明显差距。但是前提是打印语句不能丢,打印语句丢了,时间消耗就非常小了。
想要减少误差,也可用一千万次甚至更多,或者嵌套一千万次乘以一千万次循环,计算耗时。不过在这种悬殊差距下引入更浪费时间的测试方法意义已经不是很大,可做参考。
原因及优化:
根据结果,猜测是,打印语句频繁的系统调用可能是耗时增加的罪魁祸首,因为把打印语句注释掉,两者消耗都会非常低。不知道这是否是C的printf和C++的cout之间的差距,抑或是cout语句用了三次&&&&?
通过我不严谨的实验,用自己的VMWARE虚拟机+UBUNTU系统+G++编译器编译运行结果猜测,他的这个程序慢,可能就是慢在打印上了,慢在系统调用上了。
不过可以逐步”优化“,进行测试:
通过去掉endl,把&&&“的使用降低为二次:
最后测试显示0.34秒、0.30秒、0.28秒。。。
再变成只有一个cout &&:
耗时0.22秒、0.24秒、0.19秒、0.19秒。。。
用printf替代cout不就完了?(同样用的G++,不确定G++和GCC编译效率有无差异,但是都用G++,总不会让C++吃亏吧)再测:
//&&&&&&&&&&& cout && i && c[index] &&
&&&&&&&&&&&&&&& printf(&%d%c&,i,c[index]);
0.32秒、0.31秒、0.27秒。。。
和我的程序2秒左右甚至低于2秒的成绩对比,还是有些差距。甚至比cout&&i;还慢了,难道是那个c[index]造成的?
去掉c[index]:
&&&&&&&&&&&&&&& printf(&%d&,i);
输出确实会稍微快一点!
要不要把while循环改成for循环?
如果还用cout,单纯将
&& while(i += add[index] &= ){
循环,改成
&&& for(i += add[index];i &= 1000000; i += add[index])
耗时:5.41秒、4.84秒、5.49秒。。。。
循环对耗时的影响不是很大。
再改的话,最后想组合起来的话,他那个std::string的字符串又不可能在printf下面输出,再改下去就真的没原样了。
对时间消耗的主要影响,姑且认为是如下几点:
cout的使用——尤其是用了三次&&&&(也不好说全是因为数量,也可能和后边添加的c[index]和endl本身有关,反正是这个句子执行很慢)
即使改用printf打印,多一个参数c[index]也要变慢,所以这个c[index]可能是变慢的一个原因。
另外,while和for循环区别不大,。那几个数组和字符串的使用没有再去改,再改面目全非了。
总之,在本人机器上实测,这种看似很巧妙的程序、或者说从算法的角度看很巧妙的、这种“不用遍历”的、“时间复杂度略低”的程序,实际运行的效果并不如那种“无脑”版本强,还弱很多。。。
没去观察汇编代码,涉及系统调用,光是伪汇编指令都会多到眼花缭乱,而且也不能从伪汇编的绝对数量来判断究竟哪个快。
或许,算法和实现之间的关系本不像我想的那样。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:608937次
积分:4437
积分:4437
排名:第6253名
原创:145篇
评论:95条
阅读:7015
文章:24篇
阅读:30070
阅读:352333
(1)(2)(8)(8)(7)(1)(2)(1)(3)(1)(1)(3)(6)(1)(2)(12)(18)(2)(1)(6)(2)(9)(17)(2)(1)(1)(2)(11)(4)(18)推荐到广播
521637 人聚集在这个小组
(恋恋不忘)
(华生(TM))
第三方登录:一道前端面试题,求大神解答!该如何处理 - HTML/CSS当前位置:& &&&一道前端面试题,求大神解答!该如何处理一道前端面试题,求大神解答!该如何处理&&网友分享于:&&浏览:60次一道前端面试题,求大神解答!现有并列的三列布局结构,从左至右依次为&A,&B,&C,&宽度分别为180px,&600px,&180px。要求在不改变&HTML&结构的情况下用CSS实现:ABC,CBA,BAC&三种布局及在CBA排列下使B宽度自适应(三列总宽度100%)。
------解决方案--------------------.container{
margin:&0&
.cola1,.colb1,.colc1,
.cola2,.colb2,.colc2,
.cola3,.colb3,.colc3{
height:100
text-align:
line-height:&100
color:#FFF;
font-size:24
&&&&&&&&&&&&&&&&.cola1{
width:&160
background-color:&#F00;
width:&600
background-color:&#0F0;
width:&160
background-color:&#00F;
width:&160
background-color:&#F00;
margin:0&160
background-color:&#0F0;
width:&160
background-color:&#00F;
width:&160
background-color:&#F00;
width:&600
background-color:&#0F0;
width:&160
background-color:&#00F;
&div&class="container"&
&div&class="cola1"&A&/div&
&div&class="colb1"&B&/div&
&div&class="colc1"&C&/div&
&div&class="container"&
&div&class="cola2"&A&/div&
&div&class="colb2"&B&/div&
&div&class="colc2"&C&/div&
&div&class="container"&
&div&class="cola3"&A&/div&
&div&class="colb3"&B&/div&
&div&class="colc3"&C&/div&
1、2、3分别对应三种情况ABC、CBA、BAC供参考,2中B可以自适应。------解决方案--------------------改变定位试试------解决方案--------------------position:&left:------解决方案--------------------1楼&&正解------解决方案--------------------应该就是要求熟练应用浮动、绝对(相对定位)、cba的时候b可是使用最大宽度max-width定值
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有一、你工作干得并不好,让你当典型,你怎么办?
二、你的主管领导和上级领导有矛盾,上级领导常常直接布置任务给你,你怎么办?
三、你的同事或上级正在做一件不愿意让别人知道的事,你看见了他们,他们也看见了你,你怎么办?
四、某地政府组织大量人力物力在山上搞了八个大字"开垦荒山,植树造林"(大意),请间你对此有何看法?
一。首先在这时候要找到相关信息。向他检讨。并保证最短时间改正,毕竟作典型不是好的事情。如果真把我当典型,也要正确对待,不能把个人情绪带入工作。
其次就是要正视自己存在的问题,找到自己的问题所在。积极改正。要在最短时间内改正、如果对自己的问题认识不足,要及时找到领导。请领导给予指正和帮助。相信领导会帮我改正不足。
最后就是要在平时的工作中,加强学习,提高自己的业务能力。虚心的向领导和同事学习他们的工作经验和业务能力。使自己成为一名合格的公务员。
二,首先要正确对待两位领导的矛盾。不以个人的情绪看待他们。立足自己的本职工作。在他们中作到中和作用。不能其催化作用。
其次,对待上级领导安排的工作,要接受。这是组织纪律所决定的,要服从。但要看是不是自己的工作范围内,要首先作好自己的本职工作。对非本职工作的安排,可说明自己现在的工作任务很重要也很繁重。相信上级领导会安排其他人。
最后对待两位领导的矛盾,不能有事不关己高高挂起的心理,要在适当的时间和方式巧妙的化解他们的矛盾。相信他...
一。首先在这时候要找到相关信息。向他检讨。并保证最短时间改正,毕竟作典型不是好的事情。如果真把我当典型,也要正确对待,不能把个人情绪带入工作。
其次就是要正视自己存在的问题,找到自己的问题所在。积极改正。要在最短时间内改正、如果对自己的问题认识不足,要及时找到领导。请领导给予指正和帮助。相信领导会帮我改正不足。
最后就是要在平时的工作中,加强学习,提高自己的业务能力。虚心的向领导和同事学习他们的工作经验和业务能力。使自己成为一名合格的公务员。
二,首先要正确对待两位领导的矛盾。不以个人的情绪看待他们。立足自己的本职工作。在他们中作到中和作用。不能其催化作用。
其次,对待上级领导安排的工作,要接受。这是组织纪律所决定的,要服从。但要看是不是自己的工作范围内,要首先作好自己的本职工作。对非本职工作的安排,可说明自己现在的工作任务很重要也很繁重。相信上级领导会安排其他人。
最后对待两位领导的矛盾,不能有事不关己高高挂起的心理,要在适当的时间和方式巧妙的化解他们的矛盾。相信他们会求大同存小异。
三,首先要回避,在这种尴尬的情况下,回避是最好的解决方法。
其次我想要主动进行解释。并保证不会向其他的人说。消除他们的想法。同时要信守承诺。
最后如果他们的事情是违反原则和政策的,要及时制止。如以造成后果的,要向上级汇报。这是公务员的基本原则。
四,首先看到现在社会对环境和绿化的重视。从这一层面上可以对当地政府表示肯定和理解。
其次,采取大量人力和物力搞,就是不正确的。得不到人民群众的理解和支持。
最后,环境于绿化是很重要的,可以利国利民。但要用合适的方法和手段,不能盲目。
领导交给的任务我没办好,我应该受到批评。这次事情没办好主要责任在我,领导指定的老同志比较忙,我大可以向其他老同志咨询,但我没有这样做。希望领导能给我个机会,下次...
首先,要抱有平常心态,不要认为领导现在给你安排其他工作是对你有什么成见.
其次,将自己的工作进程重新规划一下,看能否通过加班加快工作速度,从而,有时间来完成领...
从字面上解析就是只要人努力什么困难就可以解决!然后你可以说说有关你所考的单位现在所面临的困难或者中国所面临的困境,只有努力什么之类的政治性言语应该差不多了吧!
同意中间一位哥们的意见。程序是关键,文件的转发是有规定的,一定要签收,这点没有做到被人冤枉不值得,只有谦虚接受批评,然后亡羊补牢,今后工作中改进。下次再递送转发...
公务员宝妈进下,请教生育险问题
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区

我要回帖

更多关于 程序员面试逻辑题解析 的文章

 

随机推荐