软件设计师-案例分析题

案例分析专题

image-20240717202811856

题型分析

软件设计师的下午题目已经固定了,每年都是这么考,从未有其他变化,所以对大家来说是十分有利的,毕竟再难的东西只要有了套路都能攻克,就看大家的方法和努力了

试题一是结构化分析设计,固定考察数据流图,比较简单,但是需要耐心,可以拿12分以上。

试题二是数据库分析设计,固定考察ER图和关系模式,比较简单,可以拿12分以上。

试题三是面向对象分析设计,固定考察UML关系和图,比较简单,可以拿12分以上。

试题四是算法分析设计,固定考察C语言代码和算法分析,比较难,可以拿7分以上

试题五是面向对象程序设计,固定考察C++或JAVA语法,建议选做 JAVA,只考基本语法,比较 简单,可以拿 12 分以上。

大家后面做真题的时候可以按照文老师上面写的来严格要求自己。需要特别注意的是:试题一二三这三题,本质上是考阅读理解,虽然简单,但是复杂,因为题目描述和图都很多,需要十分耐心去一一核对,因为软考官方不公布正确答案,这些试题答案可能会和学员做的有些许出入,这是正常的,可以联系助教进行核对。下午试题具体类型归纳如下:

image-20240717202939272

考点及解题技巧⭐

数据流图

本章节固定对应下午试题一,每年固定考察数据流图。

数据流图的设计原则

(1)数据守恒原则:对任何一个加工来说,其所有输出数据流中的数据必须能从该加工的输入数据流中直接获得,或者说是通过该加工能产生的数据。

(2)守恒加工原则:对同一个加工来说,输入与输出的名字必须不相同,即使它们的组成成分相同

(3)对于每个加工,必须既有输入数据流,又有输出数据流。

(4)外部实体与外部实体之间不存在数据流

(5)外部实体与数据存储之间不存在数据流

(6)数据存储与数据存储之间不存在数据流

(7)父图与子图的平衡原则:子图的输入输出数据流同父图相应加工的输入输出数据流必须一致,此即父图与子图的平衡。父图与子图之间的平衡原则不存在于单张图。

数据流图描述数据在系统中如何被传送或变换,以及如何对数据流进行变换的功能或子功能,用于对功能建模。

数据流:由一组固定成分的数据组成,表示数据的流向。在DFD 中,数据流的流向必须经过加工

加工:描述了输入数据流到输出数据流之间的变换,数据流图中常见的三种错误如图所示

加工3.1.2 有输入但是没有输出,称之为“黑洞

加工3.1.3 有输出但没有输入。称之为“奇迹”

加工3.1.1 中输入不足以产生输出,我们称之为“灰洞”

数据存储:用来存储数据

外部实体(外部主体):是指存在于软件系统之外的人员或组织,它指出系统所需数据的发源地(源)和系统所产生的数据的归宿地(宿)。

image-20250416094429558

image-20250416094533550

解题技巧

数据流图的考试形式非常固定,第一小题补充外部实体,第二小题补充数据存储,第三小题补充缺失数据流,第四小题考察简单概念。都不算难,以题目描述和数据流图为主,答案都在题目描述里,更像是阅读理解题,技巧如下:

1、补充外部实体:外部实体就是与系统进行交互的其他实体,可以是大型系统、公司部门、相关人员等,外部实体会与系统进行交互,反应在数据流图中就是一个个事件流,依据事件的名称结合题目描述可以轻易得出答案。

2、补充数据存储:数据存储出现在0层数据流图中,反应系统内部数据的存储,可以直接根据数据流图中数据存储的输入数据流和输出数据流判断该数据存储的信息得出答案,但注意要使用题目说明的数据存储名词作为答案。

3、补充缺失数据流:详细阅读题目描述,依据题目描述对涉及的数据流图进行一一核对,这是最为简单直接的方法,数据流与加工有关,且必须经过加工P,数据流的起点或终点必定有一个是加工

4、简单概念:题型不固定,一般只有2-3分,都是比较简单的判断。重点在于审题、审图,根据两个数据平衡原则。万变不离其宗。

常见问题

Q:补充数据存储时,题目中没有具体存储名称怎么办?

A:此时可依据数据流图中数据存储的输入输出数据流自行起名

Q:补充数据流时,该写多少条? A:一般按分写,几分就写几条。

Q:觉得要补充的数据流很多,比分数更多怎么办? A:可以多写,这个是按点给分的,多写不会扣分,但要注意不能太过分。

Q:总觉得数据流把握不准,跟答案有出入怎么办? A:首先要注意,软考官方不公布标准答案,所有答案都是老师校对的,可能会不全面:其次,部分真题本身也不太严谨,有二义性。因此不用太纠结,掌握解题方法,多刷题即可。

Q:这种题目该怎么学习,学习到哪种程度呢? A:要求能拿到12分以上;看完视频对应专题课程后,立即去做后面的历年真题。

数据库分析设计

本章节固定对应下午试题二,每年固定考察 E-R图和关系模式E-R 图转换为关系模式。

E-R图中,有实体和联系两个概念,实体和实体之间的联系分为三种,即1:1,1:N,M:N,这三种情况,转换为关系模式的方法也不同。

首先,每个实体都要转换为一个关系模式,对于联系,一对一,联系作为一个属性随便加入哪个实体中:一对多,联系可以单独转换为一个关系模式,也可以作为一个属性加入到N端中(N端实体包含1端的主键):多对多,联系必须单独转换为一个关系模式(且此关系模式应该包含两端实体的主键)。 转换之后要注意:原来的两个实体之间的联系必须还存在,能够通过查询方式查到对方在实际解题时,要注意,某个实体的属性,还应该包括其联系属性,具体问题具体分析。两个以上实体型的联系:

image-20250313163316435

解题技巧

数据库设计的考法也非常固定,第一小题补充 E-R图,第二小题补充关系模式,第三小题是简单的情景问答题。同样也都不难,结合题目描述和E-R图的一些特点可以轻易得出答案,技巧如下:

1、补充 E-R图:这是重中之重,E-R图如果弄错了,后续题目都有影响,主要是根据题目描述确认哪些实体之间有联系,联系类型是哪一种,而后进行连线即可,并不难。

2、补充关系模式:实际考察的是将 E-R图转换为关系模式,补充缺失的属性,分成两步:首先需要审题,题目会给出每个关系模式的属性信息,先将题目中的属性信息和问题对应,将缺少的属性全部补充;而后再按照规则转换,即前面所说的规则,按联系的三种对应方式决定要添加哪些字段。

3、情景问答:一般都是给出一段新的描述,要求新增一种实体-联系类型和关系模式,本质也是 考察联系类型和 E-R图转换为关系模式。

注意审题,常识以及E-R图转换为关系模式的原则(主要是联系的归属)。

常见问题

Q:E-R 图转换为关系模式时,总觉得不对怎么办? A:学员在这种类型题目里唯一的模糊点就是这里,转换为关系模式,遵循两步法,首先以题目描述为主,然后再根据不同类型的转换原则去判断是否有遗漏。

Q:这种题目该怎么学习,学习到哪种程度呢? A:要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧

面向对象分析设计

本章节固定对应下午试题三,每年固定考察 UML建模里的关系和图

用例图

image-20250313163355010

主要考察参与者和用例的识别、用例之间的关系(包含include、扩展extend、泛化),如上图所示,登记外借信息用例包含用户登录用例,因为每次如果要登记外借信息,必然要先进行用户登录。而查询书籍信息的扩展是修改书籍信息,是因为每次查询书籍信息后,发现有错误才会修改,否则不修改,不是必要的操作。因此,区分用例间的关系是包含还是扩展,关键在于是不是必须操作。

类图

image-20250313163423218

主要考察填类名、多重度、类之间的联系(泛化、组合、聚合、实现、依赖)多重度(有点类似于E-R图中的联系类型),含义如下:

1:表示一个集合中的一个对象对应另一个集合中1个对象。

0..*:表示一个集合中的一个对象对应另一个集合中的0个或多个对象。

1..*:表示一个集合中的一个对象对应另一个集合中的一个或多个对象。

*:表示一个集合中的一个对象对应另一个集合中的多个对象。

类之间的联系如下:理解聚合和组合都是部分和整体之间的关系,类之间大多考察这两种关系,必须记住其符号,且菱形一端为整体,表示其由另外的一端实体组成,可依据题意找出组成元素解题。

image-20250313163448880

依赖关系最弱,只要有部分相关就是依赖。泛化关系是父子关系;组合和聚合都是部分-整体关系,组合更强。

序列图

image-20250313163517590

序列图也即顺序图,如上图所示为顺序图,主要考察填对象名、消息名,消息就是一个个箭头上传递的,对象作为实体在最上端,自上而下为时间顺序,反应一个事件的执行过程。

活动图

image-20250313163548628

活动图类似于程序流程图,粗线表示该活动分成了多少个并行的任务,最后又会汇总到一起。主要考察填活动名称。

状态图

image-20250313163611544

主要描述状态之间的转换,主要考察的就是填状态名、填状态转换的条件,具体如上图所示。

通信(协作)图

image-20250313163636723

是顺序图的另一种表示方法,也是由对象和消息组成的图,只不过不强调时间顺序,只强调事件之间的通信,而且也没有固定的画法规则,和顺序图统称为交互图。主要考察填对象名、填消息。

解题技巧

由前面的介绍可知,考察 UL 建模就是考察多种图形,对这些图形的考察一般都是缺失一些关键点,而后要求考生补图。要求认真审题,根据题干说明补齐类名或者对象名或者消息名等等,记住类图和对象图中的多重度(互相独立的分析,掌握表示方法)、类之间的联系标识(多边形端为整体,直线端为个体)。认真审题,审图,根据说明查缺补漏,一般来说有以下几种题型: 1、补充用例图:主要考察补充用例名称、参与者、用例之间的关系,只要认真审题,根据题中描述核对,都可以轻易得出答案。 2、补充类图:主要考察补充类名称,需要根据类之间的关系以及多重度来判断,需要牢记类之间关系的图形符号,尤其是组合、聚合和继承的符号,并且观察符号上的多重度数字,与题目描述对应。 3、补充状态图:主要补充状态名称,根据题目描述可以轻易得出答案, 4、识别设计模式,掌握经典设计模式特点,并结合英文等联想。 常见问题: Q:看到一张类图都是空的,就懵了,该怎么办?

A:类和类之间的联系,尤其是泛化联系是非常重要的,也是解题的关键,要记住泛化联系的符号,而后去题目描述里找到具有父子关系的实体,基本上题目就一步步解出来了。其他如组合、聚合联系的符号也是解题关键。 Q:这种题目该怎么学习,学习到哪种程度呢? A:要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。

算法分析设计

本章节固定对应下午试题四,每年固定考察C语言代码及算法分析时间复杂度、算法判断见本专题视频讲解。

C语言入门实例

让我们看一段简单的代码,可以输出单词"Hello World":

#include<stdio.h>
int main() {
    /*我的第一个℃ 程序*/
    printf("Hello, World! \n"):
    return ;
}

程序的第一行 #include<stdio.h>是预处理器指令,告诉C编译器在实际编译之前要包含stdio.h 文件。 下一行 int main()是主函数,程序从这里开始执行,c语言程序都是从 main 函数开始执行 下一行 /*..*/将会被编译器忽略,这里放置程序的注释内容。它们被称为程序的注释。 下一行 printf(..)是c中另一个可用的函数,会在屏幕上显示消息 "Hello, World!"。 下一行 return0;终止 main()函数,并返回值 0。 英文分号; 分号是语句结束符。也就是说,每个语句必须以分号结束。它表明一个逻辑实体的结束。

