【面试笔试-c/c++】人民搜索2012校园招聘试题
2012-08-31 17:07
519 查看
2012 人民搜索笔试题:
题目如下(题目都很基础,但是要拿满分,或者做到完美,应该还是有一定难度的):
废话少说,直接上代码:
假设规模为n的问题的时间复杂度为T(n),则有
T(n) = T(n-1)+O(1)+T(n-1);
T(1) = O(1);
即T(n) = 2(T(n-1))+O(1)也就是T(n)+1 = 2((T(n-1) +O(1) )
对n依次替换,则结果为:
T(n)+1 =2(T(n-1)+1) = 2^2(T(n-2)+1) = .......2^n(T(1)+1) ==>O(2^n)
对于本思路,代码实现如下:
首先我们定义的二叉树的数据结构如下:
那么求位于区间元素个数的关键就在于preOrder:
另一方面,线段树可以维护一个数组的各个区间(子数组)状态。所以本题也可以用线段树解决。需要注意的是,线段树并非对所有的区间查询都有较好的性能(例如对于由0-10这些数字组成的数组构成的线段树,查询区间2-9就是一个比较诡异的查询,需要做相关处理【a,b】=>[a,(a+b)/2],[(a+b)/2,b]两个区间)。所以这里并不给出线段树的解决方案。
递归转移方程?
有坑的情况下,算法如何修改?
//TODO
kmp 是普通字符串匹配算法BF算法的改进算法,其主要优点是在匹配失败时,不需要对主串进行回溯,因而大大提高了匹配的质量。
有关kmp算法的具体细节,可以参考: http://blog.csdn.net/v_july_v/article/details/7041827
由于kmp算法只是“匹配”,因此,要统计数目的话,需要多次调用kmp_search.达到统计的目的。
完整实现的代码如下(这里假设用字符串代替比特位):
b.AC自动机。
AC自动机的原理是在树(trie树)上做kmp搜索。对于本题目,8个bit位的串。需要建立一个9层的trie数(注意trie树的根是不存储元素的),然后进行搜索。命中有出口,计数,否则丢弃。
相应代码稍后补上
// TODO
题目如下(题目都很基础,但是要拿满分,或者做到完美,应该还是有一定难度的):
1、打印汉诺塔移动步骤,并且计算复杂度。 2、计算两个字符串的是否相似(字符的种类,和出现次数相同) 3、定义二叉树,节点值为int,计算二叉树中的值在[a,b]区间的节点的个数。 4. 在一个坐标轴上, 给定两个点,一个起点,一个终点,起点有一个方块,方块可以左右移动,但是移动的长度只能是平方数长(1,4,9,16....) , 同时坐标轴上还有洞,移动的过程中不能越过这个洞,不然会掉下去,问 由起点到终点 至少需要多少次移动,不能到达返回-1 5、给一个整数数组,求数组中重复出现次数大于数组总个数一半的数。 6、一个128bits 的二进制流,要求找出 里面包含 某8bits 二进制流的数目。现在一个一个进行分析总结:
1、打印汉诺塔移动步骤,并且计算复杂度。
很经典的递归问题。递归的一个基本思想是:假设前一步已经得到结果,则下一步的运算(或步骤)是基于上一步骤的结果的。对于递归问题,有一点很值得注意的是:“一定要有退出递归的出口”,否则程序会无限递归下去,最终导致栈溢出。废话少说,直接上代码:
#include <stdio.h> //将编号为n的盘子移动从x移动到y void move(char x,int n,char y){ printf("%d号盘子 :%c -> %c\n",n,x,y); } /*汉诺塔的执行过程,注意n==1是递归退出的条件,这是必要的,没有这个的话会无限递归而出错误。 *参数:n==>总盘子数,x==>底座1,y==>底座2(辅助底座),z==>目标底座。 */ void hanoi(int n,char x,char y,char z){ if(n == 1){ move(x,1,z); } else{ hanoi(n-1,x,z,y); move(x,n,z); hanoi(n-1,y,x,z); } } main(){ char x = 'x',y = 'y',z = 'z'; hanoi(10,x,y,z); return 0; }对于这类递归问题的复杂度(时间)分析(方法有递推式,数学归纳法等):
假设规模为n的问题的时间复杂度为T(n),则有
T(n) = T(n-1)+O(1)+T(n-1);
T(1) = O(1);
即T(n) = 2(T(n-1))+O(1)也就是T(n)+1 = 2((T(n-1) +O(1) )
对n依次替换,则结果为:
T(n)+1 =2(T(n-1)+1) = 2^2(T(n-2)+1) = .......2^n(T(1)+1) ==>O(2^n)
2、计算两个字符串的是否相似(字符的种类,和出现次数相同)
之前有同学给出的思路是:类似字符串计数。比较每个字符出现的次数,然后根据是否相同来比较。但显然,本题目可以有更加简洁的方法,看过百度那道“兄弟单词”的应该记得:这个跟那题十分类似。因此我们的思路是:对于给定的字符串,我们先按照字母表中的顺序对字符串进行排序。如果两个字符串相似,那么他们必须有相同的签名(排序后的字符串),因此我们可以简单的通过strcmp进行比较。对于本思路,代码实现如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> int cmp(const void *a,const void *b){ return (int*)a-(int*)b; } int isSimple(char *s,char *t ){ qsort(s,strlen(s),sizeof(char *),cmp); qsort(t,strlen(t),sizeof(char *),cmp); return !strcmp(s,t); } main(){ char s[] = "abcdefg"; char t[] = "acbdefg"; printf("the result if :%s\n",isSimple(s,t)?"simple":"not simple"); }
3、定义二叉树,节点值为int,计算二叉树中的值在[a,b]区间的节点的个数。
对于本题目。如果只是一个普通的二叉树,那么思路很简单。就是简单的遍历(前中后序甚至层次均可) ==> 计数。以前序为例,代码很简洁:首先我们定义的二叉树的数据结构如下:
typedef struct BTreeNode{ BTreeNode* lchild; BTreeNode* rchild; int value; }BTreeNode,*Btree;
那么求位于区间元素个数的关键就在于preOrder:
#include <stdio.h>
#include <malloc.h>
#define LEAF -1
typedef struct BTreeNode{ BTreeNode* lchild; BTreeNode* rchild; int value; }BTreeNode,*Btree;
BTreeNode* createTree(){
BTreeNode* T;
int t;
scanf("%d",&t);
if(t == LEAF){
T = NULL;
}else{
T = (BTreeNode *) malloc (sizeof(BTreeNode));
T->value = t;
T->lchild = createTree();
T->rchild = createTree();
}
return T;
}
//对位于【a,b】区间的元素个数进行统计,为了不用全局变量。count为引用传递。
void preOrder(BTreeNode* root,int a,int b,int &count){
if(root != NULL){
if(root->value >= a && root->value <= b){
count++;
}
}
if(root->lchild != NULL){
preOrder(root->lchild,a,b,count);
}
if(root->rchild !=NULL){
preOrder(root->rchild,a,b,count);
}
}
main(){
BTreeNode * root;
root = createTree();
int a = 3,b = 8,count = 0;
preOrder(root,a,b,count);
printf("%d\n",count);
return 0;
}
另一方面,线段树可以维护一个数组的各个区间(子数组)状态。所以本题也可以用线段树解决。需要注意的是,线段树并非对所有的区间查询都有较好的性能(例如对于由0-10这些数字组成的数组构成的线段树,查询区间2-9就是一个比较诡异的查询,需要做相关处理【a,b】=>[a,(a+b)/2],[(a+b)/2,b]两个区间)。所以这里并不给出线段树的解决方案。
4、一条路有k可坑,每次能跳平方数步长(1 4 9 16。。),不能跳到坑里,从a跳到b最少几步?
我们先看看,如果不考虑坑的情况,从a跳到b最少几步?(初步估算,最多不超过三步,具体的证明暂无)递归转移方程?
有坑的情况下,算法如何修改?
//TODO
5、给一个整数数组,求数组中重复出现次数大于数组总个数一半的数。
老生常谈的题目,这里不再赘述,仅给出代码:int findMoreHalf(int a[],int N){ int theNum = a[0]; int times = 1,i; for(i = 1;i < N;i++){ if(times == 0){ theNum = a[i]; times = 1; } else{ if(a[i] == theNum){ times ++; }else{ times --; } } } return theNum; }
6、一个128bits 的二进制流,要求找出 里面包含 某8bits 二进制流的数目。
a.kmp算法。kmp 是普通字符串匹配算法BF算法的改进算法,其主要优点是在匹配失败时,不需要对主串进行回溯,因而大大提高了匹配的质量。
有关kmp算法的具体细节,可以参考: http://blog.csdn.net/v_july_v/article/details/7041827
由于kmp算法只是“匹配”,因此,要统计数目的话,需要多次调用kmp_search.达到统计的目的。
完整实现的代码如下(这里假设用字符串代替比特位):
#include <stdio.h> #include <stdlib.h> #include <string.h> void get_nextval(char const* pattenStr, int plen, int* nextval){ int i = 0; nextval[i] = -1; int j = -1; while( i < plen-1 ){ if( j == -1 || pattenStr[i] == pattenStr[j] ){ ++i; ++j; if( pattenStr[i] != pattenStr[j] ){ nextval[i] = j; } else{ nextval[i] = nextval[j]; } } else{ j = nextval[j]; } } } int index_kmp(char const* src, int slen, char const* ptn, int plen, int const* nextval, int pos){ int i = pos; int j = 0; while ( i < slen && j < plen ){ if( j == -1 || src[i] == ptn[j] ){ ++i; ++j; } else{ j = nextval[j]; } } if( j >= plen ) return i-plen; else return -1; } int getMatchCount(char const* src, int slen, char const* ptn, int plen,int const* nextval){ int start = 0,index = 0,count = 0; while((index = index_kmp(src,slen,ptn,plen,nextval,start))!=-1 && index<slen ){ count++; start = index+1; } return count; } main(){ char s[] = "10101010101111011100001010101010111111110001100110101010101011010000111111111100000001111111111100001111111100000000111100001111"; char p[] = "11111111"; int *nextval = new int[strlen(p)]; get_nextval(p,strlen(p),nextval); printf("%d ",getMatchCount(s,strlen(s),p,strlen(p),nextval)); }
b.AC自动机。
AC自动机的原理是在树(trie树)上做kmp搜索。对于本题目,8个bit位的串。需要建立一个9层的trie数(注意trie树的根是不存储元素的),然后进行搜索。命中有出口,计数,否则丢弃。
相应代码稍后补上
// TODO
相关文章推荐
- 【面试笔试-c/c++】兰亭集势2013校园招聘试题。
- 明基(BENQ)2012校园招聘笔试题之C++方向(试题+答案)
- 【面试笔试-c/c++】兰亭集势2013校园招聘试题。
- 各大IT公司2012校园招聘笔试面试整理
- 2012联发科校园招聘成都手机软件部门笔试&第一轮面试
- 东软2012校园招聘笔试试题(B)
- 编程算法/面试 - 美团网2014校园招聘笔试试题 (哈尔滨站) 及 答案
- [置顶] 各大IT公司2012校园招聘笔试面试整理
- 各大IT公司2012校园招聘笔试面试整理
- 各大IT公司2012校园招聘笔试面试整理
- 国内著名IT公司(百度、搜狗、网易、新浪)2012校园招聘笔试、面试小结
- 笔试面试(1)腾讯2014校园招聘软件开发类笔试试题
- 各大IT公司2012校园招聘笔试面试整理
- 笔试面试(1)腾讯2014校园招聘软件开发类笔试试题
- 各大IT公司2012校园招聘笔试面试整理
- 【面试笔试-c/c++】2012年9月土豆优酷网校园招聘笔试
- 各大IT公司2012校园招聘笔试面试整理
- 2012联发科校园招聘成都手机软件部门笔试&第一轮面试
- 【面试笔试-c/c++】2013年校园招聘创新工场笔试题(北邮场)
- 国内著名IT公司(百度、搜狗、网易、新浪)2012校园招聘笔试、面试小结