第1题:用C语言实现一个公用库函数void * memmove(void *dest,const void *src,size_t n)。该函数的功能是拷贝src所指的内存内容前n个字节到dest所指的地址上。注意,作为公用库函数,请注意安全检查,注意处理内存区重合的情况。
void *
memmove
(void * dest,const void *src,size_t count)
00424:
{
00425:
char *tmp, *s;
00426: assert(dest && src);
If(
dest
== src)
Return dest;
00427:
if
(dest < src) {
00428:
tmp = (char *) dest;
00429:
s = (char *) src;
00430:
while
(count- -)
00431:
*tmp++ = *s++;
00432:
}
00433:
else
{
00434:
tmp = (char *) dest + count;
00435:
s = (char *) src + count;
00436:
while
(count- -)
00437:
*- -tmp = *- - s;
00438:
}
00439:
00440:
return dest
;
第2题:写一段程序,找出数组中第k大小的数,输出数所在的位置。例如 {2,4,3,4,7}中,第一大的数是7,位置在4(位置从0开始编号)。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。第四大的数是3,位置在2。 函数接口为:int find_orderk(const int * narray, const int n, const int k)
第3题:芯片测试。有2k块芯片,已知好芯片比坏芯片多。请设计算法从其中找出一片好芯片,并说明你所用的比较次数上限。其中:好芯片和其它芯片比较时,能正确给出另一块芯片是好还是坏;坏芯片和其它芯片比较时,会随机的给出好或是坏。
思路:
用锦标赛法,
向分成
1024
组,每组两个,如果测试有一个坏的就全部抛弃,然后相邻两组和成一组,从每组里调出一个和另一组的一个进行测试,如果坏的就全部抛弃,依次类推,直到顶点。由于好的比坏的多,每次抛弃一个好的,肯定会抛弃一个坏的,这样就肯定能得到一个好的。
次数为
1024+512+
……
+1
。
1. 请列举你所知道的Linux或者Windows进程间通迅的方式(请选择一种平台回答
,至少回答6个或以上)?
Linux
上的进程间通信有:
管道
消息队列
共享内存
信号
套接字
2. 实现一个TCP端口监听服务进程通常需要使用那些socket函数,并请描述这些函
数的作用?(至少回答6个或以上)
Socket
建立套接字句柄
Bind
绑定这个套接字到服务器地址和端口上
Listen
监听套接字,
Accept
接受连接
Read
读
Write
写
3. 将基于多进程模型的程序移植为基于多线程模型的程序,通常需要如何修改调
整程序(解决那些问题)?
4. 什么是C/C++的模板(template)编程, 有什么好处?
5. 什么是数据库外键?什么是事务?存储过程和触发器的用途?
//这是第二大题编程:
二 编程题:请用c/c++语言编写完整的程序代码,除了实现题目所要求的基本功能
,还应考虑算法的效率和逻辑的严密性.
6. 请编程实现大数阶乘。比如计算2000的阶乘,要求用printf输出结果
数组乘法
int a[N];
int b[N];
int c[2 * N];
void mutiply()
{
for (int i=0; i<N; ++i) {
int carry = 0;
for (int j=0; j<N; ++j) {
carry += a[i]*b[j]+c[i+j];
c[i+j]=carry%10;
carry/=10;
}
}
}
7. 请分别设计一个递归和非递归算法来计算F(n)
F列可递归定义为:
n为大于等于0的整数
F(n)=n 当n=0,1,2
F(n)=F(n-1) - F(n-3) 当n>=3
//
递归版本
..
不考虑高精度大数了,反正这是体力活,以免大家看得辛苦
.
# include <stdio.h>
# include <string.h>
# define MAX 1000000
long long F[MAX];
bool haveBeenCal[MAX]; //
递归防止重复计算
.
long long Cal(int n)
{
if(haveBeenCal[n]) return F[n];
haveBeenCal[n]=1;
return F[n]=Cal(n-1)-Cal(n-3);
}
int main()
{
int n;
memset(haveBeenCal,0,sizeof(haveBeenCal));
haveBeenCal[0]=haveBeenCal[1]=haveBeenCal[2]=1;
F[0]=0,F[1]=1,F[2]=2;
while(scanf("%d",&n)!=EOF) {
if(n<0||n>=MAX) printf("inavailabe n/n");
printf("%lld/n",Cal(n));
}
return 0;
}
//
非递归版本
# include <stdio.h>
# define MAX 100000
int F[MAX];
int main()
{
int n,i,max;
F[0]=0,F[1]=1,F[2]=2;
max=2;
while(scanf("%d",&n)!=EOF) {
if(n<=max) {
printf("%d/n",F[n]);
continue;
}
for(i=max+1;i<=n;i++) F[i]=F[i-1]-F[i-3];
max=n;
printf("%d/n",F[n]);
}
return 0;
}
注
:
对于这一题,我们还有另一个算法,对于一个
n,
不用一步一步地推
n
次,只要
推
lg(n)
次就可以了
.
这是因为
_ _ - - - -
| F[n] | | 1 0 -1 | | F[n-1] |
| F[n-1] | = | 0 0 0 | *| F[n-2] |
| F[n-2] | | 0 1 0 | | F[n-3] |
- - - - - -
再推下去,得
:
_ _ - - ^(n-2) - -
| F[n] | | 1 0 -1 | | F[2] |
| F[n-1] | = | 0 0 0 | * | F[1] |
| F[n-2] | | 0 1 0 | | F[0] |
- - - - - -
于是,问题就转化成如何求一个矩阵的
n
次方了,用分治的思想就可以做到
lg(n)
咯
,好简单,这里略,
可以参考素数判写的
Miller-Rabin
算法
..kaka.
8. 海量单向链表排序
有一单向链表,已知其首指针为head,链表长度为百万量级,链表的每个
结点的结构如下:
typedef struct _node_t {
int a;
struct _node_t* next;
…
} node_t;
试设计程序,将该链表各结点按a值升序排序,要求在原地进行,不允许使
用大量的辅助内存。
//
直接修改一下
Mergesort
就可以了
,nlogn
# include <stdio.h>
typedef struct _node_t{
int a;
struct _node_t* next;
}node_t;
node_t* Mergesort(node_t* L,int count) //
链表头及要链表元数个数
{
if(count==1) return L;
int count1=count/2;
int count2=count-count1;
node_t* p=L;
int i;
for(i=0;i<count1;i++) p=p->next;
node_t* h1=Mergesort(L,count1);
node_t* h2=Mergesort(p,count2);
int t1=0,t2=0;
node_t *head=NULL,*cur;
while(t1<count1||t2<count2) {
if(t1<count1&&t2<count2) {
if(h1->a < h2->a) p=h1,h1=h1->next,t1++;
else p=h2,h2=h2->next,t2++;
}
else if(t1<count1) p=h1,h1=h1->next,t1++;
else p=h2,h2=h2->next,t2++;
if(head==NULL) head=cur=p;
else {
cur->next=p;
cur=p;
}
}
return head;
}
void sort(node_t* &a)
{
int count=0;
node_t* p=a;
while(a) {
count++;
a=a->next;
}
a=Mergesort(p,count);
p=a;
int i;
for(i=0;i<count-1;i++) p=p->next;
p->next=NULL;
}
void input(node_t* &a)
{
a=NULL;
int n;
node_t* p;
while(scanf("%d",&n)!=EOF) {
node_t* s= new node_t;
s->a=n;
if(a==NULL) a=p=s;
else p->next=s;
p=s;
p->next=NULL;
}
}
void output(node_t* a)
{
while(a) {
printf("%d ",a->a);
a=a->next;
}
printf("/n");
}
int main()
{
node_t* a;
//freopen("test.in","r",stdin);
input(a);//
屏幕输入时输一串数字,然后按
enter
再按
ctrl+z
结束
sort(a);
output(a);
return 0;
}
9. 集合合并
给定一个字符串集合,格式如:
{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}
要求将其中交集不为空的集合合并,要求合并完成后的集合无交集,例如上例应输
出{aaa,bbb,ccc,ddd,hhh},{eee,fff},{ggg}
1)请描述你解决这个问题的思路
2)请给出主要的处理流程,算法,以及算法的复杂度
3)请描述可能的改进(改进的方向如效果,性能等等)
(1)
主要思路
关键就是两步
:
1.
确定那些集合要合成一堆
.
2.
如何合并一堆集合
.
(2)
算法
1.
每个元素对应一个桶,装含有该元素的集合的编号
.
如例子中
:
{aaa}: 1
{bbb}: 1 2
{ccc}: 1
{ddd}: 2 5
{eee}: 3
{fff}: 3
{ggg}: 4
{hhh}: 5
这一步须时
(
所有集合中元素个数的总和
).
2.
然后用并查集,每个桶中相邻的两个集合就要合并
.
如上例,集合
1,2,5
要合并,其它独立
.
这步须时
,
总元素个数
*a(
总元素个数
)
其中
a(n)
是
Ackman
函数的反函数,一般
<=4,
所以也大约地关于总元素个数成线
性
.
3.
合并集合
例如,现在要分别合并集合的编号为
1,2,5
及集合编号为
3,4,6
的集合
.
那么,我们就把集合
1,2,5
中含有的元素都标记为
1.
再把
3,4,6
中含的元素都标记为
2.
然后把所有元素扫一次,按标号分类就可以了
.
复杂度
,O(
总元素个数
).
综上
,
复杂度大约是
O(
总元素个数
).
当然
,
这里不包括由给每个元素编号的复杂度
,
其实复杂度不高的吧
,
就是用最弱智
的方法就可以做到
不同元素的个数
*log(
不同元素的个数
).
(3)
改进
有比上面的算法快的话你通知一声我
,
谢谢
.
一、某密码表以文件的形式存储在硬盘上,文件名为:encrypt.txt,其内容为:
abcdefghijklmnopqrstuvwxyz
ushecginpaywdqmlxbozrtfvjk
其中第一行和第二行分别是原字符和加密后字符的对应,请使用任意一种语言(如PHP、PERL、C/C++、Java等)实现上述加密过程,
如字符"a"替换成字符"u"等,具体的功能要求如下:
·从文件载入上述密码表。
·对指定的文件实施加密,保存在新的文件中。
·请考虑算法的复杂度和异常处理能力。
二、数据库设计题:
请设计一套图书馆借书管理系统的数据库表结构;可以记录基本的用户信息、图书信息、借还书信息;数据表的个数不超过6个;
请画表格描述表结构(需要说明每个字段的字段名、字段类型、字段含义描述);
在数据库设计中应:
1.
保证每个用户的唯一性;
2.
保证每种图书的唯一性;每种图书对应不等本数的多本图书;保证每本图书的唯一性;
3.
借书信息表中,应同时考虑借书行为与还书行为,考虑借书期限;
4.
保证借书信息表与用户表、图书信息表之间的参照完整性;
5.
限制每个用户最大可借书的本数
6.
若有新用户注册或新书入库,保证自动生成其唯一性标识
7.
为以下的一系列报表需求提供支持:
(无特定说明,不需编写实现语句,而需在数据库设计中,保证这些报表可以用最多一条SQL语句实现)
a) 日统计报表:当日借书本数、当日还书本数报表;
b) 实时报表:
i. 当前每种书的借出本数、可借本数;
ii. 当前系统中所有超期图书、用户的列表及其超期天数
iii. 当前系统中所有用户借书的本数,分用户列出(包括没有借书行为的用户);请编写实现此需求的SQL语句:
数据库应用:
请撰写一系列的SQL语句,分别描述完整的借书行为与还书行为;并保证这一系列的SQL语句的执行完整性。
三、日志分析与统计
假设某访问日志文件的格式如下:
2005-01-09 07:02:23 | 127.0.0.1 | c=2 t=4
2005-01-09 17:12:09 | 192.168.0.1 | c=1 t=5
即:每行为一条记录,记录的格式如下:"时间 | IP | c=? t=?",每天所有的访问都记录在一个文件里。
现要求统计如下内容:
·每个IP每天的访问次数;
·每个IP每小时的访问次数;
请考虑统计程序如何实现,给出设计思路和关键算法(可使用伪代码)。可以考虑多种思路,并分析在什么情况(如数据量多少等)
下应使用哪种思路。