注释

C语言有两种注释方式:

以 //开始的单行注释,这种注释可以单独占一行。

/**/这种格式的注释可以单行或多行。

不能在注释内嵌套注释,注释也不能出现在字符串或字符值中。

标识符

C标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。一个标识符以字母A-或a-z或下划线开始,不能以数字开始,后跟零个或多个字母、下划线和数字(0-9)。

C标识符内不允许出现标点字符,比如 @、$和 %。

C 是区分大小写的编程语言。

保留字

C语言自己保留的关键字,编写程序时不能与之重复,如变量定义int/char/double 等保留字。

C中的空格

只包含空格的行,被称为空白行,可能带有注释,C编译器会完全忽略它。 在C中,空格用于描述空白符、制表符、换行符和注释。空格分隔语句的各个部分,让编译器能识别语句中的某个元素(比如int)在哪里结束,下一个元素在哪里开始。因此,在下面的语句中: int age;在这里,int和age之间必须至少有一个空格字符(通常是一个空白符),这样编译器才能够区分它们。另一方面,在下面的语句中: fruit=apples+oranges;//获取水果的总数fruit 和=,或者=和 apples 之间的空格字符不是必需的,但是为了增强可读性,可以根据需要适当增加一些空格。

sizeof 获取存储字节:为了得到某个类型或某个变量在特定平台上的准确大小,可以使用sizeof运算符。表达式sizeof(type)得到对象或类型的存储字节大小。

void 类型

void 类型指定没有可用的值。它通常用于以下三种情况下:

image-20250313163941831

变量

变量只不过是程序可操作的存储区的名称。C中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为C是大小写敏感的

变量定义:指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示:type variable list; 在这里,type 必须是一个有效的C数据类型,可以是char、w char、int、float、double 或任何用户自定义的对象,variable_list可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明: int i,j,k; 变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示: type variable name = value; 下面列举几个实例: int d=3,f=5; char x='x';

C数组

定义一维数组:type arrayName[arraySize]

C枚举

枚举语法定义格式为:

enum 枚举名 {枚举元素1,枚举元素 2,……};

枚举元素1默认为0,可以赋其他值;

枚举元素的值默认在前一个元素基础上加1;定义枚举变量:

enum DAY{MON=1,TUE,WED,THU,FRI,SAT,SUN}

C中的左值(Lvalues)和右值(Rvalues)

C中有两种类型的表达式: 左值(value):指向内存位置的表达式被称为左值(Ivalue)表达式。左值可以出现在赋值号的左边或右边。 右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。变量是左值,因此可以出现在赋值号的左边。数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边。 下面这个不是一个有效的语句,会生成编译时错误: 10= 20;

c常量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x或0x表示十六进制,0表示八进制,不带前缀则默认表示十进制。浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量,如:

3.14159 /*合法的 */ 314159E-5 /*合法的*/ 字符常量是括在单引号中,可以是一个普通的字符(例如')、一个转义序列(例如't'),或一个通用的字符(例如“u02CO")。在中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(t)等。字符串字面值或常量是括在双引号""中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。

宏定义#define 用来定义一个可以代替值的宏,语法格式如下:#define 宏名称 值实例

后续使用可用 LENGTH 代替 10 这个常量#define LENGTH 10

const 关键字定义一个只读的变量,本质是修改了变量的存储方式为只读。const intLENGTH =10; //定义变量 LENGTH=10,且只读,即无法修改 LENGTH 值。static 关键字 static 关键字指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用static修饰局部变量可以在函数调用之间保持局部变量的值。 static修饰符也可以应用于全局变量或函数。当 static修饰全局变量或函数时,会使变量或函数的作用域限制在声明它的文件内。

extern 关键字

extern 关键字用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候

typedef 关键字

C语言提供了 typedef关键字,您可以使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语BYTE typedef unsigned char BYTE: 在这个类型定义之后,标识符BYTE可作为类型unsignedchar 的缩写,例如: BYTE b1,b2: 您也可以使用 typedef 来为用户自定义的数据类型取一个新的名字。

算术运算符

下表显示了C语言支持的所有算术运算符。假设变量A的值为10,变量B的为20,则:

image-20250313164054616

关系运算符

下表显示了C语言支持的所有关系运算符。假设变量A的值为10,变量B的值为20,则:

image-20250313164121956

image-20250313164141834

逻辑运算符

下表显示了C语言支持的所有关系逻辑运算符。假设变量A的值为1,变量B的值为0,则:

image-20250313164211013

赋值运算符下表列出了C语言支持的赋值运算符

image-20250313164238752

image-20250313164250344

杂项运算符→sizeof& 三元 下表列出了℃语言支持的其他一些重要的运算符,包括sizeof和?:。

image-20250313164347319

C判断

判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。C语言把任何非零和非空的值假定为true,把零或nu假定为false。

判断语句格式:

(1)if语句
if(boolean expression) {
    /*如果布尔表达式为真将执行的语句*/
}
​
(2)ifelse语句(扩展if elseif else)
if(boolean expression) {
    /*如果布尔表达式为真将执行的语句 */
} else {
    /*如果布尔表达式为假将执行的语句 */
}
(3)switch case 语句
switch(expression) {
case constant-expression:
    statement(s):break;/*可选的*/
case constant-expression:
    statement(s):
    break;/*可选的*/
    /*您可以有任意数量的 case 语句 */
default:/* 可选的 */
    statement(s):
}

C循环

循环语句允许我们多次执行一个语句或语句组,C语言提供了以下几种循环类型:

(1)while 语句
while(condition) {
    statement(s):
}
(2)for 语句
for (init:condition:increment) {
    statement(s):
}
(3)do while 语句(至少保证执行一次循环体)
do {
    statement(s):
}
}while(condition);

循环控制语句

(1)break语句

C语言中break 语有以下两种用法: 当break语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下条语句。 它可用于终止 switch 语句中的一个 case。 如果使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。

(2)continue 语句C语言中的continue 语会跳过当前循环中的代码,强迫开始下一次循环。对于 for 循环,continue 语句执行后自增语句仍然会执行。对于while 和 do..while 循环,continue 语句重新执行条件判断语句。 (3)goto 语句(不建议使用) C语言中的goto 语句允许把控制无条件转移到同一函数内的被标记的语句

C函数

C语言中的函数定义的一般形式如下: return type function name( parameter list ) body of the function 在C语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:返回类型:一个函数可以返回一个值。returntype是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,returntype 是关键字 void。 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名

参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。函数主体:函数主体包含一组定义函数执行任务的语句。以下是 max()函数的源代码。该函数有两个参数num1和num2,会返回这两个数中较大的那个数:

/*函数返回两个数中较大的那个数*/
int max(int numl,int num) {
    /* 局部变量声明 */
    int result;
    if(numl>num) {
        result = num1;
    } else {
        result = num2;
    }
    return result;
}

函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。函数声明包括以下几个部分: return type function name( parameter list );针对上面定义的函数 max(),以下是函数声明:int max(int numl, int num2), 在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:int max(int, int); 调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:ret = max(a, b);

C作用域

局部变量:在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部 的语句使用。局部变量在函数外部是不可知的。全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。在程序中,局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值,全局变量不会被使用。

形式参数:函数的参数,形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。int test(int,int);// 形参,只声明test(5,3);// 实参,已赋值C指针每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为: type *var-name;在这里,type 是指针的基类型,它必须是一个有效的c数据类型,var-name 是指针变量的名称。用来声明指针的星号*与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明: int *ip;/*一个整型的指针 */ 使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符*来返回位于操作数所指定地址的变量的值。

include<stdio.h>

int main() {
    int var =20;/*实际变量的声明 */
    int *ip; /*指针变量的声明 */
	ip =&var;/*在指针变量中存储 var 的地址 */
    printf("Address of var variable: %pn", &var);
	/*在指针变量中存储的地址*/
	printf("Address stored in ip variable: %p\n", ip);/*使用指针访问值 */
	printf("Value of *ip variable: %d\n", *ip);
	return 0;
}

函数指针

函数指针是指向函数的指针变量。通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。函数指针可以像一般函数一样,用于调用函数、传递参数。函数指针变量的声明: typedef int(*fun ptr)(int,int);//声明一个指向同样参数、返回值的函数指针类型 C内存管理 定义一个指针,必须使其指向某个存在的内存空间的地址,才能使用,否则使用野指针会造成段错误,内存分配与释放函数如下: void free(void *addr); //该函数释放addr所指向的内存块,释放的是动态分配的内存空间。 void *malloc(int size);//在堆区分配一块制定大小为size的内存空间,用来存放数据,不会被初始化。

member-list 是标准的变量定义,比如inti;或者floatf,或者其他有效的变量定义。variable-ist 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变 在一般情况下,tag、member-list、variable-list这3部分至少要出现 2个。以下为实例://此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c//同时又声明了结构体变量s1 //这个结构体并没有标明其标签

struct {
	int a;
	char b;
	double c;
}sl;

//此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c//结构体的标签被命名为SIMPLE,没有声明变量 struct SIMPLE 老师软件设计师 int a; char b; double c; //用SIMPLE标签的结构体,另外声明了变量t1、t2、t3 struct SIMPLE tl,t2[20],*t3; //也可以用typedef创建新类型

typedef struct
    int a;
    char b;
    double c;
}Simple2;

//现在可以用Simple2作为类型声明新的结构体变量

image-20250313164624506

默认处理的是 text 文件,如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式(加字母 b):"rb","wb","ab","rb+","r+b","wb+","w+b","ab+","a+b"关闭文件 为了关闭文件,请使用 fclose()函数。函数的原型如下: int fclose( FILE *fp ); 如果成功关闭文件,fclose()函数返回零,如果关闭文件时发生错误,函数返回EOF。文件的读写操作 getc 从文件中读取一个字符 fputc 写一个字符到文件中去 fgets 从文件中读取一个字符串 fputs 写一个字符串到文件中去 fread 以二进制形式读取文件中的数据 fwrite 以二进制形式写数据到文件中去

文件定位函数

fseek 随机定位

文件结束函数

feof()函数用于检测文件当前读写位置是否处于文件尾部。只有当当前位置不在文件尾部时,才能从文件读数据。函数定义:int feof(FILE*fp)返回值:0或非0 feof()是检测流上的文件结束符的函数,如果文件结束,则返回非0值,没结束则返回0。

文件检错函数

文件操作的每个函数在执行中都有可能出错,c语言提供了相应的标准函数 ferror 用于检测文件操作是否出现错误。

函数定义:int ferror (FlLE*fp)
返回值:0或非0
Ferror 函数检査上次对文件fp所进行的操作是否成功,如果成功则返回0;出错返回非0。因此,应该及时调用 ferror 函数检测操作执行的情况,以免丢失信息。
C语言里的字符串操作函数都定义在头文件string.h中。下面是头文件 string.h 中定义的函数,掌握以下常用的函数:void *memcpy(void *dest,const void *src,size tn):从 src 复制 n 个字符到 dest。void *memset(void *str,intc,sizetn):复制字符c(一个无符号字符)到参数 str 所指向的字符串的前n个字符。
char *strcat(char *dest,const char *src):把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
char *strncat(char *dest,const char *src,size_tn):把 src 所指向的字符串追加到 dest所指向的字符串的结尾,直到n字符长度为止。
char *strchr(const char *str,int c):在参数 str 所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。
int strcmp(const char *strl,const char *str2):把strl 所指向的字符串和 str2 所指向的字符串进行比较。
int strncmp(const char *strl,const char *str2, size tn):把strl 和 str2 进行比较,
最多比较前n个字节。char *strcpy(char *dest,const char *src):把 src 所指向的字符串复制到 dest。char *strncpy(char *dest,const char *src,size_tn):把 src 所指向的字符串复制到 dest,最多复制n个字符。
sizet strlen(const char *str):计算字符串 str 的长度,直到空结束字符,但不包括空结
束字符。char *strrchr(const char *str,int c):在参数 str 所指向的字符串中搜索最后一次出现字符c(一个无符号字符)的位置。
char *strstr(const char *haystack,const char *needle):在字符串 haystack 中查找第次出现字符串 needle(不包含空结束字符)的位置。

