数据结构和算法 试题

部分    数据结构和算法

1.       假设执行语句S的时间为O(1),则执行下列程序短的时间为()

for(i=1;i<=n;i++)

       for(j=I;j<=n;j++)

              S;

A.        O(n)

B.        O(n2)

C.        O(n*i)

D.       O(n+1)

 

2.      
二位数组A[10…20,5…10]采用行序为主序方式存储,每个数据元素占4个存储单元,且A[10][5]的存储地址是1000,则A[18][9]的地址是()

A.        1208

B.        1212

C.        1368

D.       1364

 

3.      
设栈最大长度为3,入栈序列为1,2,3,4,5,6,则不可能得出栈序列是()

A.        1,2,3,4,5,6

B.        2,1,3,4,5,6

C.        3,4,2,1,5,6

D.       4,3,2,1,5,6

 

4.       设有98个已排序列元素,采用二分法查找时,最大比较次数是()

A.        49

B.        15

C.        20

D.       7

 

5.      
Hash表示用于数据存储的一种有效的数据结构,Hash表等查找复杂度依赖于Hash值算法的有效性,在最好的情况下,Hash表的查找复杂度为()

A.        O(1)

B.        O(logn)

C.        O(n)

D.       O(nlogn)

 

第二部分    软件工程

 

1.    软件能力成熟度模型CMM共分为()成熟度等级

A.    3

B.    4

C.    5

D.    6

 

2.   
按照是否了解软件的内部构造,可以将测试分为黑盒测试和白盒测试。考虑以下算法的PDL语句,如果要对其进行完全路径覆盖的白盒测试,则需要()条路径。

do ehile records remain

       read record;

       if record field 1 = 0

              then process record;

                     store in buffer;

                     increment counter;

              elseif record field 2 = 0

                     then reset counter;

                     else process record;

                     store in file;

              endif

       endif

enddo

A.    4

B.    5

C.    6

D.    7

 

3.   
按照瀑布模型的阶段划分,软件测试可以分为单元测试,集成测试,系统测试。请问以下那项测试不属于系统测试的内容()

A.    压力测试

B.    接口测试

C.    功能测试

D.    安全测试

E.    性能测试

 

4.    测试用例的设计是测试的重要阶段。系统测试用例设计应该从什么时候开始()

A.    需求完成

B.    详细设计完成

C.    编码完成

D.    系统集成完毕,提交系统测试

 

5.   
在UML方法中,使用多种类型的图形来帮助进行设计,请问一下那些图形不是UML的图形类型()

A.    类图

B.    实体关系图

C.    序列图

D.    活动图

 

第三部分    Java语言及其他

 

1.    下面哪个是short型的取值范围:()

A.    -27--- 27-1

B.    0 --- 216-1

C.    -215--- 215-1

D.    -231---231-1

 

2.    下面哪项是不合法的标识符:()

A.    $persons

B.    TwoUsers

C.    *point

D.    _endline

 

3.    设 float x = 1,y = 2,z = 3,则表达式 y+=z--/++x 的值是()

A.    3.5

B.    3

C.    4

D.    5

 

4.    下列哪些关键字即能够被用于局部变量的修饰,也可以用做类变量的修饰()

A.    public

B.    transient

C.    static

D.    finally

 

5.    以下的语句构造了几个JAVA对象?()

       String S = new String(“aaa”);

A.    1

B.    2

C.    3

 

6.    下面的哪些叙述为真()

A.    equals()方法判定引用值是否指向同一对象

B.    = = 操作符判定两个不同的对象的内容和类型是否一致

C.    equal() 方法只有在两个对象的内容一致时返回ture

D.    类File重写方法equals()在两个不同的对象的内容和类型一致时返回ture

 

7.   
如果一个对象仅仅声明实现了cloneable接口,但是不声明clone方法,外部能够调用其clone方法吗?()

A.    能

B.    不能

C.    不确定

 

8.   
考虑在C/S结构下,服务器接受并处理请求,那么关于服务器处理请求的模式,哪些描述是错误的()

