http://hi.baidu.com/bbilu/blog/item/65db87805e3519d49123d9d2.html
1、15分 如下数据结构:
typedef struct TreeNode {
char c;
TreeNode *leftchild;
TreeNode *rightchild;
}
请实现两棵树是否相等的比较,相等返回0否则返回其它值.并说明你的算法复杂度
int CompTree(TreeNode* tree1, TreeNode* tree2);
注:A,B两棵树相等当且仅当RootA->c==RootB->c,而且A和B的左右子树对应相等或
者左右互换后相等.
Answer:
http://www.gzu521.com/campus/article/it/200710/159904_3.htm
函数btreeequal(bintreenode*t1,bintreenode*t2)的功能是递归法判断两棵二叉树是否相等,若相等则返回1,否则返回0。函数中参数t1和t2分别为指向这两棵二叉树根结点的指针。当两棵树的结构完全相同,并且对应结点的值也相同时才被认为相等。
已知二叉树中的结点类型bintreenode定义为:
struct bintreenode{
char data;
bintreenode*left,*right;
};
其中data为结点值域,left和right分别为指向左、右子女结点的指针域,
【函数4.2】
int btreeequal(bintreenode*t1,bintreenode*t2)
{
if(t1==null && t2==null)return 1;∥若两棵树均为空,则相等
else if( (4) )return 0;∥若一棵为空一棵不为空,则不等
else if( (5) )return 1;∥若根结点值相等并且左、右子树
∥也相等,则两棵树相等,否则不等
else return 0;
}
【答案】 (4)tl==null‖t2==null(5)tl->data==t2->data && btreeequal(t1->left,t2->left) && btreeequal(t1->right,t2->right)
2、已知一个字串由GBK汉字和ansi编码的数字字母混合组成,编写c语言函数实现从中去掉所有ansi编码的字母和数字(包括大小写),要求在原字串上返回结果。
函数接口为:int filter_ansi(char* gbk_string)
注:汉字的GBK编码范围是0x8140-0xFEFE
(15分)
Answer:不采用移动的方法,而采用覆盖,变量j记录新的字符串的最后位置。遍历字符串string(变量i),如果当前字符c是ansi编码,那么a[j++]=c;否则,continue,i++。
J=0;
For(i=0;i<strlen(string);i++)
{
If(当前字符c是ansi编码)
{
String[j++]=c;
}
Else
{
Continue;//i下移
}
String[j]=’/0’; //加结束符
}
3、30分 芯片测试:
有2k块芯片,已知好芯片比坏芯片多.请设计算法从其中找出一片好芯片,说明你所用的比较次数上限.
其中:好芯片和其它芯片比较时,能正确给出另一块芯片是好还是坏.
坏芯片和其它芯片比较时,会随机的给出好或是坏。
Answer:http://www.ideawu.net/blog/?p=276
题目中给出的最重信息是比较方法. 根据比较方法, 我们可以得出最重的结论是, 如果两个芯片两两比较出现了坏的情况, 那么这两个芯片必有至少一个是坏的. 定义一个方法bcmp(a,b),表示a和b两两比较, 返回值0表示至少有一块芯片是坏的, 1表示a,b都是好的或者都是坏的. 这个推理是充分的, 但不是必要的 .
因为好芯片比坏芯片多, 所以从2K块芯片中随机取出K块芯片必然有至少一块好芯片, 也可能全部都是好芯片. 将这K块芯片中的随机一块基准芯片与其它所有的K-1块芯片进行bcmp(), 如果全返回1, 说明这K块芯片全部都是好芯片, 因为如果至少有一块坏芯片话, 该坏芯片必能被其中至少的一块好芯片检测出来.
如果不是全部都是好芯片的情况, 那么当bcmp()返回0时, 同时将两块芯片排除, 得到的2(K-1)块芯片仍然满足题设的条件. 然后继续进行二分.
如果K为1时, 两块芯片都是好的.
该算法最坏的情况是对芯片进行二分总是无法得到全部都是好芯片的情况, 而且直到最后一次bcmp才返回0. 所以比较次数 ((K-1)+(K-2)+...+1)*2=(K^2-K). 注意到bcmp()进行再次比较.
解题思想: 递归.
4、40分 请设计一个网页存储系统,能存储千万量级的网页。
要求:
1.支持按照URL为键值的随机添加,删除和修改网页
2.支持多个线程同时添加,修改和删除
3.支持多线程按照入库时间批量的获取网页,并尽可能的快
提示:设计应包括如下几方面:
1.网页的存储方式设计,即硬盘数据的组织形式
2.如何支持随机查找
3.如何优化批量检索
4.增删改查之间的同步和互斥,如何达到最大的并发.
系统限制和一些参考参数:
硬盘400G, 内存4G
硬盘的I/O比内存的I/O速度慢1000倍
硬盘的连续I/O比随机I/O快10倍
网页的平均长度为25K
附加:
请说明你的系统在亿到十亿规模的扩展方法.
Answer:
http://topic.csdn.net/u/20070920/16/1965db6b-a967-420f-bc18-b56c1edd44d0.html
方案一:
设计开始的考虑:
1)平均每个网页25k,千万个网页就是25k*1000w=256G个字节,32位操作系统每个文件4G,那么需要(25k*1000w)/4g=62.5个文件来存储所有网页的内容。
给每个网页分配一个从0开始的编号,编号顺序及为入库时间顺序(也可以再做一个时间与编号的对照表),网页内容按编号顺序连续存储在多个内容文件中。
索引信息主要是,一个URL包含多少个网页、包含哪些网页(指向内容文件中网页内容的指针)。
2)如何支持随机查找
有个数组按照网页编号顺序记录每个编号的网页内容在内容文件中的指针。
3)如何优化批量检索
支持多线程检索,将以前检索的结果缓存到内存
4)增删改查之间的同步和互斥,如何达到最大的并发
添加的时候没办法,只能锁住信息,进行添加,不过可以先添加内容,因为内容是向后追加的,这时候不影响检索和更新,最后再修改索引数据的时候加锁。
屏蔽位,即用1000万个位(约1.25M)的数组记录所有网页,网页编号表示这个网页在屏蔽数组中的屏蔽位是第几位。
删除的时候,将这个位数组加锁、置位、解锁。
更新就是先删除,再添加。
最后根据屏蔽位数组定期对内容和索引进行维护,回收浪费的空间。
资料的使用:
硬盘400G > 256G 说明方案可行
内存4G 具体做索引的时候会用到
硬盘的I/O比内存的I/O速度慢1000倍 使用内存缓存优化
硬盘的连续I/O比随机I/O快10倍 内容连续存储,可以一次性连续读取某段时间的网页内容。
网页的平均长度为25K 判断需要分文件存储。
最后数据亿~十亿,就要分多台机器了。可以根据网页URL散列到多台机器。
方案二:
第二道不错,基础的IR知识
随机查找可以使用trie( <算法分析与设计>)
硬盘使用大文件偏移量来解决,
更新删除可以写入新的字符,更新标记,通过后期的文件优化来回收空间.
优化批量检索如果指的是多个查询请求的话可以基于lexicon的CACHE
如果是检索中有多个key word可使用LUCENE 的skip data来优化
至少多线程,锁应该不是好的解决方案