解题技巧

算法设计是下午软件设计中最难的题型,主要难在C代码填空上,因此文老师的建议是先不解决代码填空题(因为最难),先解决其他外围问题(如时间复杂度、算法技巧、取特殊值计算结果),最后解决代码填空,有助于理解整个题目,技巧如下:

1、代码填空:第一小题,最后解决,并不影响解决其他题目,要理解题目算法原理,才能得出答案。另外近几年的算法设计真题有很大的技巧,即便不理解算法原理也可以推导出答案,要结合算法描述中的公式,以及算法代码中类似的分支,能够发现填空的答案在代码中其中地方已经给出,因为算法原理的相似可以通用,尤其是分治法算法。详见文老师真题详解,详述技巧。要注意的是,当遇到有最小值或最大值参与比较时,若比较出来比最小值更小,接下来肯定要更新这个最小值以及其下标元素值。当遇到一些条件判断的填空时,要注意对应上下文查看哪些变量是作为控制的。

2、算法、时间复杂度:第二小题,先做,考察何种算法很好分辨,涉及到分组就是分治法,局部最优就是贪心法,整体规划最优就是动态规划法,迷宫类的问题是回溯法,记住关键字很好区分;时间复杂度就是看C代码中的 for 循环层数和每一层的循环次数,涉及到二分必然有0(logn)。3、特殊值计算:第三小题,一般应该先做,不需要根据C代码,直接根据题目给出的算法原理,一步步推导即可得出答案,耐心推导并不难。但要注意,如果遇到算法原理十分复杂的,建议放弃,掌握问题1和2的技巧即可。

常见问题

Q:文老师说这一题最难,我也没基础,能不能干脆放弃?

A:这种思想是错误的,这一题共15分,放弃就难通过了,要尽可能的拿分,至少关于时间复杂度、算法判断是很简单的:而算法填空,平时做练习也要认真对待每一题,坚持下来,时间长了即使零基础也能填对几个。

Q:完全没有C语言代码基础,看不懂怎么办?

A:文老师在讲解真题和技巧时已经充分考虑到这一点,对于零基础学员,先认真听语法讲解然后听真题里对代码的分析,从英语的角度去联想其含义。不放弃就有收获。Q:算法判断不准确,不能辨别贪心法和动态规划法怎么办?

A:算法判断是很简单的了,题目中都有关键词暗示的,分而治之是分治法;迷宫问题回溯法;当题目中给出“考虑当前情况下”等词,是局部最优;当题目给出“最优子结构”、递归、最优公式等,是动态规划法。

Q:时间复杂度不知道如何求?

A:看代码循环重数,注意是嵌套的重数,不是个数。

Q:这种题目该怎么学习,学习到哪种程度呢?

A:要求能拿到8分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。

面向对象程序设计

本章节固定对应下午试题五/六,选做1题即可,每年固定考察JAVA 和 C++程序设计。建议都选JAVA题,C++语法不再做介绍。

public class Dog {
    String breed;
	int age;
	String color;
	void barking(){}
	void hungry(){}
	void sleeping(){}
}

一个类可以包含变量和方法。每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。下面是一个构造方法示例:

public class Puppy{
    public Puppy(){}
	public Puppy(string name){
        //这个构造器仅有一个参数:name
    }
}

创建对象

对象是根据类创建的。在Java中,使用关键字new 来创建一个新的对象。创建对象需要以下三步:声明:声明一个对象,包括对象名称和对象类型。实例化:使用关键字new来创建一个对象。初始化:使用new创建对象时,会调用构造方法初始化对象。

public class Puppy {
    public Puppy(String name) {
        //这个构造器仅有一个参数:name
		System.out.println("小狗的名字是" + name);
    }
	public static void main(string[] args){
        //下面的语句将创建一个Puppy对象:
		Puppy myPuppy=new Puppy("tommy");
    }
}
运行后会输出:小狗的名字是:tommy

访问实例变量和方法

public class Puppy{
    int puppyAge;
    public Puppy(String name) {
        //这个构造器仅有一个参数:name
        System.out.println("小狗的名字是:"+ name );
    }
    public void setAge( int age ){
        puppyAge = age;
    }
    public int getAge(){
        System.out.println("小狗的年龄为:"+ puppyAge );
        return puppyAge;
    }
    public static void main(String args){
        /*创建对象*/
        Puppy myPuppy=new Puppy("tommy");
        /*通过方法来设定 age */
        myPuppy.setAge(2);
        /*调用另一个方法获取 age */
        myPuppy.getAge();
        /*你也可以像下面这样访问成员变量*/
        System.out.println("变量值:"+ myPuppy.puppyAge );
    }
}
编译并运行上面的程序,产生如下结果:
小狗的名字是:tommy
小狗的年龄为:2
变量值:2

访问控制修饰符

Java 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持以下访问权限。

private :在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)

public :对所有类可见。使用对象:类、接口、变量、方法

protected:对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)。

请注意以下方法继承的规则:父类中声明为public的方法在子类中也必须为public。

父类中声明为protected的方法在子类中要么声明为protected,要么声明为public,不能声明为 private. 父类中声明为private的方法,不能够被继承。

abstract 修饰符:抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。个类不能同时被 abstract和final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法。

abstract class Caravan {
    private double price;
    private String model;
	private String year;
	public abstract void goFast();//抽象方法
    public abstract void changecolor();
}

抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。 抽象方法不能被声明成final和 static。 任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。 如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。 抽象方法的声明以分号结尾,例如:publicabstractsample();。

public abstract class SuperClass {
   abstract void m();//抽象方法 
}
class Subclass extends Superclass {
    //实现抽象方法
	void m(){
        xxx
    }
}

java 继承的特性

子类拥有父类非 private 的属性、方法。

子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

子类可以用自己的方式实现父类的方法。Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是Java继承区别于C++继承的一个特性。提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

继承可以使用extends和implements这两个关键字来实现继承extends 关键字。在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以extends 只能继承一个类。

public class Animal {
    private String name;
    private int id;
    public Animal(string myName,string myid){//初始化属性值
    }
	public void eat(){ 
        //吃东西方法的具体实现
    }
    public void sleep(){ 
        //睡觉方法的具体实现
    }
}
public class Penguin extends Animal {}

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

public interface A {
    public void eat();
    public void sleep();
}
public interface B {
    public void show();
}
public class C implements A,B{
}

了解这些基本语法即可,其他语句和C语言类似。

解题技巧

下午考试的第 5,6题为二选一作答,都是程序填空,原理一模一样,只不过一个用 C++语言,一个用JAVA 语言编写的程序,并且这个填空只是考基本语法,基本不涉及算法,比之第4题算法设计的填空简单很多,完全可以拿满分。

文老师建议,如果是初学者,或者对于两种语言都不太精通,就专攻JAVA 程序题,因为JAVA的语法比之C++要简单并且容易理解记忆,容易拿到满分。

面向对象的程序填空分为两类,一个是考察纯定义,如接口类,抽象类,接口类中的函数定义等,这些根据程序代码可以快速判断出。

另一类,就是关于设计的,填写函数体,但是这个函数体并不是要写一段真正的程序实现代码,而是调用形式的,如上面的例题,都有调用函数的,这些调用函数一般在程序中,或者在说明和类图中可以找到,考察的是调用形式。

注意以下几点: 1、定义了类的对象后,必须先初始化(使用 new 关键字);

2、接口(interface)和抽象类(abstract class)(子类继承关键字不同,为 implements 和extends)

3、抽象类中可以有普通的方法(有函数体),也可以有抽象方法(无函数体,方法前要加关键字abstract),而接口中的方法都是默认为抽象方法(因为默认,无需再加任何关键字标识);4、this的使用,指代当前对象,一般有两个重名变量的赋值时会使用到,如在构造函数中,参数名和私有变量名相同都为name,就要使用this.name=name;

4、this 的使用,指代当前对象,一般有两个重名变量的赋值时会使用到,如在构造函数中,参数名和私有变量名相同都为name,就要使用this.name-name;

5、题目所给的类图很重要,从中可以查看类之间的关系以及类中的方法。

JAVA 题总结

1、抽象类、接口相关,继承、实现关键字,抽象类中有抽象方法和普通方法,抽象方法加 abstract,接口中方法都是抽象方法,因此反而不需要加abstract。

2、类的成员变量、类的方法中参数很重要,若参数是类的对象,则一般会在实现中使用此对象调用类的方法;另外赋值中要注意this的使用,当参数名和变量名相同时使用this。

3、结合代码的上下文,明确类之间的关系,结合方法实现的功能,方法中的参数,以及类的成员变量,去解决问题。

记住:JAVA 填空都不难,只是考简单的语法问题,或者类之间的关联,方法的调用,不涉及算法原理。

常见问题

Q:零基础完全不懂 JAVA 语言怎么办?

A:这一题完全可以从英语角度去理解,根据关键词去搜索代码上下文,都能得出答案,毫无难度,每个人都能拿满分,要先树立信心。

Q:视频里为什么没有对于JAVA语言的详细讲解?

A:语言之间都是相通的,结合文老师前面对C语言的讲解,学员再去分析C语言或者 JAVA语言,其关键语法都是类似的,这个考试又不需要大家去关注细节,因此完全够用了。如果想了解具体 JAVA语法可在百度搜索“java 教程”,找一个简短的页面整体浏览一遍即可,没有必要去看相关java 代码视频。关键还在于多做真题,多听视频讲解,自己多总结。

Q:这种题目该怎么学习,学习到哪种程度呢?

A:要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。

结构化分析设计考点串讲

数据流图描述数据在系统中如何被传送或变换,以及如何对数据流进行变换的功能或子功能,用于对功能建模。 1)数据流:由一组固定成分的数据组成,表示数据的流向在DFD 中,数据流的流向必须经过加工。 2)加工:描述了输入数据流到输出数据流之间的变换,数据流图中常见的三种错误如图所示加工3.1.2 有输入但是没有输出,称之为“黑洞加工3.1.3 有输出但没有输入。称之为“奇迹“加工3.1.1 中输入不足以产生输出,我们称之为“灰洞” 3)数据存储:用来存储数据。 4)外部实体(外部主体):是指存在于软件系统之外的人员或组织,它指出系统所需数据的发源地(源)和系统所产生的数据的归宿地(宿)

image-20240717203017727

image-20240717203033710

◆数据流图的设计原则 (1)数据守恒原则:对任何一个加工来说,其所有输出数据流中的数据必须能从该加工的输入数据流中直接获得,或者说是通过该加工能产生的数据。(2)守恒加工原则:对同一个加工来说,输入与输出的名字必须不相同,即使它们的组成成分相同。 (3)对于每个加工,必须既有输入数据流,又有输出数据流(4)外部实体与外部实体之间不存在数据流(5)外部实体与数据存储之间不存在数据流(6)数据存储与数据存储之间不存在数据流 (7)父图与子图的平衡原则:子图的输入输出数据流同父图相应加工的输入输出数据流必须致,此即父图与子图的平衡。父图与子图之间的平衡原则不存在于单张图。(8)数据流与加工有关,且必须经过加工。