A.    单线程模式下,服务器使用一个线程顺序的处理所有的请求,可能导致阻塞

B.   
服务器可以为每一个请求创建一个线程来处理该请求,这样做比单线程模式更加稳定

C.   
线程池模式下,当线程使用达到最大数量限制之后,线程池中没用可用线程的时候,服务器将阻塞或者拒绝某个请求的处理

 

9.   
使用Swing做界面的时候,如果把一个JButton放在一个JFrame中,在JFrame改变时只影响JButton的高度而宽度不受影响,应该使用哪个布局管理器?()

A.    FlowLayout

B.    CardLayout

C.    North and South of BorderLayout

D.    East and West of BorderLayout

E.    GridLayout

 

10.   以下的那个状态是EntityBean所具有,而StatelessBean不具有的()

A.    池态

B.    就绪态

C.    不存在态

D.    钝化态

 

11.   以下关于数据库范式的描述,哪些是错误的()

A.    如果把多个数据项用一个大的String表示为一个字段,则不满足第一范式

B.    满足数据库范式使得数据库的效率更高

C.    如果满足更高的范式,则必须首先满足低级别的范式

D.    数据库第二范式要求把表中与所有键没有直接关系的数据全部拆分到其他表中

 

12.  
考虑一下需求:包括学生、课程和教师的信息。其中学生的信息包括学生姓名、年龄地址等;课程信息包括课程号、课程名、课程学分等;教师信息包括教师的姓名、教师的地址等。一个学生可以选修多门课,而每门课也能有多个学生选修;一位教师可以教多门课,每门课也可以由多个教师讲授。请问如果使用关系数据库,并且达到第二范式的要求,需要设计()张表

A.    3

B.    4

C.    5

D.    6

 

13.  
为了加快数据库查找的速度,需要对数据表添加索引,请问以下关于索引的描述,哪些是错误的()

A.    聚类索引中,表中行的物理次序与索引键值的逻辑顺序相同

B.    使用索引会使得数据更新的效率降低

C.    在大多数数据库系统中,每张表只能够有一个聚类索引

D.    考虑这个SQL语句:Select S.name,S.age from Student S where
S.address=”成都”,如果我们对表Student建一个复合索引(age,address),可以改善上述查询的效率。

 

第四部分    问答题

1.    简述一个Linux驱动程序的主要流程与功能。

 

2.    请列举一个软件中时间换空间或者空间换时间的例子。

 

3.    简述进程与线程的区别。

 

4.    static有什么用途?(请至少说明两种)

 

5.    头文件中的ifndef/define/endif做什么用?

 

6.    请问一下程序将输出什么结果?

char *RetMenory(void)

{

       char p[] = “hellow world”;

       return p;

}

void Test(void)

{

       char *str = NULL;

       str = RetMemory();

       printf(str);

}

 

7.    引用与指针有什么区别?

 

8.    描述实时系统的基本特性

 

9.    全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

 

10.   什么是平衡二叉树?

 

11.   堆栈溢出一般是由什么原因导致的?

 

12.   什么函数不能声明为虚函数?

 

13.   冒泡排序算法的时间复杂度是什么?

 

14.   #include <filename.h> 和 #include “filename.h” 有什么区别?

 

15.   写出float x 与“零值”比较的if语句。

 

16.   操作系统中进程调度策略有哪几种?

 

17.   Internet采用哪种网络协议?该协议的主要层次结构?

 

18.   Internet物理地址和IP地址转换采用什么协议?

 

19.   IP地址的编码分为哪俩部分?


写一个程序, 要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数。
如:100个1是一个组合,5个1加19个5是一个组合。。。。 请用C++语言写。

答案:最容易想到的算法是:
设x是1的个数,y是2的个数,z是5的个数,number是组合数
注意到0<=x<=100,0<=y<=50,0<=z=20,所以可以编程为:


number=0;
for (x=0; x<=100; x++)
for (y=0; y<=50; y++)
for (z=0; z<=20; z++)
if ((x+2*y+5*z)==100)
number++;
cout<<number<<endl;


