|
常用链接
留言簿(1)
随笔分类
随笔档案
文章分类
文章档案
相册
搜索
最新评论
Powered by: 博客园
模板提供:沪江博客
|
|
|
|
|
发新文章 |
|
|
现在一单链表,要求用既省时间又省空间的方法找出倒数第m个元素。倒数第m个元素的定义是:当m=0时,返回最后一个元素。写出设计思路和和C语言作答。给出以下代码及函数声明:两种思路,前一种是我自己想的, 1,两个指针,一个先遍历m下停止,然后在两个同时遍历,这时另一个就到是倒数第m个了,稍微一点逻辑思维就可以搞定了,看代码
element *FindMToLastElement(element *head, int m) { element *p1, *p2; p1 = head; for(int i = 0; i < m; ++i){ if(p1->next) p1 = p1->next; else return NULL; } p2 = head; while(p1->next){ p1 = p1->next; p2 = p2->next; } return p2; }
2,以前看过的阿诺的解答,整个长度m的循环链表遍历,这样的话,最后的m个元素都有了。
2,请说明下面这个程序的输出,并给予解释 int func(int i,int n) { return (i<n && printf("%d\n",i)) && !p(i+1,n) || printf("%d\n",i); } 3 两个整型数,不准用if 、switch 、?:等判断语句求出两者最大值,说出你的思路,能写出代码更好 关于2题,这里有个很好的解释
已折叠 第二题其实也算一个比较常见的“智力”题。仔细观察一下就可以发现return始终返回1,这样理解里面的递归就比较容易了。
因为:i <n && printf("%d\n",i)) && !func(i+1,n) || printf("%d\n",i)
可以看做: exp1 && exp2 && exp3 || exp4,由于exp4是printf()的返回值,始终是一个非零值,所以不管前面的exp1,exp2,exp3的值什么,这个总表达式(exp1 && exp2 && exp3 || exp4)的值总是为1,也就是return始终返回1,也就是fun(i,n)的返回值始终为1.
再依次来看: 如果i >= n,则等价于 0 && printf("%d\n",i)) && !func(i+1,n) || printf("%d\n",i) 由于&&的短路性质,等价于 0 || printf("%d\n",i),即打印 i 的值。
如果i < n,则等价于 1 && printf("%d\n",i)) && !func(i+1,n) || printf("%d\n",i) 所以按顺序执行过去,先打印一个 i ,随后递归 !func(i+1,n),在递归里一样处理,打印i + 1,进入第二次递归;打印i + 1 + 1,进入第三次递归。。。
一直到i = n为止,此时打印i,也就是打印n ,然后第一次返回,返回值为1。
在第一次返回的上下文中:i = n - 1, 由于func(i+1,n) 返回值恒等于1,所以!func(i+1,n)恒等于0,原来的总表达式等价于exp1 && exp2 && 0 || printf("%d\n",i),不管exp1和exp2的值为什么,这里都会执行最后的打印语句,而这里的i = n - 1,所以打印n - 1。
然后第二次返回,此时i = n - 2,打印n - 2。
第三次返回,打印 n - 3.
一直到i为最初的i,此时再打印一次i。
第3题有很多种解法,我来列举一下 1,((a+b) + pow((a-b)*(a-b), 0.5))/2,从((a + b) + abs(a - b))/2而来,后者由于abs时加了判断,所以用pow就显得聪明了。 2,第二种解法一般用移位: 如果a>b,则a-b的二进制表示中最高位为0,(a-b)>>31 = 0;bigger = m[0]; 如果a <b,则a-b的二进制表示中最高位为1,(a-b)>>31 = 1;bigger = m[1]; 3,第三种解法主要借助&&和||来判断,是受到二题的启发
topic.csdn.net\u\20081030\16\1e4c9e2e-f704-4b24-b53e-169fc8246522.html
如果n为整数,则将它除以2 如果n为奇数,则将它加1或者减1 问对于一个给定的n,怎样才能用最少的步骤将它变到1 例如 n=61 n-- 60 n/2 30 n/2 15 n++ 16 n/2 8 n/2 4 n/2 2 n/2 1
编程用c/c++ 解答: 向4靠拢是有道理的,把数字用二进制表示,通过右移一位、加一、减一,让他最终变成0(注意,看成变成0的更好理解一些,其实1变成0只是一个“减一”操作,就相差一步),就需要把所有的1消除掉。 怎么去掉1呢,右移不能消除一,只有加减一能够,所以奇数时要考虑加还是减。 对于...01(2进制)这样的情形,减一能够消除1,加一不能,所以要减一; 对于...11,加一能够至少消除一个1(比如...0111就是消除两个1),减一只能消除一个1,那么对于...011的情形,应该加一还是减一呢? 答案应该是加一,因为向高位进的1可能会与更高位的1合并为1个连续的1串,使以后加一能够一下子消除更多的1; 这里有一个例外,就是3(二进制11),因为更高位没有1了,所以不能加一。
本人比较懒,具体的算法就不总结了
|
|