◆数据字典DD数据流图描述了系统的分解,但没有对图中各成分进行说明。数据字典就是为数据流图中的每个数据流、文件、加工,以及组成数据流或文件的数据项做出说明。数据字典有以下4 类条目:数据流、数据项、数据存储和基本加工。

image-20240717203104284

加工逻辑也称为“小说明”。常用的加工逻辑描述方法有结构化语言、判定表和判定树 3 种。

2.解题技巧 文老师软考教育 数据流图的考试形式非常固定,第一小题补充外部实体,第二小题补充数据存储,第三小题补都不算难,以题目描述和数据流图为主,答案都在题目充缺失数据流,第四小题考察简单概念。描述里,更像是阅读理解题,技巧如下,1、补充外部实体:外部实体就是与系统进行交互的其他实体,可以是大型系统公司部门、相关人员等,外部实体会与系统进行交互,反应在数据流图中就是一个个事件流,依据事件的名称结合题目描述可以轻易得出答案。 2、补充数据存储:数据存储出现在0层数据流图中,反应系统内部数据的存储可以直接根据数据流图中数据存储的输入数据流和输出数据流判断该数据存储的信息得出答案但注意要使用题目说明的数据存储名词作为答案, 3、补充缺失数据流:详细阅读题目描述,依据题目描述对涉及的数据流图进行一核对,这是因为即使开始就去考虑数据守恒、父图子图平衡等原则,最终还是要根据最为简单直接的方法题目描述核对,不如一开始就直接核对。 简单概念:题型不固定,一般只有2-3分,都是比较简单的判断

常见问题: a:补充数据存储时,题目中没有具体存储名称怎么办?A:此时可依据数据流图中数据存储的输入输出数据流自行起名, 补充数据流时,该写多少条?a: 般按分写,几分就写几条A: 觉得要补充的数据流很多,比分数更多怎么办?可以多写,这个是按点给分的,多写不会扣分,但要注意不能太过分。A: 总觉得数据流把握不准,跟答案有出入怎么办? 其次,首先要注意,软考官方不公布标准答案,所有答案都是老师校对的,可能会不全面A'部分真题本身也不太严谨,有二义性。因此不用太纠结,掌握解题方法,多刷题即可。 这种题目该怎么学习学习到哪种程度呢?Q:要求能拿到12分以上看完视频对应专题课程后,立即去做后面的历年真题。A:

历年典型真题1详解

某公司欲开发一款二手车物流系统,以有效提升物流成交效率。该系统的主要功能是:(1)订单管理:系统抓取线索,将车辆交易系统的交易信息抓取为线索。帮买顾问看到有买车线索后,会打电话询问买家是否需要物流,若需要,帮买顾问就将这个线索发起为订单并在系统中存储,然后系统帮助买家寻找物流商进行承运。(2)路线管理:帮买顾问对物流商的路线进行管理,存储的路线信息包括路线类型、物流商、起止地点。路线分为三种,即固定路线、包车路线、竞拍体系,其中固定路线和包车路线是合约制。包车路线的发车时间由公司自行管理,是订单的首选途径。(3)合约管理:帮买顾问根据公司与物流商确定的合约,对合约内容进行设置,合约信息包 括物流商信息、路线起止城市、价格、有效期等。(4)寻找物流商:系统根据订单的类型(保卖车、全国购和普通二手车)、起止城市,需要的服务模式(买家接、送到买家等)进行自动派发或以竞拍体系方式选择合适的物流商。即:有新订单时,若为保卖车或全国购,则直接分配到竞拍体系中:否则,若符合固定路线和/或包车路线,系统自动分配给合约物流商,若不符合固定路线和包车路线,系统将订单信息分配到竞拍体系中。竞拍体系接收到订单后,将订单信息推送给有相关路线的物流商,物流商对订单进行竞拍出价最优报价的物流商中标。最后,给承运的物流商发送物流消息,更新订单的物流信息,给车辆交易系统发送物流信息。 (5)物流商注册:物流商账号的注册开通。

image-20240717203450509

问题1】(3分)使用说明中的词语,给出图1-1中的实体E1~E3的名称, 问题2】(5分)使用说明中的词语,给出图1-2中的数据存储D1~D5的名称, 【问题3】(4分)根据说明和图中术语,补充图1-2中缺失的数据流及其起点和终点 【问题4】(3分)根据说明,采用结构化语言对“P5:寻找物流商”的加工逻辑进行描述

image-20240717203512675

【说明】 某房产中介连锁企业欲开发一个基于Web的房屋中介信息系统,以有效管理房源和客户提高成交率。该系统的主要功能是: 1.房源采集与管理。系统自动采集外部网站的潜在房源信息,保存为潜在房源。由经纪人联系确认的潜在房源变为房源,并添加出售/出租房源的客户。由经纪人或客户登记的出售/出租房源,系统将其保存为房源。房源信息包括基本情况、配套设施、交易类型、委托方式、业主等。经纪人可以对房源进行更新等管理操作。2.客户管理。求租/求购客户进行注册、更新,推送客户需求给经纪人,或由经纪人对求租/求购客户进行登记、更新。客户信息包括身份证号、姓名、手机号、需求情况、委托方式等。3.房源推荐。根据客户的需求情况(求购/求租需求情况以及出售/出租房源信息),向已登 录的客户推荐房源。经纪人对租售客户双方进行交易信息管理,包括订单提交和取消,设置收4.交易管理。:取中介费比例。财务人员收取中介费之后,表示该订单已完成,系统更新订单状态和房源状态,向客户和经纪人发送交易反馈。 5.信息查询。客户根据自身查询需求查询房屋供需信息。

image-20240717203538623

问题:1.1(4分)使用说明中的词语,给出图1-1中的实体E1-E4的名称。 问题:1.2(4分)使用说明中的词语,给出图1-2中的数据存储D1-D4的名称。 问题:1.3(3分)根据说明和图中术语,补充图1-2中缺失的数据流及其起点和终点,。 问题:1.4(4分)根据说明中术语,给出图1-1中数据流"客户信息"、"房源信息"的组成。

image-20240717203604874

◆E-R图:即实体-联系图,使用椭圆表示属性、长方形表示实体、菱形表示联系,联系两端要标注联系类型。联系类型:一对一1:1、一对多1:N、多对多M:N。实体和弱实体(之间直接用直线连接,是从属关系,无联系类型)1、 多个实体一个类型(一般是三个实体连接到一个类型上,根据题目说明,:若有三个实体相关 则是此种情况) 3、主键和外键(主键是本关系内唯一,外键是其他关系的主键,外键可以有多个)

image-20240717203625154

关系模式就是以名称和属性名表示一个联系,如下 客户(客户ID、姓名、身份证号、电话、住址、账户余额)员工(工号、姓名、性别、岗位、身份证号、电话、住址)家电(家电条码、家电名称、价格、出厂日期、(1))家电厂商(厂商ID、厂商名称、电话、法人代表信息、厂址、(2))购买(订购单号、(3)、金额) ◆主键:不能为空,能唯一标识当前关系的属性。 ◆外键:其他关系模式的主键或者为空。

◆ E-R图转换为关系模式 E-R图中,有实体和联系两个概念,实体和实体之间的联系分为三种,即1:1,1:N,M:N,这三种情况转换为关系模式的方法也不同。 ◆首先,每个实体都要转换为一个关系模式,对于联系: 一对二联系作为一个属性随便加入哪个实体中一对多联系可以单独转换为一个关系模式,也可以作为一个属性加入到N端中(N端实体包含1端的主键) ◆多对多,联系必须单独转换为一个关系模式(且此关系模式应该包含两端实体的主键) ◆转换之后要注意:原来的两个实体之间的联系必须还存在能够通过查询方式查到对方,

数据库设计的考法也非常固定,第一小题补充E-R图,第二小题补充关系模式,第三小题是简单的情景问答题。同样也都不难,结合题目描述和E-R图的一些特点可以轻易得出答案,技巧如下:1、补充E-R图:这是重中之重,E-R图如果弄错了,后续题目都有影响,主要是根据题目描述确认哪些实体之间有联系,联系类型是哪一种,而后进行连线即可,并不难。 补充关系模式:实际考察的是将E-R图转换为关系模式,补充缺失的属性,分成两步:首先需要审题,题目会给出每个关系模式的属性信息,先将题目中的属性信息和问题对应,将缺少的属性全部补充;而后再按照规则转换,即前面所说的规则,按联系的三种对应方式决定要添加哪些字段。 3、情景问答:一般都是给出一段新的描述,要求新增一种实体-联系类型和关系模式,本质也是考察联系类型和E-R图转换为关系模式。 ◆注意审题,?常识以及E-R图转换为关系模式的原则(主要是联系的归属)

◆常见问题: E-R图转换为关系模式时,总觉得不对怎么办?Q:学员在这种类型题目里唯一的模糊点就是这里,转换为关系模式,遵循两步法首先以题目A:描述为主,然后再根据不同类型的转换原则去判断是否有遗漏。 这种题目该怎么学习,!学习到哪种程度呢?Q: 要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。A:

【说明】 某创业孵化基地管理若干孵化公司和创业公司,为规范管理创业项目投资业务,需要开发一个信息系统。请根据下述需求描述完成该系统的数据库设计。需求描述) (1)记录孵化公司和创业公司的信息。孵化公司信息包括公司代码、公司名称、法 人代表名称注册地址和一个电话:创业公司信息包括公司代码、公司名称和一个电话。孵化公司和创业公司的公司代码编码不同。(2)统一管理孵化公司和创业公司的员工。员工信息包括工号、身份证号、姓名、性别、所属公司代码和一个手机号,工号唯一标识每位员工,(3)记录投资方信息。投资方信息包括投资方编号、投资方名称和一个电话。(4)投资方和创业公司之间依靠孵化公司牵线建立创业项目合作关系,具体实施由 孵化公司的-位员工负责协调投资方和创业公司的一个创业项目。一个创业项目只属于一个创业公司,但可以接受若干投资方的投资。创业项目信息包括项目编号、创业公司代码、投资方编号和孵化公司员工工号。

【概念模型设计】 根据需求阶段收集的信息,设计的实体联系图 (不完整)如图2-1所示

逻辑结构设计根据概念模型设计阶段完成的实体联系图,得出如下关系模式(不完整)孵化公司(公司代码,公司名称,法人代表名称,注册地址,电话)创业公司(公司代码,公司名称,电话)员工(工号,身份证号,姓名,性别,(a),手机号)投资方(投资方编号、投资方名称,电话)项目(项目编号,创业公司代码(b),孵化公司员工号)

image-20240717203747363

【问题1】(5分) 根据问题描述,补充图2-1的实体联系图。 【问题2】(4分)补充逻辑结构设计结果中的(a)、(b)两处空缺及完整性约束关系。 【问题3】(6分)若创业项目的信息还需要包括投资额和投资时间,那么(1)是否需要增加新的实体来存储投资额和投资时间?如果增加新的实体,请给出新实体的关系模式,并对图2-1进行补充。如果不需要增加新的(2)实体,请将“投资额”和“投资时间”两个属性补充连线到图2-1合适的对象上,并对变化的关系模式进行修改。

问题2🅰️所属公司代码,b:投资方编号完整性约束: a.主键:工号 外键:所属公司代码b.主键:项目编号,投资方编号 外键:创业公司代码,员工号 问题3:不需要创建新实体,修改项目关系模式为项目(项目编号,创业公司代码,投资方编号,孵化公司员工工号,投资额,投资时间)

image-20240717203819227

image-20240717203827552