上面这个程序一共要循环100*50*20次,效率实在是太低了
事实上,这个题目是一道明显的数学问题,而不是单纯的编程问题。我的解法如下:
因为x+2y+5z=100
所以x+2y=100-5z,且z<=20 x<=100 y<=50
所以(x+2y)<=100,且(x+5z)是偶数
对z作循环,求x的可能值如下:

z=0, x=100, 98, 96, ... 0
z=1, x=95, 93, ..., 1
z=2, x=90, 88, ..., 0
z=3, x=85, 83, ..., 1
z=4, x=80, 78, ..., 0
......
z=19, x=5, 3, 1
z=20, x=0

因此,组合总数为100以内的偶数+95以内的奇数+90以内的偶数+...+5以内的奇数+1,
即为:
(51+48)+(46+43)+(41+38)+(36+33)+(31+28)+(26+23)+(21+18)+(16+13)+(11+8)+(6+3)+1


某个偶数m以内的偶数个数(包括0)可以表示为m/2+1=(m+2)/2
某个奇数m以内的奇数个数也可以表示为(m+2)/2

所以,求总的组合次数可以编程为:
number=0;
for (int m=0;m<=100;m+=5)
{
number+=(m+2)/2;
}
cout<<number<<endl;
这个程序,只需要循环21次, 两个变量,就可以得到答案,比上面的那个程序高效了许多
倍----只是因为作了一些简单的数学分析

这再一次证明了:计算机程序=数据结构+算法,而且算法是程序的灵魂,对任何工程问
题,当用软件来实现时,必须选取满足当前的资源限制,用户需求限制,开发时间限制等种
种限制条件下的最优算法。而绝不能一拿到手,就立刻用最容易想到的算法编出一个程序了
事——这不是一个专业的研发人员的行为。

那么,那种最容易想到的算法就完全没有用吗?不,这种算法正好可以用来验证新算法
的正确性,在调试阶段,这非常有用。在很多大公司,例如微软,都采用了这种方法:在调
试阶段,对一些重要的需要好的算法来实现的程序,而这种好的算法又比较复杂时,同时用
容易想到的算法来验证这段程序,如果两种算法得出的结果不一致(而最容易想到的算法保
证是正确的),那么说明优化的算法出了问题,需要修改。
可以举例表示为:
#ifdef DEBUG
int simple();
#end if
int optimize();
......
in a function:
{
result=optimize();
ASSERT(result==simple());
}
这样,在调试阶段,如果简单算法和优化算法的结果不一致,就会打出断言。同时,在程
序的发布版本,却不会包含笨重的simple()函数。——任何大型工程软件都需要预先设计良
好的调试手段,而这里提到的就是一种有用的方法。

 

一个学生的信息是:姓名,学号,性别,年龄等信息,用一个链表,把这些学生信息连在一起,
给出一个age, 在些链表中删除学生年龄等于age的学生信息。

#include "stdio.h"
#include "conio.h"

struct stu{
char name[20];
char sex;
int no;
int age;
struct stu * next;
}*linklist;
struct stu *creatlist(int n)
{
int i;
//h为头结点,p为前一结点,s为当前结点
struct stu *h,*p,*s;
h = (struct stu *)malloc(sizeof(struct stu));
h->next = NULL;
p=h;
for(i=0;i<n;i++)
{
s = (struct stu *)malloc(sizeof(struct stu));
p->next = s;
printf("Please input the information of the student: name sex no age \n");
scanf("%s %c %d %d",s->name,&s->sex,&s->no,&s->age);
s->next = NULL;
p = s;
}
printf("Create successful!");
return(h);
}
void deletelist(struct stu *s,int a)
{
struct stu *p;
while(s->age!=a)
{
p = s;
s = s->next;
}
if(s==NULL)
printf("The record is not exist.");
else
{
p->next = s->next;
printf("Delete successful!");
}
}
void display(struct stu *s)
{
s = s->next;
while(s!=NULL)
{
printf("%s %c %d %d\n",s->name,s->sex,s->no,s->age);
s = s->next;
}
}
int main()
{
struct stu *s;
int n,age;
printf("Please input the length of seqlist:\n");
scanf("%d",&n);
s = creatlist(n);
display(s);
printf("Please input the age:\n");
scanf("%d",&age);
deletelist(s,age);
display(s);
return 0;
}

