[软件笔试] 2014暴风影音校招技术笔试题(长春站)

试题来源:http://www.itmian4.com/forum.php?mod=viewthread&tid=3622&extra=page%3D1

1.升序排列下列数值:(101001)2,(40)10,(23)8,(18)16

解:个人理解,全统一到某一进制,如10进制数,再进行比较。

2.写出下列函数的返回值
int func(int x=300){
            int y=0;
            while(x){
                y++;
                x=x&(x-1);
            }
        return y;
}

解:x = x&(x-1)的作用是将x(二进制表示)最右边的1消去,所以,程序的功能是求x的二进制表示法有多少个1.因为300(10)=100101100(2),所以返回值是4.

3.写出下面代码的输出
#include<stdio.h>
int main(){
    char *p="abcdef";
    char str[]="123456";
   
    printf("d%\n",*(p+4));
    printf("c%\n",p[4]);
    printf("c%\n",*(str+4));
    printf("c%\n",str[4]);
   
    return 0;
}

解:这道题出得十分YD,注意是d%而不是%d,所以,你懂的。答案是,一不小心,可能会跌爆眼镜!

d

c

c

c

4.使用C语言写出存储内容为整数的单链表数据类型定义,并使用自己定义的单链表数据类型定义,完成下面的算法,要求优化时间与空间复杂度。
算法要求:合并两个已经排序的单链表为一个排序的单链表,相同内容只保留一个
如:单链表a:1->2->3->4
单链表b:3->4->5

输出:1->2->3->4->5

解:合并两个链表的方法其它同类型的面试题已经有讲过不少了,这里多了一个“去重”要求。只需要多处理一种情况即可。下面用的是C++,稍作改进就可以变成C.

#include<iostream>
using namespace std;
struct node
{
	int key;
	node* next;
	node(int k):key(k),next(NULL){}
};
struct List
{
	node* head;
	List():head(NULL){}
};
node* ListInsert(node* head,node* z)
{
	if(!head) 
	{
		head=z;
		return head;
	}
	else
	{
		head->next=ListInsert(head->next,z);
		return head;
	}
}

node* recurMergeList(node* head1,node* head2)
{
	if(!head1)//如果没有head1
		return head2;
	else if(!head2)//如果没有head2
		return head1;
	node* MergeHead=NULL;
	if(head1->key < head2->key)
	{
		MergeHead=head1;
		MergeHead->next=recurMergeList(head1->next,head2);
	}
	else if(head1->key > head2->key )
	{
		MergeHead=head2;
		MergeHead->next=recurMergeList(head2->next,head1);
	}
	else //head1->key ==head2->key
	{	//新增的部分
		MergeHead=head1 ;
		node* nextMergeHead = recurMergeList(head1->next,head2->next);
		if(nextMergeHead && MergeHead->key == nextMergeHead->key)
			MergeHead=nextMergeHead;
		else
			MergeHead->next = nextMergeHead;
	}
	return MergeHead;
}

void main()
{
	int A[]={1,2,2,5,9,13,16};
	int B[]={2,5,12,13,13,16,19};
	int len=sizeof(A)/sizeof(A[0]);
	List* LA=new List;
	for(int i=0;i<len;++i)
	{
		LA->head=ListInsert(LA->head,new node(A[i]));
	}
	List* LB=new List;
	for(int i=0;i<len;++i)
	{
		LB->head=ListInsert(LB->head,new node(B[i]));
	}
	node* p=LA->head;
	while(p)
	{
		cout<<p->key<<' ';
		p=p->next;
	}
	cout<<endl;
	p=LB->head;
	while(p)
	{
		cout<<p->key<<' ';
		p=p->next;
	}
	cout<<endl;
	p=recurMergeList(LA->head,LB->head);
	//p=MergeList(LA->head,LB->head);
	while(p)
	{
		cout<<p->key<<' ';
		p=p->next;
	}
}

5.编写程序,把一个有序整数数组放到以整数为元素的二叉树中,生成一个平衡排序二叉树。设计并变成实现一种遍历方法,,是这种遍历方法的输出正好是输入数据的次序。
如数组 a:{1,2,3,4,5,6,7}
生成的二叉树:
4
/  \
2    6
/\    /\

1  3   5  7

解:本来将一个有序数组放到一棵二叉树有很多种摆放方式,但是题目要求是平衡二叉树,容易想到的是二分思想,当每个结点左边和右边的结点数相等(或只相差1个的时候)这棵树就是平衡的,最后再中序输出即可。

#include<iostream>
#include <exception>
using std::cout;
using std::endl;
struct node
{
	int value;
	node* left;
	node* right;
	node(int v):value(v),left(NULL),right(NULL){}
};

node* Build_Tree(int* A,int l,int r)
{	
	if(!A || l > r)
		return NULL;
	int mid = (l+r)>>1;
	node* root = new node(A[mid]);
	root->left = Build_Tree( A, l, mid-1);
	root->right = Build_Tree( A, mid+1,r);
	return root;
}

void TreeWalk(node* z)
{
	if(!z)
		return ;
	TreeWalk(z->left);
	cout<<z->value<<' ';
	TreeWalk(z->right);
}

int main()
{
	int Inorder[] = {1,2,3,4,5,6,7};
	int len=sizeof(Inorder)/sizeof(Inorder[0]);
	node* root=Build_Tree(Inorder,0,len-1);
	TreeWalk(root);
	return 0;
}

6.编写程序,在原字符串中把尾部m个字符移动到字符串的头部,要求:长度为n字符串操作时间复杂度为O(n),空间复杂度为O(1)。

如:原字符串为”Ilovebaofeng”,m=7,输出结果:”baofengIlove”

解:具体见http://blog.csdn.net/linraise/article/details/12237185的左旋转部分,5种办法中只有2处是符合要求的。递归要用到栈,空间不是O(1).

7.暴风影音的片源服务器上保存着两个文件a和b,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出a,b文件共同的URL。要求:算法设计。

解:大数据问题。5*64=320G,4G内存无法一次性装入。因此可以用一个hash函数将a文件的URL hash到n个小文件中,对b文件的URL做同样的操作,因此,所有可能相同的URL都会被分到相同的小文件中。因为hash函数的特点是如果a=b,则hash(a)=hash(b).再对每一个小文件统计相同的URL即可,可以两次扫描,也可以用位图。

你可能感兴趣的:(大数据,面试题)