说明】 某海外代购公司为扩展公司业务,需要开发一个信息化管理系统。请根据公司现有业务及需求完成该系统的数据库设计。需求描述) (1)记录公司员工信息。员工信息包括工号、身份证号、姓名、性别和一个手机号,工号唯一标识每位员工,员工分为代购员和配送员。 (2)记录采购的商品信息。商品信息包括商品名称、所在超市名称、采购价格、销售价格和商品介绍,系统内部用商品条码唯一标识每种商品。一种商品只在一家超市代购。(3)记录顾客信息。顾客信息包括顾客真实姓名、身份证号(清关缴税用)、一个手机号和一个收货地址,系统自动生成唯一的顾客编号。(4)记录托运公司信息。托运公司信息包括托运公司名称、电话和地址,系统自动生成唯一的托运公司编号。 (5)顾客登录系统之后,可以下订单购买商品。订单支付成功后,系统记录唯一的支付凭证编号,顾客需要在订单里指定运送方式:空运或海运。(6)代购员根据顾客的订单在超市采购对应商品,一份订单所含的多个商品可能由多名代购员从不同超市采购。 (7)采购完的商品交由配送员根据顾客订单组合装箱,然后交给托运公司运送。托运公司按顾客订单核对商品名称和数量,然后按顾客的地址进行运送。

概念模型设计】 根据需求阶段收集的信息,设计的实体联系图(不完整)如图2-1所示

逻辑结构设计】根据概念模型设计阶段完成的实体联系图,得出如下关系模式(不完整) 员工(工号,身份证号,姓名,性别,手机号)商品(条码,商品名称,所在超市名称,采购价格,销售价格,商品介绍)顾客(编号,姓名,身份证号,手机号,收货地址)托运公司(托运公司编号,托运公司名称,电话,地址)订单(订单ID,(a),商品数量,运送方式,支付凭证编号)代购员工号,(b)) 代购(代购ID, 运送(运送ID,配送员工号,托运公司编号,订单ID,发运时间)

image-20240717203906600

【问题1】(3分)根据问题描述,补充图2-1的实体联系图。 【问题2】(6分) 补充逻辑结构设计结果中的(a)、(b)两处空缺。 【问题3】(6分) 为方便顾客,允许顾客在系统中保存多组收货地址。请根据此需求,增加“顾客地址”弱实体对图2-1进行补充,并修改“运送”关系模式。

答案: 问题2:(a)商品条码,顾客编号(b)订单ID,商品条码问题3:运送关系增加顾客地址字段,所以运送不需要再关联订单信息。

image-20240717203935602

◆用例图:主要考察参与者和用例的识别、用例之间的关系(包含include、扩展extend、泛化)。

image-20240717203954184

◆类图:主要考察填类名、多重度、类之间的联系◆多重度(有点类似于E-R图中的联系类型)含义如下1:表示一个集合中的一个对象对应另一个集合中1个对象。0..:表示一个集合中的一个对象对应另一个集合中的0个或多个对象。表示一个集合中的一个对象对应另一个集合中的一个或多个对象。1.·表示一个集合中的一个对象对应另一个集合中的多个对象。米。

image-20240717204012713

状态图主要描述状态之间的转换,主要考察的就是填状态名填状态转换的条件,具体如图所示◆转换可以通过事件触发器触发,事件触发后相应的监护条件会进行检查。状态图中转换和状态是两个独立的概念,如下:图中方框代表状态,箭头上的代表触发事件,实心圆点为起点和终点。

image-20240717204031721

序列图:即顺序图,动态图是场景的图形化表示,描述了以时间顺序组织的对象之间的交互活动。 消息名主要考察填对象名、消息就是一个个箭头上传递的,对象作为实体在最上端。

image-20240717204050996

通信图:是顺序图的另一种表示方法,也是由对象和消息组成的图,只不过不强调时间顺序只强调事件之间的通信,而且也没有固定的画法规则,和顺序图统称为交互图。主要考察填对象名、填消息。

image-20240717204116325

活动图:动态图,是一种特殊的状态图,展现了在系统内从一个活动到另一个活动的流程。活动的分岔和汇合线是一条水平粗线。◆主要考察填活动名称。

image-20240717204135727

◆由前面的介绍可知,考察UML建模就是考察多种图形,对这些图形的考察一般都是缺失一些关键点,而后要求考生补图。◆要求认真审题,根据题干说明补齐类名或者对象名或者消息名等等,记住类图和对象图中的多重度(互相独立的分析,掌握表示方法)、类之间的联系标识(多边形端为整体,直线端为个体) ◆认真审题,审图,根据说明查缺补漏,一般来说有以下几种题型:1、补充用例图:主要考察补充用例名称、参与者、用例之间的关系只要认真审题,根据题中描述核对,都可以轻易得出答案。 2、补充类图:主要考察补充类名称,!需要根据类之间的关系以及多重度来判断,需要牢记类之间关系的图形符号,尤其是组合、聚合和泛化的符号,并且观察符号上的多重度数字,与题目描述对应。 3、补充状态图:主要补充状态名称,根据题目描述可以轻易得出答案

常见问题: 9:看到一张类图都是空的,就懵了,该怎么办?类和类之间的联系,尤其是泛化联系是非常重要的,也是解题的关键,要记住泛化联系的符A:里而后去题目描述里找到具有父子关系的实体,基本上题目就一步步解出来了。其他如组合聚合联系的符号也是解题关键。 这种题目该怎么学习,!学习到哪种程度呢?要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。A:

说明】 某牙科诊所拟开发一套信息系统,用于管理病人的基本信息和就诊信息。诊所工作人员包括:医护人员(Dentaltaff)、接待员(Receptionist)和办公人员(0fficestaf)等。系统主要功能需求描述如下1.记录病人基本信息(Maintain patientinfo)。初次就诊的病人,由接待员将病人基本信息录入系统病人基本信息包括病人姓名、身份证号、出生日期、性别、首次就诊时间和最后一次就诊时间等每位病人与其医保信息(Medicallnsurance)关联。2.记录就诊信息(Record office visit info)。病人在诊所的每一次就诊,由接待员将就诊信息(0fficeVisit)录入系统。就诊信息包括就诊时间、就诊费用、支付代码、病人支付费用和医保支付费用等。病人在就诊时,可能需要接受多项治疗,每项治疗3.记录治疗信息(Record dental procedure)。(Procedure)可能由多位医护人员为其服务。治疗信息包括:治疗项目名称、治疗项目描述、治疗的牙齿和费用等。治疗信息由每位参与治疗的医护人员分别向系统中录入。4.打印发票(Print invoices)。发票(lnvoice)由办公人员打印。发票分为两种:给医保机构的发票(insurancelnvoice)和给病人的发票(Patientinvoice)。 两种发票内容相同,只是支付的费用不同。当收到治疗费用后,办公人员在系统中更新支付状态(Enterpayment)。5.记录医护人员信息(Maintain dentalstaffinfo)。办公人员将医护人员信息录入系统。医护人员信息包括姓名、职位、身份证号、家庭住址和联系电话等。6.医护人员可以查询并打印其参与的治疗项目相关信息(Search and print procedureinfo)。

现采用面向对象方法开发该系统,得到如图3-1所示的用例图和3-2所示的初始类图

image-20240717204226880

【问题1】(6分)根据说明中的描述,给出图3-1中A1~A3所对应的参与者名称和U1~U3所对应的用例名称。 问题2】(5分)根据说明中的描述,给出图3-2中C1~C5所对应的类名, 【问题3】(4分)根据说明中的描述,给出图3-2中类C4、C5、Patient和Dentalstaff的必要属性。

答案: 问题1:A1:接待员(Receptionist)A2:医护人员(DentalStaff) A3:办公人员(OfficeStaff) 记录病人基本信息(Maintain patient info)U1: U2:记录就诊信息(Record office visit info) 打印发票(Print invoices)U3 : 问题2:C1:给病人的发票(PatientInvoice)给医保机构的发票(Insurancelnvoice)C2:C3:发票(lnvoice)C4:治疗(Procedure)c5:就诊信息(Office Visit) 问题3:C4:治疗项目名称、治疗项目描述、治疗的牙齿和费用、参与治疗的医护人员C5:就诊时间、就诊费用、支付代码、病人支付费用和医保支付费用、病人身份证号:Patient属性:病人姓名、身份证号、出生日期、性别、首次就诊时间和最后一次就诊时间、医保信息; Dentalstaff属性:姓名、职位、身份证号、家庭住址和联系电话

【说明】某玩具公司正在开发一套电动玩具在线销售系统,用于向注册会员提供端对端的玩具定制和销售服务。在系统设计阶段,"创建新订单(New Order)"的设计用例详细描述如表3-1所示,候选设计类分类如表3-2所示,并根据该用例设计出部分类图如3-1所示。

image-20240717204301380

image-20240717204310303

在订单处理的过程中,会员可以点击“取消订单”取消该订单。如果支付失败,该订单将被标记为挂起状态,可后续重新支付,如果挂起超时30分钟未支付,系统将自动取消该订单。订单支付成功后,系统判断订单类型:(1)对于常规订单,标记为备货状态,订单信息发送到货运部,完成打包后交付快递发货:(2)对于定制订单,会自动进入定制状态,定制完成后交付快递发货。会员在系统中点击”收货"按钮变为收货状态,结束整个订单的处理流程。根据订单处理过程所设计的状态图如图3-2所示

image-20240717204331354

【问题1】(6分)根据表3-1中所标记的候选设计类请按照其类别将编号C1~C12分别填入表3-2中的(a)、(b)和(c)处。 问题2 (4分)根据创建新订单的用例描述,请给出图3-1中X1~X4处对应类的名称。 【问题3】(5分)根据订单处理过程的描述,在图3-2中S1~S5处分别填入对应的状态名称。

答案: 问题1::C3、C8(a) C5、C7、C10、C11(c)C1、C2、C4、C6、C9、C12 问题2:X1:收货地址X2:支付方式X3:邮箱地址X4:电动玩具定制属性 问题3:S1:订单挂起 S2:订单备货S3:订单定制S4:订单发货S5:订单收货

image-20240717204402183

◆英文分号 也就是说,每个语句必须以分号结束,在C程序中,分号是语句结束符。 ◆C语言有两种注释方式: 以/开始的单行注释,这种注释可以单独占一行。 /**/这种格式的注释可以单行或多行。 不能在注释内嵌套注释,注释也不能出现在字符串或字符值中。 ◆C标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。一个标识符以字母 A-Z或 a-z或下划线 开始,不能以数字开始,后跟零个或多个字母、下划线和数字(0-9)。c标识符内不允许出现标点字符,比如 @、$ 和 %。C是区分大小写的编程语言。 c语言自己保留的关键字,编写程序时不能与之重复,如变量定义int/char/double等保留字。

c中的空格◆只包含空格的行,被称为空白行,可能带有注释,C编译器会完全忽略它。◆在C中,空格用于描述空白符、制表符、换行符和注释。空格分隔语句的各个部分,让编译器能识别语句中的某个元素(比如 int)在哪里结束,下一个元素在哪里开始。因此,在下面的语句中:int age; 在这里,int和 age 之间必须至少有一个空格字符(通常是一个空白符),这样编译器才能够区分它们。另一方面,在下面的语句中:fruit=apples+oranges;//获取水果的总数fruit 和 =,或者=和 apples 之间的空格字符不是必需的,但是为了增强可读性,可以根据需要适当增加一些空格。 ◆sizeof获取存储字节为了得到某个类型或某个变量在特定平台上的准确大小,可以使用sizeof运算符。表达式sizeof(type) 得到对象或类型的存储字节大小。

void类型 void 类型指定没有可用的值。它通常用于以下三种情况下

image-20240717204438904

变量其实只不过是程序可操作的存储区的名称。C中每个变量都有特定的类型类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上◆变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为C是大小写敏感的。◆变量定义:指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示type variable list;在这里,type必须是一个有效的c数据类型,可以是char、w_char、int、float、double 或任何用户自定义的对象,variable list 可以由一个或多个标识符名称组成,多个标识符之间用逗号分隔。下面列出几个有效的声明:int i j, k; ◆变量可以在声明的时候被初始化(指定一个初始值)。初始化器由一个等号,后跟一个常量表达式组成,如下所示: type variable name = value下面列举几个实例:int d= 3,f= 5;char x ='x': //定义并初始化 整型变量d和 f/字符型变量x的值为'x'

image-20240717204503720

c常量 ◆整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0x 表示十六进制表示八进制,不带前缀则默认表示一十进制。◆浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量,如: 3.14159 /合法的/ 314159E-5 /*合法的 */◆字符常量是括在单引号中,可以是一个普通的字符(例口'x')一个转义序列(例如“t')在C中,有一些特定的字符当它们前面有反斜杠时它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等。 ◆字符串字面值或常量是括在双引号"" 中的。,一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。 宏定义#define 用来定义一个可以代替值的宏,,语法格式如下#define 宏名称 值 实例:define LENGTH 10 //后续使用可用LENGTH代替10这个常量

const关键字定义一个只读的变量,本质是修改了变量的存储方式为只读。 const int LENGTH=10;//定义变量LENGTH=10,且只读,即无法修改LENGTH值。 使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。static 修饰符也可以应用于全局变量或函数。当 static修饰全局变量或函数时,会使变量或函数的作用域限制在声明它的文件内。 ◆extern 关键字用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候 一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE:typedef关键字为类型取-typedef unsigned char BYTE:在这个类型定义之后,标识符 BYTE 可作为类型 unsigned char 的缩写,例如:BYTE b1, b2;

算术运算符: 下表显示了c语言支持的所有算术运算符。假设变量A的值为 10,变量B的值为 20,则:

image-20240717204539885

关系运算符:下表显示了c语言支持的所有关系运算符。假设变量A的值为10,变量B的值为20,则:

image-20240717204559460

逻辑运算符:下表显示了c语言支持的所有逻辑运算符。假设变量A的值为1,变量B的值为0则

image-20240717204623163

赋值运算符下表列出了c语言支持的赋值运算符

image-20240717204640051

杂项运算符口 sizeof& 三元下表列出了c语言支持的其他一些重要的运算符,包括sizeof和?:。

image-20240717204657356

c判断:判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。C语言把任何非零和非空的值假定为true把零或 nu 假定为 false。

image-20240717204719659

c循环循环语句允许我们多次执行一个语句或语句组,C语言提供了以下几种循环类型:

image-20240717204735175

循环控制语句 (1)break语句 C语言中 break 语句有以下两种用法◆当 break 语句出现在一个循环内时循环会立即终止,且程序流将继续执行紧接着循环的下条语句。◆它可用于终止 switch 语句中的一个 case。如果使用的是嵌套循环(即一个循环内嵌套另一个循环)break语句会停止执行最内层的循环然后开始执行该块之后的下一行代码。 (2)continue语句◆C语言中的 continue 语句会跳过当前循环中的代码,强迫开始下一次循环。◆对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 while 和 do..while 循环continue 语句重新执行条件判断语句。 (3)goto语句◆C语言中的 goto 语句允许把控制无条件转移到同一函数内的被标记的语句

C作用域 ◆局部变量:在某个函数或块的内部声明的变量称为局部变量。,它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。◆在程序中,人局部变量和全局变量的名称可以相同,但是在函数内,如果两个名字相同,会使用局部变量值,全局变量不会被使用。 C内存管理◆定义一个指针,必须使其指向某个存在的内存空间的地址,才能使用,否则使用野指针会造成段错误,内存分配与释放函数如下: void free(void *addr); //该函数释放addr所指向的内存块,释放的是动态分配的内存空间,void *malloc(int size); //在堆区分配一块制定大小为size的内存空间,用来存放数据,不会被初始化。

下面是头文件 string.h中定义的函数,掌握以下常用的函数:void *memcpy(void *dest, const void *src,size tn):从src 复制n个字符到 dest。void *memset(void *str, intc,size tn):复制字符c(一个无符号字符)到参数 str所指向的字符串的前n个字符。char *strcat(char *dest, const char *src):把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,char *strncat(char *dest,const char *src,size tn):把src 所指向的字符串追加到 dest 所指向的字符串的结尾直到 n字符长度为止。char *strchr(const char *str,int c):在参数 str所指向的字符串中搜索第一次出现字符c(一个无符号字符)的位置。int strcmp(const char *str1, const char *str2):把 str1 所指向的字符串和 str2 所指向的字符串进行比较,int strncmp(const char *str1, const char *str2,size tn):把str1和 str2 进行比较,最多比较前n个字节char *strcpy(char *dest, const char *src):把src 所指向的字符串复制到 dest。char *strncpy(char *dest,const char *src,size tn):把src 所指向的字符串复制到 dest,最多复制n个字符size t strlen(const char *str):计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。char *strrchr(const char *str,int c):在参数str所指向的字符串中搜索最后一次出现字符c(一个无符号字符)的位置。
char *strstr(const char *haystack, const char *needle):在字符串 haystack 中查找第一次出现字符串 needle(不包含空结束字符)的位置。

image-20240717204816140

image-20240717204827926

看看历年真题判断关键字 0-1 背包问题定义为:给定i个物品的价值 v[1…i]、小重量 w[1...i]和背包容量T,每个物品装到背包里或者不装到背包里。求最优的装包方案,使得所得到的价值最大。“ 0-1背包问题具有最优子结构性质。定义ci为最优装包方案所获得的最大价值,则可得到如下所示的递归式。e 0c]T]=c{i-1max(ci-1]+v].ci-1) 若i=0或T=0 若T<w[] 若i>0日Tzw[i]。 动态规划法:最优子结构、递归、公式。

