1. 网络计算题
1.1 码分多址
1.1.1 码分多址习题1
两个站点A和B,要向C发送数据,采用码分多址的方法,其中:
- A的芯片序列为: +1,-1,-1,+1,+1,+1,+1,-1
- B的芯片序列为: -1,+1,-1,+1,-1,+1,+1,+1
请问:
- 如果A发送1则发出的是什么,如果A发送0则发出的是什么。
- AB是否可以同时发送数据?
- 假设A发送1,B发送1。那么C收到的码片序列是什么。
- 如果C接收到的码片序列(-2,+2,0,0,-2,0,0,+2)问哪个站发送数据了?发送数据的站发送的1还是0?
1. 发送1时发送芯片序列,发送0是发送芯片序列反码,则答案为:
- 发送1时:+1,-1,-1,+1,+1,+1,+1,-1
- 发送0时:-1,+1,+1,-1,-1,-1,-1,+1
2. 多个站点同时发送数据的时候,要求各个站点芯片序列相互正交,规格化内积为0
(+1 -1 -1 +1 +1 +1 +1 -1)·(-1 +1 -1 +1 -1 +1 +1 +1) / 8
= (-1 -1 +1 +1 -1 +1 +1 -1) / 8
= 0
答:可以发送数据
3. A发送的和B发送的在信道中被线性相加
(+1 -1 -1 +1 +1 +1 +1 -1) + (+1 -1 +1 -1 +1 -1 -1 -1)
= (+2 -2 0 0 +2 0 0 0)
4. 合并的数据和源站规格化内积
对A内积
(-2 +2 0 0 -2 0 0 +2)·(+1 -1 -1 +1 +1 +1 +1 -1) / 8
=(-2 -2 0 0 -2 0 0 -2) / 8
= -1
可知 A 发送的为 0
对B内积
(-2 +2 0 0 -2 0 0 +2)·(-1 +1 -1 +1 -1 +1 +1 +1) / 8
=(+2 +2 0 0 +2 0 0 +2) / 8
= 1
可知 B 发送的为 1
1.1.2 码分多址习题2
共有四个站进行码分多址 CDMA 通信。四个站的码片序列为:
- A (-1 -1 -1 +1 +1 -1 +1 +1)
- B (-1 -1 +1 -1 +1 +1 +1 -1)
- C (-1 +1 -1 +1 +1 +1 -1 -1)
- D (-1 +1 -1 -1 -1 -1 +1 -1)
现收到这样的码片序列:(-1 +1 -3 +1 -1 -3 +1 +1)。问哪个站发送数据了?发送数据的站发送的1还是0?
题解:
A站的内积:
(-1+1-3+1-1-3+1+1)·(-1-1-1+1+1-1+1+1)/8 = (+1-1+3+1-1+3+1+1)/8 = 1
B站的内积:
(-1+1-3+1-1-3+1+1)·(-1-1+1-1+1+1+1-1)/8 = (+1-1-3-1-1-3+1-1)/8 = -1
C站的内积:
(-1+1-3+1-1-3+1+1)·(-1+1-1+1+1+1-1-1)/8 = (+1+1+3+1-1-3-1-1)/8 = 0
D站的内积:
(-1+1-3+1-1-3+1+1)·(-1+1-1-1-1-1+1-1)/8 = (+1+1+3-1+1+3+1-1)/8 = 1
因此,A和D发送1,B发送0,而C未发送数据。
1.1.3 码分多址习题3
一条广播信道上接有3个站点A、B、C,介质访问控制采用信道划分方法,信道的划分采用码分复用技术,A,B要向C发送数据,设A的码序列为 +1,-1,-1,+1,+1,+1,+1,-1。站B可以可以选用的码片序列为()
- -1,-1,-1,+1,-1,+1,+1,+1
- -1,+1,-1,-1,-1,+1,+1,+1
- -1,+1,-1,+1,-1,+1,-1,+1
- -1,+1,-1,+1,-1,+1,+1,+1
题解:
B站点选用的码片序列一定要与 A 站点序列正交,且规格化内积为0。分别计算ABCD:
例如D:(+1-1-1+1+1+1+1-1)·(-1+1-1+1-1+1+1+1)/8 = 0
答案为D
1.2 网络层相关
1.2.1 子网划分
注:就目前来说,现在可以使用全0和全1子网。但我们现在学习时,还强调子网划分时要去掉全0全1
现有一公司需要创建内部网络,该公司包括工程技术部,市场部,财务部,办公室4个部门,每个部门有20 - 30 台计算机,试问:
- 若要将几个部门从网络上分开,如果分配给该公司使用的地址为一个 C 类地址,网络地址为192.168.161.0,那么如何划分网络?可以将几个部门分开?
- 确定各部门的网络地址和子网掩码,并写出分配给每个部门网络中的主机IP地址范围。
答:
1. 可以采用划分子网的方法对该公司的网络进行划分。由于该公司包括4个部门,共需要划分为4个子网
2.
已知:网络地址192.168.161.0 是一个C类地址,
所需的子网数为4,
每个子网的主机数为20-30台。
由于:自子网号和主机号不允许为全0或全1,因此子网号的比特数为3,即最多有2^3 -2 = 6 个可分配的子网,主机号的比特数为5,即每个子网最多有2^5 -2 = 30 个可分配的IP地址。
4个部门的子网掩码均为255.255.255.224,各部门的网络地址与部门主机的IP地址范围可分配如下:
————————————————————————————————————————————————————————————————————————————
| 部门 | 部门网络地址 | 主机IP地址范围 |
| 技术部 | 192.168.161.32 | 192.168.161.33 - 192.168.161.62 |
| 市场部 | 192.168.161.64 | 192.168.161.65 - 192.168.161.94 |
| 财务部 | 192.168.161.96 | 192.168.161.97 - 192.168.161.126 |
| 办公室 | 192.168.161.128 | 192.168.161.129 - 192.168.161.158 |
————————————————————————————————————————————————————————————————————————————
1.2.2 路由聚合
在4个“/24”地址块中进行最大可能的聚合:
- 212.56.132.0/24
- 212.56.133.0/24
- 212.56.134.0/24
- 212.56.135.0/24
由于一个CIDR地址块中可以包含多个地址,所以路由表中就利用CIDR地址块来查找目的网络,这种地址的聚合常称为路由聚合。
本题已知有212.56.132.0/24、212.56.133.0/24、212.56.134.0/24、212.56.135.0/24地址块,
可知第三字节的前6位都相同,因此共同前缀8+8+6=22位,由于这4个地址块的第1、2个字节相同,考虑他们第3个字节即可。
132 = 10000100
133 = 10000101
134 = 10000110
135 = 10000111
所以共同的前缀有22位,所以聚合的CIDR地址块是212.56.132.0/22
1.3 检错编码
1.3.1 奇偶校验码
奇偶校验码由 1 位校验元和 n-1 位信息元构成。信息元就是发送的数据,校验元就是奇偶校验的冗余码。
- 奇校验:1的个数为奇数
- 偶校验:1的个数为偶数
如果一个字符S的ASCII编码从低到高依次为1100101,采用奇校验,在下述收到的传输后字符中,那种错误不能检测?
- 11000011
- 11001010
- 11001100
- 11010011
解析:
我们字符S的编码1100101就是n-1位信息元,如果采用奇校验,则需要在最前面添上一个冗余码,使得总共1的个数为奇数,如果采用偶校验,加上校验元后,总共1的个数则为偶数,所以这道题发送的应该是11100101
奇偶校验码特点:
只能检查出奇数个比特错误,检错能力为50%
1.3.2 CRC循环冗余码
要发送的数据是1101 0110 11,采用CRC校验,生成多项式是10011,那么最终发送的数据应该是?接收端是如何检错的?
解析: 最终发送的数据 = 要发送的数据+帧检验序列FCS(冗余码)
如何计算冗余码?
-
加r个0
-
使用模2除法
1.加0 假设生成的多项式G(x)的阶为r则加r个0
10011的多项式为x4 + x1 + x0 ,所以阶为 4 ,加4个0
则1101 0110 1100 00
2.模2除法
数据加0后使用模2除法除以多项式,余数就是冗余码
1100001
10011 √11010110110000
10011
10011
10011
0000010110
10011
10100
10011
1110
最后的1110就是冗余码(FCS)
所以最终发送的就是110101101100 1110
那么接收端是如何检错的?
把收到的在模2除法除以多项式,然后检查得到余数R。
- 余数为0,这个帧没有差错,接收。
- 余数不为0,有差错,但不知道哪错了,所以只能丢弃。
2. 数据库大题
2.1 函数依赖
2.1.1 函数依赖习题1
设有关系模式 R(职工名,项目名,工资,部门名,部门经理)
如果规定:
- 每个职工可参加多个项目,各领一份工资;
- 每个项目只属于一个部门管理;
- 每个部门只有一个经理。
请回答下面几个问题:
- 试写出关系模式 R 的基本函数依赖和主码。
- 说明 R 不是 2NF 模式的理由,并把 R 分解成 2NF 。
- 进而将 R 分解成 3NF ,并说明理由。
分析:
--------第一问---------
1.试写出关系模式 R 的基本函数依赖和主码。
依赖关系我们使用 → 表示,可以理解为指向谁就代表可以推出谁,或者归谁管。比如:
- 职工名和项目名合在一起可以推出工资是多少就可以表示为:(职工名,项目名)→工资
- 项目归部门管,可以表示为:项目名→部门名
- 部门归部门经理管可以表示为:部门名→部门经理
好了,到现在为止我们就已经将第一问中的函数依赖写出来了,我们再来捋一下:
- 部门经理依赖于部门,也就是说要先确定部门才能确定部门经理,所以是依赖关系;
- 而部门依赖于项目,要先确定项目才能确定部门;
- 工资依赖于两个属性:职工名和项目名。
那么主码又是什么呢?
- 主码也叫主键,是指可以通过它唯一确定一条数据的这样一个属性。
- 比如学号就可以做主键,因为一个学号对应一个学生。
那么这里的主键是什么呢?
- 我们就要找通过谁可以唯一确定一条记录,
- 项目名肯定不行,因为他和职工名一起才可以确定工资,
- 那职工名肯定也不行,但是把它们合在一起就可以了,这样就可以确定唯一的一条记录。
- 所以,主键为(职工名,项目名)。
所以答案就是:
- 函数依赖关系:
- (职工名,项目名)→工资
- 项目名→部门名
- 部门名→部门经理
- 主键为(职工名,项目名)。
--------第二问---------
2.说明 R 不是 2NF 模式的理由,并把 R 分解成 2NF 。
2NF 是什么呢?
- 2NF就是一种规范,他规定不能存在部分依赖。
部分依赖是啥意思呢?
- 就是我们只看依赖于主键的属性,这里有工资和部门名,
- 但是他们两个的区别是工资对应的全部的主键,也就是两个值,
- 但是部门名只依赖于项目名,少了一个,所以是部分依赖。
- 所以他存在了部分依赖就不是 2NF 模式了。
那么怎么把它化成 2NF 呢?
- 一般我们只能通过分解的方式来消除,就是把一个关系拆成两个关系:
- R1(项目名,部门名,部门经理)
- R2(职工名,项目名,工资)
这样每个关系中就不存在部分依赖了
--------第三问---------
3.进而将 R 分解成 3NF ,并说明理由。
那么 3NF 又是啥?
- 我们先来观察上面那个 2NF 的关系,
- 发现有一个关系R1(项目名,部门名,部门经理),
- 他比较特殊,就是项目名→部门名,部门名→部门经理,
- 他是连续的,就是传递性的依赖关系,3NF 就是要去掉这种依赖关系。
- 那么我们可以把 R1 再分成两个关系:
- R11(项目名,部门名)
- R12(部门名,部门经理)
最后总结一下 2NF 和 3NF 的关系:
|
| 1NF
| ↓ 消除非主属性对码的部分依赖
| 2NF
| ↓ 消除非主属性对码的传递依赖
| 3NF
↓
2.1.2 函数依赖习题2
设有关系模式R(A,B,C,D,E,F),其函数依赖集为:F={E→D,C→B,CE→F,B→A}。
请回答如下问题:
- 指出 R 的所有候选码并说明原因;
- R 最高属于第几范式,为什么?
- 分解 R 为 3NF。
1. 指出 R 的所有候选码并说明原因;
- 候选码就是主码,即可以作为决定性因素的属性,
- 候选码可以 → 所有的值,通俗地讲就是只能出现在箭头的前面,不能出现在后面。
- 那这里A、B、D、F四个属性肯定是不行了,只有 C和E了,
- 发现 CE 之间没有依赖关系,并且CE→ABCDEF,所以CE就是候选码。
2. R 最高属于第几范式,为什么?
- 我们来看一下有没有部分依赖,大家可以先自己想一下什么是部分依赖。
- 这里主键不是两个吗?
- 我们要找的就是哪一个属性只依赖于其中的一个主键,也就是只依赖于 C 或者 E ,
- 可以看到 B 和 D 都是部分依赖,同时 B 和 A 是传递依赖,就等同于 C→A,
- 所以 A 也是 部分依赖于 C 。那他肯定就不符合 2NF 了,那最多就是 1NF 了。
3. 分解 R 为 3NF。
- 首先分解为 2NF:模仿第一道题题目,把那个主键的单独拿出来:
- R1(E,D)
- R2(C,B,A)
- R3(C,E,F)
- 区分的依据就是看看有没有依赖关系,有依赖关系就放一起。
- 然后我们化成 3NF ,就是去掉传递依赖,发现 R2 是传递依赖,
- 所以把他化成R21(C,B) 和 R22(B,A),这样就有 4 个关系了,他们都是 3NF 模式的。
- R1(E,D)
- R21(C,B)
- R22(B,A)
- R3(C,E,F)
2.1.3 函数依赖习题3
设有关系模式R(A,B,C,D,E),其函数依赖集为F={A→B,CE→A,E→D}
请回答如下问题:
- 指出 R 的所有候选码,并说明理由;
- R 最高属于第几范式(在1NF~3NF范围内),为什么?
- 将 R 分解到 3NF。
1. 候选码:CE,因为CE→ABCDE;
2. 可以看到 D 只依赖于 E,但是主键是 CE,所以 D 是部分依赖于 CE,那么最高就是 1NF 了。
3. R1={C,E,A},R2={E,D},R3={A,B}
2.1.4 函数依赖习题4
设有一个记录各个球队队员每场比赛进球数的关系模式,R(队员编号,比赛场次,进球数,球队名,队长名)
如果规定,每个队员只能属于一个球队,每个球队只有一个队长。
- 试写出关系模式 R 的基本函数依赖和主码。
- 说明 R 不是 2NF 模式的理由,并把 R 分解成 2NF 。
- 进而将 R 分解成 3NF 。
1. 试写出关系模式 R 的基本函数依赖和主码。
- 每一个队员对应一个球队:队员编号→球队名
- 每一个球队对应一个队长:球队名→队长名
- 进球数肯定是统计的某一个场次的某一个球员的进球数,所以球员和比赛场次对应进球数:
- (队员编号,比赛场次)→进球数
- 根据经验,主键肯定是那个两个的了。
解答:关系模式R的基本函数依赖F如下
- F = { 队员编号→球队名,球队名→队长名,(队员编号,比赛场次)→进球数 }
- 其主键为(队员编号,比赛场次)。
2. 说明 R 不是 2NF 模式的理由,并把 R 分解成 2NF 。
- 理由:球队名部分依赖于主键
- 分解:
- R1={队员编号,球队名,队长名}
- R2={球队名,比赛场次,进球数}
3. 进而将 R 分解成 3NF 。
- R11={队员编号,球队名}
- R12={球队名,队长名}
- R2={球队名,比赛场次,进球数}
2.2 关系代数
2.2.1 除运算
除法运算的一般形式示意图:
这里通过一个实例来说明除法运算的求解过程
题目: 设有关系R、S如图所示,求R÷S的结果
R: S:
|+++++++++++| |+++++++++++|
| X | Y | | Y | F |
|+++++|+++++| |+++++|+++++|
| X1 | Y1 | | Y1 | F1 |
| X2 | Y2 | | Y2 | F3 |
| X2 | Y3 | |+++++++++++|
| X2 | Y1 |
|+++++++++++|
解答:
1.找出关系R和关系S中相同的属性,即Y属性。
— 在关系S中对Y做投影(即将Y列取出)
- 所得结果如下:
| Y |
|+++++|
| Y1 |
| Y2 |
2.找到被除关系R中与S中不相同的属性列,即X属性。
- 关系R在属性(X)上做取消重复值的投影为{X1,X2}。
3.求关系R中X属性对应的像集
- 值X1对应的像集: |+++++++++++|
| X | Y |
|+++++|+++++|
| X1 | Y1 |
|+++++++++++|
- 值X2对应的像集: |++++++++++++|
| X | Y |
|+++++|+++++|
| | Y1 |
| X1 | Y2 |
| | Y3 |
|+++++++++++|
4.判断包含关系
- R÷S其实就是判断关系R中X各个值的像集是否包含关系S中属性Y的所有值。
- 对比即可发现:
- X1的像集只有Y1,不能包含关系S中属性Y的所有值,所以排除掉X1
- 而X2的像集包含了关系S中的属性Y的所有值,所以R÷S的最终结果就是X2.
答案:
R÷S:
|+++++|
| X |
|+++++|
| X2 |
|+++++|
除算法可以解决什么问题?
设有关系S,C,以及SC,如下所示,求SC÷C的结果
S: C: SC:
|++++++++| |+++++++++| |+++++++++++++++|
| sname | | cname | | sname | cname |
| 张三 | | 语文 | | 张三 | 语文 |
| 张三 | | 数学 | | 张三 | 数学 |
| 张三 | |+++++++++| | 李四 | 数学 |
|++++++++| |+++++++++++++++|
很容易求得结果为:{张三 }
所以你很容易看出来SC÷C 在这里解决的问题就是:“得到选修了所有课程的学生”
SC÷C的意义就是:“在S和C的联系SC中,找出与C中所有的元组有关系的R元组”。
2.2.2 差运算
差运算的一般形式示意图如下所示
【例】设有关系S,C,以及SC,如下所示,求李四不学的课程,并用关系带数表示出来
S: C: SC:
|++++++++| |+++++++++| |+++++++++++++++|
| sname | | cname | | sname | cname |
| 张三 | | 语文 | | 张三 | 语文 |
| 张三 | | 数学 | | 张三 | 数学 |
| 张三 | |+++++++++| | 李四 | 数学 |
|++++++++| |+++++++++++++++|
解题思路:先求出李四学的课程,再用全部的课程 - 李四学的课程,即为李四不学的课程 。
-
李四学的课程。关系代数表示为:Πcname(σcname=李四 (SC) )
-
全部的课程 - 李四学的课程:Πcname (C) - Πcname(σcname=李四 (SC) )
-
结果:李四不学语文
2.2.3 关系代数习题
设有如图所示的三个关系,student,score,course:
- S
| sno | sname | age | sex |
|---|---|---|---|
| 1 | 李强 | 23 | 男 |
| 2 | 刘丽 | 22 | 女 |
| 5 | 张友 | 22 | 男 |
- C
| cno | cname | teacher |
|---|---|---|
| k1 | C语言 | 王华 |
| k5 | 数据库原理 | 程军 |
| k8 | 编译原理 | 程军 |
- SC
| sno | cno | grade |
|---|---|---|
| 1 | k1 | 83 |
| 2 | k1 | 85 |
| 5 | k1 | 92 |
| 2 | k5 | 90 |
| 5 | k5 | 84 |
| 5 | k8 | 80 |
试用关系代数表达式表示下列查询语句:
- 检索至少选修成军老师所授的全部课程的学生姓名
- 检索李强同学不学课程的课程号
- 检索至少选修两门课程的同学的学号
- 检索全部学生都选修的课程号和课程名
- 检索选修课程号为K1和K5的学生学号
- 检索选修全部课程的学生姓名
- 检索选修课程包含学号为 2 的学生所选修课程的学生学号
- 检索选修课程名为C语言的学生学号和姓名
- 检索一没有一门课程成绩不及格的学生学号和姓名
答案:
- 检索至少选修程军老师所授的全部课程的学生姓名
解答思路: 第一步:获得选修全部程军课程的学生学号
先求出课程表中教师为程军的课程号—关系A,和所有选课表中所有的 sno,cno—关系B。
A为:Π cno (σ teacher=程军 (C))
B为:Π sno,cno (SC)
A: B:
|++++++++| |++++++++++++++|
| cno | | sno | cno |
| k5 | | 1 | k1 |
| k8 | | 2 | k1 |
|++++++++| | 5 | k1 |
| 2 | k5 |
| 5 | k5 |
| 5 | k8 |
|++++++++++++++|
得到关系B中所有包含关系A所有值的关系 B ÷ A,从中获得选修全部程军课程的学生学号 5
关系代数为:Π sno,cno (SC) ÷ Π cno (σ teacher=程军 (C))
B ÷ A:
|++++++++|
| sno |
| 5 |
|++++++++|
第二步:从学生表中获取改学号对应的学生姓名
将 B ÷ A 与 S 做自然连接运算,得到(B÷A) ∞ S
B ÷ A: S:
|++++++++| |++++++++++++++++++++++++++++++++|
| sno | | sno | sname | age | sex |
| 5 | | 1 | 李强 | 23 | 男 |
|++++++++| | 2 | 刘丽 | 22 | 女 |
| 5 | 张友 | 22 | 男 |
|++++++++++++++++++++++++++++++++|
(B÷A) ∞ S :
|++++++++++++++++++++++++++++++++|
| sno | sname | age | sex |
| 5 | 张友 | 22 | 男 |
|++++++++++++++++++++++++++++++++|
再将(B÷A) ∞ S 中的 sname 投影出来,Π sname ( (B÷A) ∞ S )
带入A和B的关系代数,答案的关系代数为:
Π sname ( (Π sno,cno (SC) ÷ Π cno (σ teacher=程军 (C))) ∞ S )
-
检索李强同学不学课程的课程号
Π cno (C) - Π cno ( σsname=李强(S) ∞ SC )
-
检索至少选修两门课程的同学的学号
Π sno (σ1=4∧2≠5(SC × SC))
-
检索全部学生都选修的课程号和课程名
Π cno,cname (Πsno,cno(SC) ÷ Πsno(S) ∞ C)
-
检索选修课程号为K1和K5的学生学号
Π sno,cno (SC) ÷ Πcno( σcno=k1∨cno=k5(C) )
-
检索选修全部课程的学生姓名
Π sname ( (Π sno,cno (SC) ÷ Π cno(C)) ∞ S)
-
检索选修课程包含学号为 2 的学生所选修课程的学生学号
Π sno,cno(SC) ÷ Π cno (σsno=2(SC))
-
检索选修课程名为C语言的学生学号和姓名p
Πsno,sname(Πsno (SC∞(σcname=C语言(C))) ∞ S)
-
检索一没有一门课程成绩不及格的学生学号和姓名
Πsno,sname((Πsno(S) - Πsno(σgrade<60(SC)) ∞ S)
2.3 SQL编程
创建数据库代码如下
--使用T-SQL语句创建名为schooldb 数据库
--数据库主文件名为schooldb_data,初始大小为10MB,最大为50mb,增长速度为5%,
--日志文件名为schooldb_1og,初始大小为10MB ,最大为100mb,增长速度为5mb,
--所有文件都放在C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER2\MSSQL\DATA 这个文件目录下
create database schooldb
on(
name = schooldb_data,
filename = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER2\MSSQL\DATA\schooldb_data.mdf',
size = 10mb,
maxsize = 50mb,
filegrowth = 5)
log on
(
name = 'schooldb_1og',
filename= 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER2\MSSQL\DATA\schooldb_log.ldf',
size = 10mb,
maxsize = 1000mb,
filegrowth = 5mb
)
go
use schooldb
go
--根据下面三个表创建数据库
create table student
(sno char(8) primary key,
sname char(8) not null,
sex char(2) not null check(sex in ('男','女')),
sage int not null,
sdept char(8)
)
go
create table course
(cno char(8) primary key,
cname char(8) not null,
cpno char(8),
credit int,
)
go
create table sc
(sno char(8) foreign key references student(sno),
cno char(8) foreign key references course(cno),
grade int,
primary key(sno,cno)
)
go
利用上面的数据库,进行SQL编程
- 查询选修2门课以上(包括2门)学生学号和姓名
- 将‘CS’ 系全体学生的选课信息删除
- 创建视图 vsc(sno,sname,cno,canme,grade)。
- 以学生的名字创建索引ids,逆序。
- 删除上述建立的索引
- 创建存储过程proc1,通过学生姓名,可以查询此学生的全部科目的成绩。
- 向student表中添加约束,限定sex列的数据只能有"男"或”女“。
- 向student表中添加约束,使sage列的默认值为18。
- 给用户userdb授予查询学生表的权限。
- 收回用户userdb查询学生表的权限。
- 列出大于男生平均年龄的女生的学号,姓名,年龄,专业名,系名。
- 把表Student中学号为'001'的学生,现在想把其学号为‘001’修改为‘070101’。
- 查询平均分最高的学生学号及平均分。
-- 1. 查询选修2门课以上(包括2门)学生学号和姓名
select s.sno,s.sname
from student s, sc
where s.sno =sc.sno
group by s.sno,s.sname
having count(s.sno) >= 2
-- 2. 将‘CS’ 系全体学生的选课信息删除
delete from sc --这个from可以省略
from student s
where s.sno = sc.sno
and s.sdept = 'CS'
--3. 创建视图 vsc(sno,sname,cno,canme,grade)。
create view vsc(sno,sname,cno,cname,grade)
as
select s.sno, s.sname, c.cno, c.cname, sc.grade
from student s, course c, sc
where s.sno = sc.sno and c.cno = sc.cno
--4. 以学生的名字创建索引ids,逆序。
create index ids
on student(sname desc)
--5. 删除上述建立的索引
drop index student.ids
--6. 创建存储过程proc1,通过学生姓名,可以查询此学生的全部科目的成绩。
create procedure proc1
@sname char(10)
as
begin
select sname, cname, grade
from student s, course c, sc
where s.sno = sc.sno and c.cno = sc.cno
and sname = @sname
end
-- 使用方式
exec proc1 '李勇'
-- 7. 向student表中添加约束,限定sex列的数据只能有"男"或”女“。
alter table student
add constraint ch1 check(sex = '男' or sex ='女')
--不起约束名的形式
alter table student
add check(sex = '男' or sex ='女')
--8. 向student表中添加约束,使sage列的默认值为18。
alter table student
alter column sage
set default 18
--9. 给用户userdb授予查询学生表的权限。
grant select on object::student
to userdb
--10. 收回用户userdb查询学生表的权限。
revoke select on object::student
to userdb
--11. 列出大于男生平均年龄的女生的学号,姓名,年龄,系名。
select sno, sname, sage, sdept
from student
where ssex = '女'
and sage > (select avg(sage) from student where ssex = '男')
-- 12. 把表Student中学号为'001'的学生,现在想把其学号为‘001’修改为‘070101’。
update student
set sno = '710101'
where sno = '001'
-- 13. 查询平均分最高的学生学号及平均分。
select top 1 sno, avg(grade) as avgGrade
from sc
group by sno
order by avg(grade) desc
3.C语言编程题
3.1 平年闰年问题
输入某天的年月日,计算该天为当年的第几天
输入:
1998,9,25
输出:
9月25日是1998年的第268天
-
能被4整除却不能被100整除,或能被400整除的年份是闰年。
-
闰年的2月为29天,平年的2月为28天
代码:
/**
* 输入某天的年月日,计算该天为当年的第几天
* 输入:
* 1998,9,25
* 输出:
* 9月25日是1998年的第268天
* 闰年的额判断方法为:
* 能被4整除却不能被100整除,或能被400整除的年份是闰年。
* 闰年的2月为29天,平年的2月为28天
*/
#include <stdio.h>
int main() {
int year,month,day;
scanf("%d,%d,%d",&year, &month, &day);
int arr[12] = {31,-999,31,30,31,30,31,31,30,31,30,31}; //2月待定
//判断是否为闰年
if ((year%4 == 0 && year%100 != 0) || year%400 == 0) {
arr[1] = 29;
} else {
arr[1] = 28;
}
int answer = 0;
int i;
//如果求的是9月x号那么需要先累加1-8月每月固定的天数,
//在数组里,则是索引为0-7的元素,也就是0累加到month-2。
for (i = 0; i <= month - 2; i++) {
answer += arr[i];
}
answer += day;
printf("%d月%d日是%d年的第%d天\n",month,day,year,answer);
return 0;
}
3.2 自守数问题
自守数是指一个数的平方的尾数等于该数自身的自然数
例如:5^2 = 25, 25^2 = 625, 76^2 = 5776,9376^2 = 87909376
题目:编写一个程序输出10000以内的自守数。
/**
* 自守数是指一个数的平方的尾数等于该数自身的自然数
* 例如:5^2 = 25, 25^2 = 625,
* 76^2 = 5776,9376^2 = 87909376
* 编写一个程序输出10000以内的自守数
*/
#include <stdio.h>
int getDigit(int num) {
int i;
for (i = 1; i <= 6; i++) {
num = num / 10;
if (num < 1) {
break;
}
}
return i;
}
int getTen(int d) {
int i = 1;
int ten = 10;
while (i < d) {
ten = ten * 10;
i++;
}
return ten;
}
int main() {
int d; //自守数位数,比如9376^2 = 8790937 则i=4
int num; //原数
int sqNum; //平方后的数
int sqNumLast; //平方数的后d位数
for (num = 0; num <= 10000; num++) {
d = getDigit(num);
sqNum = num * num;
sqNumLast = sqNum % getTen(d); //如后有d位,则需余10^d。
if (num == sqNumLast) {
printf("%d ",num);
}
}
return 0;
}
0 1 5 6 25 76 376 625 9376
--------------------------------
Process exited after 0.0452 seconds with return value 0
请按任意键继续. . .
3.4 结构体编程题
有5个学生,每个学生有3门课成绩,要求实现如下3个功能,请给出程序的实现代码。
- 从键盘输入5个学生的数据,包括学号,姓名,3门课成绩
- 计算每门课的平均成绩和每个学生的平均成绩。
- 按每个学生的平均成绩由小到大进行排序。排序后按顺序输出学生姓名。
/*
有5个学生,每个学生有3门课成绩,要求实现如下3个功能,请给出程序的实现代码。
1. 从键盘输入5个学生的数据,包括学号,姓名,3门课成绩
2. 计算每门课的平均成绩和每个学生的平均成绩。
3. 按每个学生的平均成绩由小到大进行排序。排序后按顺序输出学生学号和姓名和平均成绩。
*/
#include <stdio.h>
typedef struct {
int sno;
char sname[20];
double grade[3];
} Student;
void avgCourse(Student stu[5], double avgCourseGrade[3]); //计算每个门课的平均成绩
void avgStudent(Student stu[5], double asg[5]); //计算每个学生的平均成绩
void sortStudentAsAvgGrade(Student stu[5], double asg[5]); //使每个学生按平均成绩从小到大排序
void swapStudent(Student *one, Student *two); //交换两个学生的全部信息,用于排序
void swapAvgGradeArr(double *one, double *two); //交换平均成绩数组中的两个值,用于排序
/**
* 描述:主函数
*
* @acg: 每门课程的平均成绩数组
* @asg:每个学生的平均成绩数组
* @stu:用来表示5个学生的数组
*/
int main() {
Student stu[5];
double acg[3];
double asg[5];
int i, j, k;
//功能1
for (i = 0; i < 5; i++) {
printf("请输入第%d为同学的信息:\n", i+1);
printf("学号:");
scanf("%d", &stu[i].sno);
printf("姓名:");
scanf("%s", stu[i].sname);
printf("成绩一:");
scanf("%lf", &stu[i].grade[0]);
printf("成绩二:");
scanf("%lf", &stu[i].grade[1]);
printf("成绩三:");
scanf("%lf", &stu[i].grade[2]);
}
//功能2
printf("\n每门课的平均成绩:\n");
//通过函数,使acg数组获取到每门课的平均成绩
avgCourse(stu, acg);
//循环输出
for (i = 0; i < 3; i++) {
printf("第%d门课的平均成绩为:%f\n",i, acg[i]);
}
printf("\n每位学生的平均成绩:\n");
//通过函数,使asg数组获取到每个学生的的平均成绩
avgStudent(stu, asg);
//循环输出
for (i = 0; i < 5; i++) {
printf("%s的平均成绩为:%f\n",stu[i].sname, asg[i]);
}
//功能3
printf("\n排序后按顺序输出学生学号和姓名和平均成绩。\n");
sortStudentAsAvgGrade(stu, asg);
for(i = 0; i < 5; i++) {
printf("%d %s %f \n", stu[i].sno, stu[i].sname, asg[i]);
}
}
/**
* 描述 : 计算每个门课的平均成绩
* 接收主函数的两个数组,一个stu,一个acg
* 三门课的成绩保存在 acg中
* 由于C语言的语法,函数参数为数组时为地址传递
* 可以改变数组中原先的值。
*
* 函数中有两个循环
* 最外层的for i 一共3次,每次算出一门课的平均成绩
* 内层的for j 一共5次,每次累加1位学生的第i门课的成绩,
* for j 的5次循环则可以累加出5位学生的第i门课的成绩
*/
void avgCourse(Student stu[5], double acg[3]) {
int i, j;
double sum;
for (i = 0; i < 3; i++) {
sum = 0;
for (j = 0; j < 5; j++) {
sum += stu[j].grade[i];
}
acg[i] = sum / 5;
}
}
/**
* 描述 : 计算每个学生的平均成绩
*
* for i 一共5次,每次循环计算1位学生的平均分
* 首先sum累加第i位同学的总成绩,再除以3。
* 得到的平均分保存在数组 asg 中
* C语言函数参数为数组时进行地址传递,所以也改变主函数中asg数组的值。
*/
void avgStudent(Student stu[5], double asg[5] ) {
int i;
double sum;
for (i = 0; i < 5; i++) {
sum = 0;
sum += stu[i].grade[0];
sum += stu[i].grade[1];
sum += stu[i].grade[2];
asg[i] = sum / 3;
}
}
/**
* 描述 : 使每个学生按平均成绩从小到大排序
*
* 首先,stu的5个学生和asg的5个平均成绩是一一对应的。
* 也就是说,stu[1]这位同学的平均成绩是asg[1],sty[2]的平均成绩是asg[2]
*
* 所以,我们只需要对asg数组进行从小到大排序,
* 排序时,asg数组中的每个元素发生交换的同事,stu数组的也跟着发生交换。
* 具体的排序算法使用的是冒泡排序,排序方案另学
*/
void sortStudentAsAvgGrade(Student stu[5], double asg[5]){
int i, j;
for (i = 0; i < 5; i++) {
for (j = 0; j < 4; j++) {
if (asg[j] > asg[j+1]) {
swapAvgGradeArr(&asg[j], &asg[j+1]);
swapStudent(&stu[j], &stu[j+1]);
}
}
}
}
/**
* 描述 :用于排序中的交换两个浮点数
*
* 由于要改变原值,所以必须要地址传递,则需要用指针来接收参数
*/
void swapAvgGradeArr(double *one, double *two) {
double temp = *one;
*one = *two;
*two = temp;
}
/**
* 描述 :用于排序中的交换两个stu
*/
void swapStudent(Student *one, Student *two) {
Student temp = *one;
*one = *two;
*two = temp;
}
程序运行结构
请输入第1为同学的信息:
学号:1001
姓名:白大
成绩一:100
成绩二:91
成绩三:98
请输入第2为同学的信息:
学号:1002
姓名:刘二
成绩一:90
成绩二:91
成绩三:92
请输入第3为同学的信息:
学号:1003
姓名:张三
成绩一:80
成绩二:85
成绩三:88
请输入第4为同学的信息:
学号:1004
姓名:李四
成绩一:70
成绩二:77
成绩三:78
请输入第5为同学的信息:
学号:1005
姓名:王五
成绩一:60
成绩二:66
成绩三:61
每门课的平均成绩:
第0门课的平均成绩为:80.000000
第1门课的平均成绩为:82.000000
第2门课的平均成绩为:83.400000
每位学生的平均成绩:
白大的平均成绩为:96.333333
刘二的平均成绩为:91.000000
张三的平均成绩为:84.333333
李四的平均成绩为:75.000000
王五的平均成绩为:62.333333
排序后按顺序输出学生学号和姓名和平均成绩。
1005 王五 62.333333
1004 李四 75.000000
1003 张三 84.333333
1002 刘二 91.000000
1001 白大 96.333333
--------------------------------
Process exited after 87.18 seconds with return value 21
请按任意键继续. . .