2、实现一个函数,把一个字符串中的字符从小写转为大写。

#include "stdio.h"
#include "conio.h"

void uppers(char *s,char *us)
{
for(;*s!='\0';s++,us++)
{
if(*s>='a'&&*s<='z')
*us = *s-32;
else
*us = *s;
}
*us = '\0';
}
int main()
{
char *s,*us;
char ss[20];
printf("Please input a string:\n");
scanf("%s",ss);
s = ss;
uppers(s,us);
printf("The result is:\n%s\n",us);
getch();
}

随机输入一个数,判断它是不是对称数(回文数)(如3,121,12321,45254)。不能用字符串库函数

/***************************************************************
1.
函数名称:Symmetry
功能: 判断一个数时候为回文数(121,35653)
输入: 长整型的数
输出: 若为回文数返回值为1 esle 0
******************************************************************/
unsigned char Symmetry (long n)
{
long i,temp;
i=n; temp=0;
while(i) //不用出现长度问题,将数按高低位掉换
{
temp=temp*10+i%10;
i/=10;
}
return(temp==n);
}
方法一
/*
---------------------------------------------------------------------------
功能:
判断字符串是否为回文数字
实现:
先将字符串转换为正整数,再将正整数逆序组合为新的正整数,两数相同则为回文数字
输入:
char *s:待判断的字符串
输出:

返回:
0:正确;1:待判断的字符串为空;2:待判断的字符串不为数字;
3:字符串不为回文数字;4:待判断的字符串溢出
----------------------------------------------------------------------------
*/
unsigned IsSymmetry(char *s)
{
char *p = s;
long nNumber = 0;
long n = 0;
long nTemp = 0;

/*判断输入是否为空*/
if (*s == \'\\0\')
return 1;

/*将字符串转换为正整数*/
while (*p != \'\\0\')
{
/*判断字符是否为数字*/
if (*p<\'0\' || *p>\'9\')
return 2;

/*判断正整数是否溢出*/
if ((*p-\'0\') > (4294967295-(nNumber*10)))
return 4;

nNumber = (*p-\'0\') + (nNumber * 10);

p++;
}

/*将数字逆序组合,直接抄楼上高手的代码,莫怪,呵呵*/
n = nNumber;
while(n)
{
/*判断正整数是否溢出*/
if ((n%10) > (4294967295-(nTemp*10)))
return 3;

nTemp = nTemp*10 + n%10;
n /= 10;
}

/*比较逆序数和原序数是否相等*/
if (nNumber != nTemp)
return 3;

return 0;
}

方法二
/*
---------------------------------------------------------------------------
功能:
判断字符串是否为回文数字
实现:
先得到字符串的长度,再依次比较字符串的对应位字符是否相同
输入:
char *s:待判断的字符串
输出:

返回:
0:正确;1:待判断的字符串为空;2:待判断的字符串不为数字;
3:字符串不为回文数字
----------------------------------------------------------------------------
*/
unsigned IsSymmetry_2(char *s)
{
char *p = s;
int nLen = 0;
int i = 0;

/*判断输入是否为空*/
if (*s == \'\\0\')
return 1;

/*得到字符串长度*/
while (*p != \'\\0\')
{
/*判断字符是否为数字*/
if (*p<\'0\' || *p>\'9\')
return 2;

nLen++;
p++;
}

/*长度不为奇数,不为回文数字*/
if (nLen%2 == 0)
return 4;

/*长度为1,即为回文数字*/
if (nLen == 1)
return 0;

/*依次比较对应字符是否相同*/
p = s;
i = nLen/2 - 1;
while (i)
{
if (*(p+i) != *(p+nLen-i-1))
return 3;

i--;
}

return 0;
}

求2~2000的所有素数.有足够的内存,要求尽量快


答案:
int findvalue[2000]={2};
static int find=1;
bool adjust(int value)
{
assert(value>=2);
if(value==2) return true;
for(int i=0;i<=find;i++)
{
if(value%findvalue[i]==0)
return false;
}
findvalue[find++];
return true;
}


1.printf的输出问题

printf("%d",total);//this is right
printf(total);//this is wrong
printf("hello");//but this is right

2.整数类型的长度
char 1个子节,8位

unsigned short [int]
[signed] short int
short 2个字节,16位

[signed] int
unsigned int
int 型在vc里是4个子节,32位,也可能是16位,2个字节

long [int]
unsigned long [int]

long型都是32位,4个字节

float 32 ,4

double 64,8

long double 128,16

char 8,一个字节,存放的实际上是字符的ascii码

3、找出错误并改正

char *my_cpy(char* src, int len){
char dest[1024];
memcpy(dest, src, len);
return dest;
}
上面的函数是否有问题,如果有指出其所在,如果没有,给出函数功能描述。

答案:
1。数组应该初始化
2。memcpy不判断是否越界,所以调用前应该判断是否越界
3。不应该返回rest,因为这个数组是在函数内部申请的,所以函数结束之后就会消失,指针也会变成“野指针”,所以指向非法地址
最后一个比较隐蔽

char *memcpy( char *dest, const char *src,int len )
{
char* pDest = (char*)dest;
char* pSrc = (char*)src;
int pos;
for(pos=0;pos{
pDest[pos] = pSrc[pos];
}
return (char*)pDest;
}

存在地问题就是没有判断指针是否非法assert(dest !=NULL || src != NULL); 条件为
FLASE 显示

 

不调用其他函数,写一个memcpy的函数,函数原型为
void *memcpy(void *dest, void *src, size_t length);

-----------利用好断言---------

/* memcpy ─── 拷贝不重叠的内存块 */
void memcpy(void* pvTo, void* pvFrom, size_t size)
{
void* pbTo = (byte*)pvTo;
void* pbFrom = (byte*)pvFrom;
ASSERT(pvTo != NULL && pvFrom != NULL);
/* 内存块重叠吗?如果重叠,就使用memmove */
ASSERT(pbTo>=pbFrom+size || pbFrom>=pbTo+size);
while(size-->0)
*pbTo++ == *pbFrom++;
return(pvTo);
}

-----------------------

常见函数编程:
char *strcpy(char *strDest, const char *strSrc)
{
ASSERT(strDest != NULL && strSrc != NULL);
char *addr = strDest;
while(*strDest++=*strSrc++)
NULL; //NULL可以省略,但更有利于编译器发现错误
}
return addr;
}

void *memcpy(void *dest, const void *src, int count)
{
ASSERT(dest!= NULL && src!= NULL);
for(int i=0; i< cout; i++)
{
dest[i] = src[i];
}
}
int strcmp(const char*str1, const char *str2)
{
while (str1 != NULL && str2 != NULL)
{
if(*str1 < *str2) return -1;
else if(*str1 > *str2) return 1;
else { str1++; str2++;}
}
if(str1 == NULL && str2 != NULL)
return -1;
else if(str1 != NULL && str2 == NULL)
return 1;
else return 0;
}

//way2: more compact
int strcmp(const char*str1, const char *str2)
{
int i = strlen( str1 );
int j;
for(j=0; j<=i; j++)
{
if(str1[j] > str2[j]) return 1; //if str2 terminates, then str2[j]=0,
str1[j]>str2[j], return 1;
else if(str1[j] < str2[j]) return -1;
else if(str1[j] == '\0') return 0;
}
}
//way3: optimize again.
int strcmp(const char * str1, const char * str2 )
{
while(1)
{
if(*str1 > *str2) return 1;
else if(*str1 < *str2) return -1;
else if(*str1 == '\0') return 0;
str1++;str2++;
}
}


 

你可能感兴趣的:(数据结构,算法,数据库,struct,测试,null)