看看历年真题判断关键字 n皇后问题描述为:在一个 nxn的棋盘上摆放n个皇后,要求任意两个皇后不能冲突,即任意两个皇后不在同一行、同一列或者同一斜线上。e 算法的基本思想如下:←将第i个皇后摆放在第i行,i从1开始,每个皇后都从第1列开始尝试。尝试时判断在该列摆放皇后是否与前面的皇后有冲突,如果没有冲突,则在该列摆放皇后,并考虑摆放下一个皇后;如果有冲突,则考虑下一列。如果该行没有合适的位置,回溯到上一个皇后考虑在原来位置的下一个位置上继续尝试摆放皇后,…,直到找到所有合理摆放方案。← 回溯法:回溯。

看看历年真题判断关键字 给定一个字符序列 B-b;b....b,其中bE{A,C,G,U)。B上的二级结构是一组字符对集 合 S={(b,b;)},其中i,j∈{1,2.…n,并满足以下四个条件: (1)S中的每对字符是(A,U),(U,A),(C,G)和(GC)四种组合之一: (2)S中的每对字符之间至少有四个字符将其隔开,即i<j-4: (3)S中每一个字符(记为b)的配对存在两种情况:b不参与任何配对;b和字符b配对,其中t<k-4; (4)(不交叉原则)若(b,b;)和(b,b)是S中的两个字符对,且i<k,则i<k<j<1不成立。 B的具有最大可能字符对数的二级结构S被称为最优配对方案,求解最优配对方案中的字符对数的方法如下: 假设用C(ij)表示字符序列bb…...b,的最优配对方案(即二级结构S)中的字符对数,则 C(i.j)可以递归定义为: (max(c(.j-1).mar(C(L,t-1)+1+C( +1,j-1))お,働西R层i<j-4C(LD=香则 动态规划法:最优配对方案、递归式、公式。

看看历年真题判断关键字 某公司购买长钢条,将其切割后进行出售。切割钢条的成本可以忽略不计,钢条的长度为整英寸。已知价格表P,其中中 Pi(i=1,2,…m)表示长度为i英寸的钢条的价格。现要求解使销售收益最大的切割方案。← 求解此切割方案的算法基本思想如下:← 假设长钢条的长度为n英寸,最佳切割方案的最左边切割段长度为i英寸,则继续求解剩余长度为n-i英寸钢条的最佳切割方案。考虑所有可能的i,得到的最大收益rn 对应的切割方案即为最佳切割方案rn 的递归定义如下:← rn =max1s i ≤n(pi +rn-i)← 对此递归式,给出自顶向下和自底向上两种实现方式<动态规划法:最优、递归式、公式。

看看历年真题判断关键字 【说明】← 假币问题:有n枚硬币,其中有一枚是假币,己知假币的重量较轻。现只有一个天平,要求用尽量少的比较次数找出这枚假币。← 【分析问题】← 将n枚硬币分成相等的两部分: (1)当n为偶数时,将前后两部分,即 1..n/2和 n/2+1..0,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币:9 (2)当n为奇数时,将前后两部分,即 1..(n-1)/2 和(n+1)/2+1..0,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币:若两端重量相等,则中间的硬币,即第(n+1)/2 枚硬币是假币。← 分治法:分成两部分、分而治之

看看历年真题判断关键字 设有n个货物要装入若干个容量为C的集装箱以便运输,这n个货物的体积分别为(s1,s2,…,sn),且有 s1≤c(1≤i≤n)。为节省运输成本,用尽可能少的集装箱来装运这n个货物。←下面分别采用最先适宜策略和最优适宜策略来求解该问题。e 最先适宜策略(firstfit)首先将所有的集装箱初始化为空,对于所有货物,按照所给的次序,每次将一个货物装入第一个能容纳它的集装箱中。e 最优适宜策略(bestfit)与最先适宜策略类似,不同的是,总是把货物装到能容纳它且目前剩余容量最小的集装箱,使得该箱子装入货物后闲置空间最小。← 贪心法:求最优,但没有最优子结构、递归等。

◆算法设计是下午软件设计中最难的题型,主要难在C代码填空上,因此文老师的建议是先不解决代码填空题(因为最难)先解决其他外围问题(如时间复杂度、算法技巧、取特殊值计算结果),最后解决代码填空,有助于理解整个题目,技巧如下:最后解决,并不影响解决其他题目,要理解题目算法原理,才能得出1、代码填字:第一小题,答案。另外近几年的算法设计真题有很大的技巧,即便不理解算法原理也可以推导出答案,要结合算法描述中的公式,以及算法代码中类似的分支,能够发现填空的答案在代码中其中地方已经给出,因为算法原理的相似可以通用,尤其是分治法算法。详见文老师真题详解,详述技巧。 2、算法、时间复杂度:第二小题,先做,考察何种算法很好分辨,涉及到分组就是分治法,局部最优就是贪心法,整体规划最优就是动态规划法,迷官类的问题是回溯法,记住关键字很好区分;时间复杂度就是看c代码中的for循环层数和每一层的循环次数,涉及到二分必然有0(logn)。 3、特殊值计算:第三小题,一般应该先做,,不需要根据C代码,直接根据题目给出的算法原理一步步推导即可得出答案,耐心推导并不难。但要注意,如果遇到算法原理十分复杂的,建议放弃,掌握问题1和2的技巧即可

文老师说这一题最难,我也没基础,能不能干脆放弃?Q:这种思想是错误的,这一题共15分放弃就难通过了,要尽可能的拿分,,至少关于时间复杂A:度、算法判断是很简单的;而算法填空,平时做练习也要认真对待每一题,坚持下来,时间长了即使零基础也能填对几个, Q:完全没有C语言代码基础,看不懂怎么办?A.文老师在讲解真题和技巧时已经充分考虑到这一点,对于零基础学员,先认真听语法讲解然后听真题里对代码的分析,从英语的角度去联想其含义。不放弃就有收获。 Q:算法判断不准确,不能辨别贪心法和动态规划法怎么办?A:算法判断是很简单的了,题目中都有关键词暗示的,分而治之是分治法;迷宫问题回溯法;当题目中给出“考虑当前情况下”等词,是局部最优;当题目给出“最优子结构”、)递归、最优公式等,是动态规划法。 时间复杂度不知道如何求? 看代码循环重数,注意是嵌套的重数,不是个数。A: 这种题目该怎么学习,学习到哪种程度呢?要求能拿到8分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧。A:

【说明】0-1背包问题定义为:给定ì个物品的价值v1..1、小重量w[1..]和背包容量T,每个物品装到背包里或者不装到背包里。求最优的装包方案,使得所得到的价值最大。0-1背包问题具有最优子结构性质。定义c[i][T]为最优装包方案所获得的最大价值,则可得到如下所示的递归式。 若i=0或T-0 cfi 1[T]- 若 T<w[i] max(ci- 1T-w[i]]+v].ci-1) 若i>0目T≥w[] 【c代码】下面是算法的C语言实现。 (1)常量和变量说明 T: 背包容量 v]:价值数组 w[1:重量数组 c:ci表示前i个物品在背包容量为j的情况下最优装包方案所能获得的最大价值

image-20240717205013508

【问题1】(8分)根据说明和C代码,填充c代码中的空(1)~(4)。 【问题2】(4分)根据说明和C代码,算法采用了(5)设计策略。在求解过程中,采用了(6)(自底向上或者自顶向下)的方式。 问题3】(3分)若5项物品的价值数组和重量数组分别为v[]=(0,1,6,18,22,28}和w[]=(0,1,2,5,6,7}背包容量为T= 11,则获得的最大价值为(7)。

image-20240717205034098

阅读下列说明和C代码,回答问题1至3,将解答写在答题纸的对应栏内。说明n皇后问题描述为:在一个nXn的棋盘上摆放n个皇后,要求任意两个皇后不能冲突,即任意两个皇后不在同一行、同一列或者同一斜线上。算法的基本思想如下:将第i个皇后摆放在第i行,从1开始,每个皇后都从第1列开始尝试。尝试时判断 在该列摆放皇后是否与前面的皇后有冲突,如果没有冲突,则在该列摆放皇后,并考虑摆 放下一个皇后;如果有冲突,则考虑下一列。如果该行没有合适的位置,回溯到上一个皇后考虑在原来位置的下一个位置上继续尝试摆放皇后,……,直到找到所有合理摆放方案。 (1)常量和变量说明← n:皇后数,棋盘规模为nxn quccn[]:皇后的摆放位置数组,qucen[i]表示第i个皇后的位置,I≤queen[i]≤n

image-20240717205055063

问题1】(8分)根据题干说明,填充C代码中的空(1)一(4)。 问题2】(3分)根据题干说明和C代码,算法采用的设计策略为 币软 (5) 【问题3】(4分)当n=4时,有(6) 种摆放方式,分别为(7)

答案:问题1: (1)queen[i]==queen[j] (2)13)Place(i)&&j<=nNqueen( j+1) 问题2:(5)回溯法问题3:有2种摆法,分别为2413,3142

