摘要:
【方法一】函数参数与局部变量。函数参数先入栈,然后才是局部变量。如下面的代码,1-向上生长;0-向下生长。int stackDir( int x ) { int a; return (&a - &x)>0; }注意:不推荐同时使用两个局部变量的地址进行判断,因为有的时候编译器会做优化。【方法二】声明在两个不同函数作用域中的局部变量。如下面的代码:#include <iostream>#include <string>#include <algorithm>using namespace std;void func(){int temp; 阅读全文
摘要:
【问题】活动选择问题的大致意思就是在一种只能被独占的资源上,现在有很多事务(这些事务只有两个参数:开始时间和结束时间)在竞争使用这个资源,如何能让更多数目的事务使用这个资源。计算机科学中的例子:比如这个资源是CPU,那么好多进程要竞争使用CPU,那么如何能让CPU处理更多的进程。现实生活中的例子:某大学里只有一间活动教室,用于举办各种学生活动。现在有学生会的各个部门来申请这间教室,如何分配这个教室,能使得这个活动教室举办活动更多呢?当然,我们仅仅考虑活动的开始和结束时间,而不考虑活动的优先级之类的。【参考文献】http://blog.csdn.net/a9529lty/archive/2009 阅读全文
摘要:
【问题】原文参见这里:http://yueweitang.org/blog/posts/rotate-coin-games.html原文中只给出了一个结果,但是没有分析过程。最后我逆向了一下,有点拾人牙慧。我再引用一下人家的题目:Alice和Bob两人玩一种硬币游戏。游戏在一个的棋盘上进行,棋盘上每个格子上都有一枚硬币。在每一回合,Alice可以决定选择翻转某两枚或者一枚硬币,接着Bob可以选择将棋盘旋转90,180或者270度,也可以什么都不做。 游戏轮流进行直到棋盘上所有硬币都正面朝上或者反面朝上,Alice获得胜利。 如果Alice在游戏过程中无法看到棋盘上的银币,也不知道游戏刚开始的状 阅读全文
摘要:
下面是两道常见笔试题:栈的原地排序。(注:所谓原地就是指不需要额外的辅助空间,或者只需要常数个额外空间)栈的原地倒转。但是在这里递归的思想非常抽象,但是又不得不让人叹服!(我也是看了别人的答案,简直太经典了!)另外,虽然不允许另外使用额外空间,但实际上递归本身就要很多空间。。。【栈的原地倒转】这里的递归思想用语言描述太复杂,但是您一看代码,加上那一点注释,很快就能明白的。相信你也会为这个递归的用法感到奇妙!#include <iostream>#include <stack>using namespace std;//display the stackvoid prin 阅读全文
摘要:
数据结构的基础知识中重要的一点就是能否根据两种不同遍历序列的组合(有三种:前序+中序,前序+后序,中序+后序),唯一的确定一棵二叉树。然后就是根据二叉树的不同遍历序列(前序、中序、后序),重构二叉树。下面是这个问题的证明与结论:①给定二叉树结点的前序序列和对称序(中序)序列,可以唯一确定该二叉树。证明:因为前序序列的第一个元素是根结点,该元素将二叉树中序序列分成两部分,左边(设1个元素)表示左子树,若左边无元素,则说明左子树为空;右边(设r个元素)是右子树,若为空,则右子树为空。根据前序遍历中"根-左子树-右子树"的顺序,则由从第二元素开始的1个结点序列和中序序列根左边的1 阅读全文
摘要:
【问题】区间覆盖问题(Interval Cover Problem)常常又叫区间重合问题。一般情况下是求最少区间覆盖,顾名思义,就是用最少数量的小区间去覆盖一个更大的区间。但是本文所说的问题仅仅指的是:判断一个源区间能否被若干给定的已知区间覆盖,是个判断题。【例题】《编程之美》P211的“区间重合判断”就是一种区间覆盖问题。题目:给定源区间[1,6]和一组无序的目标区间[2,3][1,2][3,9],即可认为区间[1,6]在区间[2,3][1,2][3,9]内。【分析】参见编程之美。主要分以下三步:(1)排序。(2)合并。(3)搜索。(1和3具体请看编程之美书中的介绍)下面我只是讲解我的对“合 阅读全文
摘要:
所谓子集,是一个数学中的概念。例如一个集合S = {1,2,3,4,5},那么X = {1,3,5}就是它的一个子集,1+3+5等于9就是对应于X的一个子集和。其实子集对于一个数组来说,就是相当于一个子序列(不是子数组,因为子序列意味着可以不连续,而子数组往往是连续的);那么子集和也就是子序列和。另外,子集问题需要与数学中的“排列”问题区分开来。因为子集往往是无序的,但排列是需要考虑顺序的;所以子集问题常常只是一个“组合”问题,而不是“排列”问题。从另一个角度讲,这种子集和问题是一种背包问题的特例。【问题1】下面举一个退化(之所以说退化,因为这里的子集的大小是2,比较特殊)的子集和问题的例子, 阅读全文
摘要:
【问题】现在有一种彩票,总的有N个选择(比如36选7,那么总的选择就是36种),请问期望用多少次可以取到所有的彩票(有放回--当然,没放回就简单了。。。)?同样的一个题目就是:一个袋子里放N个不同的球,有放回的取球。请问期望用多少次可以取到所有不同的球?【解答】粗略的答案,这个期望次数是随着N的规模成O(N*logN)的规模扩大的。下面是分析:我们采取递推的方式,假设现在已经取到了i-1个不同的球或者不同的彩票(我们下边都用球代替),那么下一次取到第i个球的概率是:( N - ( i - 1 ) ) / N这个很显然:下次想取到一个跟以前的球不同的球,显然是在剩下的N-(i-1)个球中任取一个 阅读全文
摘要:
【概念】a) 作用域。作用域有大小之分。比如全局作用域大于局部作用域,这个很显然。要强调的是另一点:基类作用域大于派生类作用域。可能有人会有疑问,这两个作用域看不见摸不到,怎么知道大小?但是其实仔细想想,这很符合现实世界的面向对象模型:鱼的作用域显然要比金鱼大,交通工具的作用域肯定要比飞机大。如果你实在理解不了,那你还是就这么记住吧。b) 名字查找。请注意,这里的名字仅仅是指函数的名字,而不是原型!名字相同,查找即成功。这是个跟作用域密切相关的概念。名字查找符合以下的过程:1.根据对象,指针,引用的静态版本决定哪一个函数被调用。2.到相应的类中查找,如果没有找到,则到该类的直接基类中查找,按此 阅读全文
摘要:
微软的Visual Studio 2008(VS2008)提供了一个新的选项,给用户显示C++对象在内存中的布局。这个选项就是/d1reportSingleClassLayout。具体使用方法如下,在写好相应的cpp文件之后,需要启动VS2008的命令行工具“Visual Studio 2008 Command Prompt”,切换到cpp文件所在目录之后,输入如下的命令:cl [filename].cpp /d1reportSingleClassLayout[className]cl当然就是MS的编译器咯;[filename].cpp就是你所想要查看的class所在的cpp文件(class定 阅读全文
摘要:
下面是原题:表达式求值,一个字符串只由'+','-',和‘0’-‘9’组成,并且'+','-'只作为二元运算符。bool calculate(const char* exp, int &result);想了想,这个用STL做很简单,因为只有+号和-号,没有其他符号,只要从左向右即可,不需要用栈。存操作数的用双端队列,存操作符的用普通队列先进先出即可。下面是我的解决代码:#include <iostream>#include <string>#include <deque>#include 阅读全文
摘要:
【方法一】使用宏定义,判断long long类型的位数。#include <iostream>using namespace std;#define IS_64bit() (sizeof(long) == 8) #define IS_32bit() (sizeof(long) == 4)void main(void){ cout<<IS_32bit()<<endl; cout<<IS_64bit()<<endl;}【方法二】判断一个指针的大小。sizeof(ptr)。因为指针的位数代表了CPU所能寻址的范围,所以也能判断出来。通过 W 阅读全文
摘要:
都有“快速”两个字,实际上快速选择算法跟快速排序算法的思想完全一样:先分区。也就是分治的思想。快速选择算法的目的就是找到数组中的第K大的数。我写的快速排序的算法见这里:http://hi.baidu.com/microgrape/blog/item/30b7f88a0166bd1bc9fc7a43.html可以对比一下下面的快速选择算法的代码。#include <iostream>#include <vector>using namespace std;//search the kth biggest numberint QuickSelect(vector<in 阅读全文
摘要:
其实二叉树的遍历,这么经典的东西,我自己一直都不明白。递归算法那么简洁,让人神魂颠倒;非递归算法就那么不好理解。。。最近使劲想了一想,似乎有一些眉目了,于是记录下来。【思想】(1)递归思想。虽然非递归算法没有直接使用函数递归,但是使用了栈,所以实际上仍然是递归的思想。但是它递归的是那么朦胧,让人无法捉摸。可以从以下几个方面思考:首先,三个非递归遍历的算法开始都是向左走到树的最左下方的节点,并把路上遇到的节点入栈,这其实就是递归中的前一半过程。如下图所示:图中上半部分表示了一个递归函数的层层深入的栈结构,下面则是模拟了将二叉树的节点入栈的过程。以此类推,从最左下的节点向上的过程就是退栈的过程,也 阅读全文
摘要:
首先,这个问题的最简单情况就是判断两个链表是否相交问题。我写过一篇文章,见这里:http://hi.baidu.com/microgrape/blog/item/5575771e6d3f9c03304e15d8.html===============================================================然后引申到如何判断一个链表存在环的问题。一个有环的链表示意图如下:注:图中的head是链表头;粗的线条表示链表,其中环从图中O点开始,从链表头到交点的距离为z。P点及另外两个长度下面再解释。关于这个问题,解决方案及解释如下:用两个指针来遍历这个单向链表, 阅读全文
摘要:
此题目的意思是:形如下面的两个字符串阶乘,判断哪个更大。12!!!! 和 3!!!!!。前者有4个阶乘号,后者有5个。利用的原理就是:越大的数的同阶阶乘越大。也就是阶乘的单调性。所以可以直接去掉相同个数的阶乘号后再作比较。没有写大整数类,所以请不要用剩余两个!!以上的数测试,会溢出。下面是主要函数的代码:#include <iostream>#include <string>#include <algorithm>using namespace std;long long factorial( string& str ){int excl = cou 阅读全文
摘要:
题目要求:找到一个字符串中的一个连续子串,这个子串内不能有任何两个字符是相同的,并且这个子串是符合要求的最长的。例如:abcdeab,这个字符串有很多不重复子串,比如:abcde, bcdea, cdeab都是不重复子串,而且都是最长的。这个是一个经典的笔试题,百度也曾经出过。下面是代码:(注:由于我的代码本来目的是只求出长度即可,所以只保留了最后一个最长串的结果;如果想求得所有最长的不重复子串,即把所有可能都列出来,则需要再遍历一遍数组或者把所有结果保存下来,需要对代码作修改)PS:我在代码中用了hash_map,估计要比较新版的VC才支持,我不知道GCC或者G++需要把命名空间改为什么,请 阅读全文
摘要:
这是动态规划的经典问题之一,也有空间换时间的特点:储存计算过程中的信息,防止回溯及多余的遍历。【公共连续子串】我们知道,如果寻找“最长公共连续子串”问题,那么可以用下面文章所说的“矩阵填充法”:http://acm.whu.edu.cn/blog/read.php?24实际上不连续的子序列问题,也还是采用了类似的方法。【最长公共子序列问题】具体的解释和递推公式,可以看下面的参考文献。我的代码里面主要是两个函数,第一个是计算长度,第二个是在矩阵中回溯,以找到这个子序列。回溯采取了与生成完全一致的方法。//LCS#include <iostream>#include <vecto 阅读全文
摘要:
(1)基本思想我感觉可以把基数排序归类在“减治”的算法类别中,因为基数排序实际上每执行一次排序就能减少问题的规模(它是一种稳定的排序)。我们在日常生活中最常使用的十进制数的大小比较其实就是基数排序最好的实例(具体见本文第2节),我们在比较两个2位数时,会先比较其十位的大小,然后比较个位大小。例如,53和56。这是基数排序的MSD(most significant digital)的情况。当然,基数排序其实并没有用“比较”,基数排序和桶排序(bucket sort)都采用了“桶”作为每一步排序的存储单位。这些“桶”其实是排序好的。对于十进制数来说,一共只有0-9共10个桶。如果将乱序的数字(比如 阅读全文
摘要:
汤森路透的笔试题是IKM的标准试题--Internet Knowledge Measurement,软件开发的主要包括三种内容:C++语法/UML设计/SQL语句。考得很细节。这个笔试题是考虑时间因素的,如果是题目答对的一样多,如果时间越短,最后的成绩会越高;不会的题可以skip,因为答错还倒扣分。我记得我skip了很多SQL的题目,但是最后还是过了,我是那场第一个答完题目的。过了一周之后,HR通... 阅读全文