image-20240717205132909

创建对象 ◆对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:声明:声明一个对象,包括对象名称和对象类型。实例化:使用关键字 new 来创建一个对象。初始化:使用 new 创建对象时,会调用构造方法初始化对象。运行后会输出:小狗的名字是:tommy

image-20240717205150786

image-20240717205200693

◆访问控制修饰符:Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。 Java 支持以下访问权限。 private:在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)public:对所有类可见。使用对象:类、接口、变量、方法 protected:对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类) 请注意以下方法继承的规则: 父类中声明为 public 的方法在子类中也必须为 public。◆父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。 ◆父类中声明为 private 的方法,不能够被继承。

abstract 修饰符抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充◆如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误·抽象类可以包含抽象方法和非抽象方法。 public abstract class superclassabstract void m(); //抽象方法 abstract class caravanfprivate double priceprivate string model;private string year;public abstract void goFast(); //抽象方法public abstract void changecolor(); class Subclass extends superclass//实现抽象方法void m(){ 抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类◆如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。:抽象类可以不包含抽象方法,抽象方法的声明以分号结尾,例如:publicabstract sample();。

java继承的特性子类拥有父类非 private 的属性、方法子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。子类可以用自己的方式实现父类的方法。 ◆继承可以使用 extends 和 implements 这两个关键字来实现继承, extends关键字在Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

image-20240717205243477

◆下午考试的第5,6题为二选一作答,都是程序填空,原理一模一样,只不过一个用C++语言-个用JAVA语言编写的程序,并且这个填空只是考基本语法,不涉及算法,比之第4题算法设计的填空简单很多,突完全可以拿满分。 ◆文老师建议,如果是初学者,或者对于两种语言都不太精通,就专攻JAVA程序题,,因为JAVA的语法比之C++要简单并且容易理解记忆,容易拿到满分。 ◆面向对象的程序填空分为两类,一个是考察纯定义如接口类,抽象类,接口类中的函数定义等,这些根据程序代码可以快速判断出。 ◆另一类,就是关于设计的,填写函数体,但是这个函数体并不是要写一段真正的程序实现代码而是调用形式的,都有调用函数的,这些调用函数一般在程序中,或者在说明和类图中可以找到考察的是调用形式。

◆常见问题: Q:零基础完全不懂JAVA语言怎么办?A:这一题完全可以从英语角度去理解,都能得出答案,毫无难根据关键词去搜索代码上下文,度,每个人都能拿满分,要先树立信心 9:视频里为什么没有对于JAVA语言的详细讲解?A:语言之间都是相通的,结合文老师前面对c语言的讲解,:学员再去分析C语言或者JAVA语言,其关键语法都是类似的,这个考试又不需要大家去关注细节,因此完全够用了。如果想了解具体JAVA语法可在百度搜索“java教程”找一个简短的页面整体浏览一遍即可,没有必要去看相关java代码视频。关键还在于多做真题,多听视频讲解,自己多总结。 这种题目该怎么学习,!学习到哪种程度呢?Q: 要求能拿到12分以上;看完视频对应专题课程后,立即去做历年真题,掌握技巧A:

【说明】某文件管理系统中定义了类0fficeDoe和DocExplorer。当类OfficeDoc发牛变化时,类DocExplorer的所有对象都要更新其自身的状态。现采用观察者(0bserver)设计模式来实现该需求,所设计的类图如图6-1所示。

image-20240717205335298

image-20240717205346815

image-20240717205359143

答案:void update();过西寸四Observer;obs.update();Subject;Attach(this);

阅读下列说明和Java代码,将应填入(n)处自对应栏内。说明】某快餐厅主要制作并出售儿童套餐,一般包括主餐(各类比萨)、饮料和玩具,其餐品种类可能不同,但其制作过程相同。前台服务员(Waiter)调度厨师制作套餐。现采用生成器(Builder)模式实现制作过程,得到如图6-1所示的类图。

image-20240717205430675

image-20240717205445607

image-20240717205457685

数据流图

问题一:外部实体

image-20250514193351287

image-20250514194049976

问题二:数据存储

image-20250514193444912

问题三:数据流

加工:就是图中的P

image-20250514193643324

外部实体(方框):如客户、管理员

加工/处理(圆形/椭圆):功能模块,编号如 1、2、3 等

数据流(箭头):数据在系统内流动的路径,带数据名

数据存储(双横线):表/文件,如“预订表”“客户信息表”等

原则说明
1️⃣ 每个功能(加工)都有数据流进和出加工是处理信息的,不可能孤立
2️⃣ 每个数据流有“起点”和“终点”,且必须有一个是加工起点/终点可能是外部实体、加工、数据存储
3️⃣ 每个数据存储必须被“读”和“写”至少一次数据库要能被访问、更新
4️⃣ 所有数据流图要与上下文图对应(整体数据流平衡)不能新增没有上下文图支撑的数据流
5️⃣ 功能模块之间尽量通过数据存储交互加工 → 存储 → 加工,不直接连接除非必要

实战技巧:如何找出缺失数据流?

你可以用“三问法”:


✅ 1. 谁触发了这个功能?(外部实体 → 加工)

  • 谁是触发者?

  • 会发送什么数据?

  • 数据叫什么名?

例:

客户提交预订请求 → 临时预订 → 数据流名:客户预订请求


✅ 2. 功能需要访问哪些数据?(加工 → 数据存储)

  • 需要读取什么信息(检查)?

  • 需要写入什么信息(更新)?

例:

检查可用性 → 读取“预订表” 临时预订 → 写入“预订表” 和 “客户信息表”


✅ 3. 功能会向谁返回结果?(加工 → 外部实体/存储)

  • 系统要返回哪些确认、信息?

  • 要发送通知给谁?

例:

确认预订 → 给客户发出“预订确认信息” 要求付款 → 给客户发送“支付余款通知”


✅ 四、应用到你的题目(例子分析)

你题中提到的一些已知点,转换成数据流图要素:

功能/加工输入数据流输出数据流存取数据
1. 检查可用性客户预订请求可用/不可用信息读取:预订表
2. 临时预订客户预订请求通知临时预订确认、支付定金要求写:预订表、客户信息表
3. 分配设备设备需求信息更新确认、写入设备表读/写:设备表、预订表
4. 确认预订客户支付通知预订确认信息更新:预订表
5. 变更预订客户变更请求变更确认信息读:预订表,写:预订表、设备表
6. 要求付款系统判断(查询)支付余款通知读:预订表、客户表
7. 支付余款客户支付通知支付确认更新:预订表

ER图

联系类型

类型含义举例特点
1. 一对一(1:1)A 的一条记录最多对应 B 的一条记录人 ⇄ 身份证双方都唯一
2. 一对多(1:N)A 的一条记录对应 B 的多条记录,B 的一条记录只能对应 A 的一条部门 → 员工一边唯一,另一边不唯一
3. 多对多(M:N)A 的一条记录可对应 B 的多条记录,反之亦然学生 ⇄ 课程双方都不唯一,需要中间表

主键和外键判断

主键

✳️ 1. 能否唯一标识一条记录(唯一性

  • 主键的基本要求:能唯一标识一条记录。

  • 如果用某一个字段不能唯一,就需要组合其他字段

✳️ 2. 是不是“最小字段组合”即可唯一(最小性

  • 组合字段越少越好,不能多加不必要的字段。

  • 比如:(A, B) 能唯一,就不用 (A, B, C)

问题判断
单个字段是否唯一标识记录?否 → 考虑复合主键
加上哪个字段后可以唯一?找出最小组合
是否还加了多余的字段?是 → 不符合“最小性”,去掉

场景 1:选课系统

选课表:

  • 学号(student_id)

  • 课程号(course_id)

  • 选课时间

一个学生可以选多门课,一门课也可以被多个学生选 → 需要复合主键。

✅ 主键 = (student_id, course_id)


🎯 场景 2:员工表

员工表:

  • 员工号(唯一)

  • 姓名

  • 电话

✅ 主键 = 员工号(单字段即可,不需要复合)


🎯 场景 3:群发消息系统

消息记录:

  • 编号

  • 接收人

一个编号可以群发 → 需要靠接收人区分

✅ 主键 = (编号, 接收人)

外键

问题判断方式
是不是外键?看这个字段是否引用了另一个表的主键
外键和主键一样正常吗?是的,尤其在一对一关系中
一个字段能是外键也是主键吗?可以,比如 profile.emp_id 既是外键又是主键
外键一定要是主键吗?❌ 外键引用的是别的表的主键;自身并不一定是主键
外键必须唯一吗?❌ 外键字段可以重复(比如多个员工属于同一个部门)
  • ✅ 消息表:消息(编号, 内容, 接收人, 发送人)

  • 接收人、发送人 → 都是员工表的员工号 → 都是外键

  • 主键是 (编号, 接收人)

所以:

字段是主键吗?是外键吗?引用哪个表
编号✅ 是主键组成-
接收人✅ 是主键组成员工表(emp_id)
发送人员工表(emp_id)


✅ 六、你可以这样记:

✔️ 外键是用来连接别的表的,是否加外键,要看这个字段是不是“依赖另一个表”的数据。

UML画图

用例名

格式示例
动词 + 名词登录系统、浏览商品、提交订单、查询库存
动词短语修改个人信息、添加图书到购物车、处理支付请求

关系判断

重复执行?用 include:包含 多个用例都有的公共部分,抽出来,包含它。

有条件才执行?用 extend:扩展 某些情况才可能发生,属于附加或例外行为。

父子种类分?用 generalization:泛化 子用例“是”父用例的一种,还可能有自己特殊行为。

假设有以下场景:

  1. 用户登录系统时必须验证密码

  2. 登录失败时提示错误信息

  3. 登录方式可以是“密码登录”或“指纹登录”

请判断三者之间的关系:

  • 验证密码是必须 → <<include>>

  • 提示错误信息是条件行为 → <<extend>>

  • 密码登录、指纹登录是登录的两种方式 → generalization

算法

算法判断和时间复杂度

动态规划法:最优子结构、最优配对方案、递归、公式

回溯法:回溯

分治法:分成两部分、分而治之

贪心法:求最优、但没有最优子结构,递归等

Java程序设计

原型模式

例1 阅读下列说明和 Java 代码,将应填入(n)处的子句写在答题纸的对应栏内。(2013年5月试题六)

现要求实现一个能够自动生成求职简历的程序,简历的基本内容包括求职者的姓名、性别、年龄及工作经历。希望每份简历中的工作经历有所不同,并尽量减少程序中的重复代码。现采用原型模式(Prototype)来实现上述要求,得到如图 6-26 所示的类图。

image-20250310115436820

 //工作简历
Class WorkExperience (1) Cloneable{
    Private string workDate;
    Private string company;
    Public object clone() {
        (2);
        obj.workDate=this.workDate;
        obj.company-this.company;
        Return obi;
    }
}
​
Class Resume (3) Cloneable {
    Private string name;
    Private string sex;
    Private string age;
    Private WorkExperience work;
    Public Resume(string name){
        This.name=name;
        work=new WorkExperience();
    }
    Private Resume(WorkExperience work){
        This.work=(4)
    }   
    Public void setPersonalInfo(string sex,string age){ 
        /*代码省略*/
    }
    Public void SetworkExperience(String workDate,string company){
        /*代码省略*/
    }
    Public obiect clone(){
        Resume obi=(5)
        //其余代码省略
        Return obi;
    }
    
Class WorkResumef {
    Public static void main(string[] args){
        Resume a=new Resume("张三");
        a.SetPersonalInfo("男""29");
        a.SetworkExperience("1998~2000","XXX公司");
        Resume b=(6);
        b.SetWorkExperience("2001~2006""YYY 公司");
    }
}
题中WorkExperience类和Resume类需要实现Cloneable接口,故空(1)处和空(3)处应填入implements。WorkExperience中需要实现Clone方法,并将自身复制一份,由下面的代码可知空(2)处应填入WorkExperience obj=new WorkExperience()。Resume类中的私有构造方法实现WorkExperience的深复制,故空(4)处应填入(WorkExperience)work.Clone()。而Resume类中的Clone方法实现自身的复制,故空(5)处应填入new Resume(this.work)。main中实现Resume b对a的复制,故空(6)处应填入a.Clone。
答案:
(1)implements
(2)WorkExperience obj=new WorkExperience()
(3)implements
(4)(WorkExperience)work.Clone()
(5)new Resume(this.work)
(6) a.Clone()

抽象工厂

现欲开发一个软件系统,要求能够同时支持多种不同的数据库,为此采用抽象工厂式设计该系统。以SQL Server和 Access 两种数据库以及系统中的数据库表Department 为例其类图如图 6-27 所示。

image-20250310140205823

import java.util.*;
​
class Department {
    /*代码省略*/
}
​
interface IDepartment {
    (1)
    (2)
}
​
class SqlserverDepartment (3) {
    public void Insert(Department department) {
        System.out.println("Insert a record into Department in SOL Server!\n");
        //其余代码省略
    }
    public Department GetDepartment(int id){
        /*代码省略*/
    }
}
class AccessDepartment (4) {
    public void Insert (Department department){
        System.out.println("Insert a record into Department in AccEss!\n");
        //其余代码省略
    }
    public Department GetDepartment(int id){
        /*代码省略*/
    }
}
​
(5) {
    (6)
}
                   
class SalserverFactoryimplements IFactory {
    public IDepartment CreateDepartment() {
        return new SalserverDepartment();
    }
    //其余代码省略
}
class AccessFactory implements IFactory {
    public IDepartment CreateDepartment() {
        return new AccessDepartment();
        //其余代码省略
    }
}
空(1)处和空(2)处考查接口 IDepartment 中方法的定义。由其子类 SglserverDepartment和 AccessDepartment 中方法的定义,可知空(1)处应填入 void Insert(Department department)空(2)处应填入 Department GetDepartment(int id).
空(3)处和空(4)处考查接口 IDepartment 的实现。接口的实现是在一个类的声明中使用关键字“implements”来表示该类使用某个已经定义的接口,然后即可在该类体中使用接口中定义的常量,而且必须实现接口中定义的所有方法。因此,空(3)处和空(4)处都应填入implements IDepartment.
由于所给程序中缺少接口 IFactory 的定义,因此空(5)处应定义接口 IFactory,应填入interface IFactory。由于类 SqlserverFactory和AccessFactory 中必须实现接口 IFactory 中定义的所有方法,观察这两个类中的方法可知,空(6)处应填入 IDepartment CreateDepartment()。
​
答案:
(1)void Insert(Department department)
(2)Department GetDepartment(int id).
(3)implements IDepartment.
(4)implements IDepartment.
(5)interface IFactory.
(6)IDepartment CreateDepartment().

装饰器

某咖啡店卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如表 6-6 所示。

image-20250310141628308

现采用装饰器(Decorator)模式来实现计算费用的功能,得到如图 6-29 所示的类图

image-20250310141719436

import java.util.*;
(1) class Beverage { //饮料
    String description="Unknown Beverage";
    public (2)(){
        return description;
    }
    public (3);
}
abstract class CondimentDecorator extends Beverage {//配料
    (4)
}
class Espresso extends Beverage {//蒸馏咖啡
    private final int ESPRESSO PRICE = 25;
    public Espresso(){
        description="Espresso";
    }
    public int cost(){
        return ESPRESSO PRICE;
    }
}
class DarkRoast extends Beverage{//深度烘焙咖啡
    private final int DARKROAST PRICE = 20;
    public DarkRoast(){
        description="DarkRoast";
    }
    public int cost(){ 
        return DARKROAST PRICE;
    }
}
​
class Mocha extends CondimentDecorator {//摩卡
    private final int MOCHA PRICE=10;
    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    public string getDescription() {
        return beverage.getDescription()+",Mocha";
    }
    public int cost(){
        return MOCHA PRICE +beverage.cost();
    }
}
class Whip extends CondimentDecorator {//奶泡
    private final int WHIP PRICE=8;
    public whip(Beverage beverage){ 
        this.beverage = beverage;
    }
    public string getDescription(){
        return beverage.getDescription()+",whip";
    }
    public int cost(){
        return WHIP PRICE + beverage.cost();
    }
}
public class Coffee {
    public static void main(string args[]){
        Beverage beverage =new DarkRoast();
        beverage=new Mocha((5));
        beverage=new whip((6));
        System.out.println (beverage.getDescription()+"¥" +beverage.cost ());
    }
}
                                       
编译运行上述程序,其输出结果为:
DarkRoast,Mocha,whip ¥38

图 6-29 中的 Beverage 对应的就是图 6-30 中的抽象类 Component,Espresso和DarkRoast对应的是 ConcreteComponent,CondimentDecorator 对应的是 Decorator,Mocha 和 Whip 扮演的是类 CondimentDecorator 的具体装饰器角色 ConcreteDecorator。 由于类 Beverage 为其子类提供了统一的操作接口,所以将其定义为抽象类。可以通过在类名前加 abstract 关键字来定义抽象类,因此空(1)处应填入 abstract。空(2)处和空(3)处考查构造函数的定义。从空(2)处构造函数体中返回值的类型及后续的子类继承程序可知,空(2)处应填入 String getDescription;从 public int cost(){ returnESPRESSO PRICE;}可以看出,cost()函数的返回值为常量,因此(3)处应填入 abstract intcost(。 空(4)处考查对 CondimentDecorator 的定义,在该类中声明一类成员变量,并在this.beverage= beverage 和 retumn beverage.getDescription()+",Mocha"中加以使用,因此空(4)处应填入 Beverage beverage. 空(5)处和空(6)处考查实例化类模板的方法。类模板必须在实例化后才能使用。实例化类模板时,要给出类型实参。从类图可知,空(5)处和空(6)处均应填入 beverage。

(1)abstract
(2)String getDescription
(3)abstract int cost()
(4)Beverage beverage
(5)beverage
(6)beverage

(3) Beverage beverage; 是因为:

  • 每个装饰者需要 保存被装饰的对象

  • 它通过调用 beverage.getDescription()beverage.cost()扩展功能

状态模式

某大型商场内安装了多个简易的纸中售卖机,自动售出2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图 6-31 所示。

image-20250506160047536

采用状态(State)模式来实现该纸巾售卖机,得到如图 6-32 所示的类图。其中类 State 为抽象类,定义了投币、退币、出纸巾等方法接口。类 SoldState、SoldOutState、NoOuarterState和 HasQuarterState 分别对应图 6-31 中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有 2 元钱。

image-20250506160109348

import java.util.*
interface state{
    public void insertQuarter();//投币
    public void ejectQuarter();//退币
    public void turnCrank();//按下“出纸巾”按钮
    public void dispense();//出纸巾
}
​
class TissueMachinef
    (1) soldoutstate,noQuarterstate,hasQuarterstate,soldstate,state;
    state=soldoutState;
    int count=0; //纸巾数
    public TissueMachine(int number){/*实现代码省略*/}
    public state getHasQuarterstate(){return hasouarterstate;}
    public State qetNoQuarterState(){return noQuarterState;}
    public stategetSoldState() {return soldState;}
    public stategetSoldoutstate(){return soldoutstate;}
    int getCount{return count;}
    //其余代码省略
}
​
​
class NoQuarterstate implement statefTissueMachine tissueachine;public void insertQuarter(){tissueMachine.setstate((2));
//构造方法以及其余代码省略
class HasQuarterstate implement state TissueMachine tissueMachine;public void eiectouarter(){tissueMachine.setstate((3));
//构造方法以及其余代码省略
class soldstate implement state{TissueMachine tissueMachine;public void dispense(){if(tissueMachine.getCount()>0){tissueMachine.setstate((4));
else{
tissueMachine.setstate((5));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值