tks
DESCRIPTION
TKS. 1. 高级语言. (第十八讲). 在线做题排名 --EXCEL 排序问题. -- 结构数组程序设计. 绍兴文理学院. 计算机系计算机应用教研室. 第八章 结构与联合 (1). 一、教学目的: 明确结构数据类型的概念;掌握结构类型变量的定义方法、引用和初始化;掌握结构变量的操作方法;利用结构类型数据进行算法和程序设计能力的训练。. 二、教学重点: 结构类型变量的定义方法、引用和初始化;结构变量的操作方法;结构类型算法和程序设计能力的训练。. 三、教学难点: 结构变量的操作方法;结构体类型算法和程序设计能力的训练。 四、教学过程:. - PowerPoint PPT PresentationTRANSCRIPT
1TKS 1
(第十八讲)
绍兴文理学院计算机系计算机应用教研室
在线做题排名在线做题排名 --EXCEL--EXCEL 排序问排序问题题---- 结构数组程序设计结构数组程序设计
2
第八章 结构与联合 (1)
二、教学重点:二、教学重点:结构类型变量的定义方法、引用和初始结构类型变量的定义方法、引用和初始化;结构变量的操作方法;结构类型算法和程序设计能力化;结构变量的操作方法;结构类型算法和程序设计能力的训练。的训练。
一、教学目的:一、教学目的:明确结构数据类型的概念;掌握结构类型明确结构数据类型的概念;掌握结构类型变量的定义方法、引用和初始化;掌握结构变量的操作方变量的定义方法、引用和初始化;掌握结构变量的操作方法;利用结构类型数据进行算法和程序设计能力的训练。法;利用结构类型数据进行算法和程序设计能力的训练。
三、教学难点:三、教学难点:结构变量的操作方法;结构体类型算法结构变量的操作方法;结构体类型算法和程序设计能力的训练。和程序设计能力的训练。四、教学过程:四、教学过程:
3
Excel 可以对一组记录按任意指定列排序。现请你编写程序实现类似功能。
Input测试输入包含若干测试用例。每个测试用例的第 1 行包含两个整数 N (<=100000) 和 C ,其中 N 是记录的条数, C 是指定排序的列号。以下有 N 行,每行包含一条学生纪录。每条学生记录由学号( 6 位数字,同组测试中没有重复的学号)、姓名(不超过 8 位且不包含空格的字符串)、成绩(闭区间 [0, 100] 内的整数)组成,每个项目间用 1 个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。Output对每个测试用例,首先输出 1 行 "Case i:" ,其中 i 是测试用例的编号(从 1 开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2 时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。注意:对于 C=2 或者 C=3 的情况,如果学生具有相同姓名或者相同成绩,则按他们的学号递增排序。 —— 结构数组程序设计结构数组程序设计
?在线做题排名 --EXCEL 排序问题 (1046)
TKS
3 18:40
4
§8.1 §8.1 结构和联合的概念结构和联合的概念 C++C++ 语言还允许程序员在一定的框架范围内语言还允许程序员在一定的框架范围内定制定制所需要的所需要的数据数据类型类型。定义了类型之后,程序员就可以使用它们来自定义变量,如。定义了类型之后,程序员就可以使用它们来自定义变量,如同使用系统所提供的同使用系统所提供的 intint 、、 charchar 、、 floatfloat 、、 doubledouble 、、 boolbool 类型类型等一样。等一样。 C++C++ 语言允许用户自定义数据类型,自定义类型包括:语言允许用户自定义数据类型,自定义类型包括: 结构结构 (struct)(struct) 、枚举、枚举 (enum)(enum) 、联合、联合 (union)(union)(( 也称共用体也称共用体 )) 和和类类 (class)(class) 。。 本课程主要讲解本课程主要讲解结构结构的使用。的使用。§8.2 §8.2 结构的定义 11 、结构的引入、结构的引入 在实际应用中,在实际应用中,有时候需要有时候需要将不同类型的数据组合成一个有机的将不同类型的数据组合成一个有机的整体整体,这些组合在一个整体中的数据是互相联系的。,这些组合在一个整体中的数据是互相联系的。
TKS
4 18:40
5
numnum namename sexsex ageage scorescore addraddr070101070101 Li MingLi Ming MM 1919 96.596.5 ChengduChengdu
int num;int num;char name[20];char name[20];
char sex;char sex;int age;int age;
float score;float score;
char addr[30];char addr[30];
应当把它们组织成一个组合项,在一个组合项应当把它们组织成一个组合项,在一个组合项内包含内包含若干个类型不同若干个类型不同 (( 或相同或相同 )) 的数据项。的数据项。 C ++ 语言提供了这种数据结构:允许用户将不同类型的数据组合成一个有机的整体,这些数据互相联系;这种数据结构称为结构结构 (structure) 。
如一个学生的信息包括学号、姓名、性别、年龄、成绩、地址等。如一个学生的信息包括学号、姓名、性别、年龄、成绩、地址等。
TKS5 18:40
6
2 、结构的定义格式(1) 概述 所谓结构的定义,是指定义相应的数据结构,即所谓结构的定义,是指定义相应的数据结构,即创建一个新的数创建一个新的数据类型据类型。 。 因为因为只有数据类型只有数据类型才能去定义变量等。才能去定义变量等。(2) 定义一个结构体类型的一般形式
structstruct < 结构类型名结构类型名 >>{ < 成员类型名类型名 1>1> << 成员名成员名 1>1>;; < 成员类型名类型名 2>2> << 成员名成员名 22>>;; …… …… …… …… < 成员类型名类型名 n>n> << 成员名成员名 n>n>;;};
;
如:如: structstruct studentstudent{{ int num;int num; char name[20];char name[20]; char sex;char sex; int age;int age; float score;float score; char addr[30];char addr[30];} } ;
TKS
6 18:40
7
structstruct studentstudent{{int num;int num; char name[20];char name[20]; char sex;char sex; int age;int age; float score;float score; char addr[30];char addr[30];}};
3 、结构定义说明 ① structstruct 是关键字,不能省略是关键字,不能省略,表示将要进行结构的定义; ② ② studentstudent 是用户自己定义的结构类型名的标是用户自己定义的结构类型名的标志,即该志,即该结构类型名,结构类型名,由用户自己命名由用户自己命名 ,, 用它可用它可以以定义定义相应的相应的结构体变量结构体变量;; ③ ③ {}{}内是该结构中的各个成员,由它们组成一个结构;在结构内对各成员都应进行类型声明在结构内对各成员都应进行类型声明; ④④ “成员表列”也称为域表域表。每个成员也称为结构的一个域,成员名命名规则与变量名一样;
④ 每个成员名前的类型标识符可以为已定义了的任意类型,也可以是结构类型标识符,即结构成员也可以是另一个结构变量结构成员也可以是另一个结构变量。
⑤ 此处只是构造出一个新的类型,并没有定义该类型的变量,因此在内存中并没有开辟任何存储空间在内存中并没有开辟任何存储空间; ⑥ 在程序中可以定义多个结构体类型,不同结构体类型用不同的结构体名来区分。
TKS7 18:40
8
§8.3 §8.3 定义变量的定义和初始化 1 、用结构类型名定义变量(1) (1) 定义形式定义形式 [[struct] < 结构类型名结构类型名 >> << 变量名变量名 >> [[={<={< 初始化数据初始化数据 >}>}],…],…; 注意:这里的结构类型名是已经定义了的。是已经定义了的。(2) 定义结构体变量的三种方法定义结构体变量的三种方法 ① 用结构类型名定义变量结构类型名定义变量
struct student{ int num; char name[20]; float score;};;
student stu1,stu2;
结构体类型名结构体类型名 结构体变量名结构体变量名10101
Zhang 92
10102 Li 97
stu1
stu2
在定义了结构体变量后,系统会为之分配内存单元。sizeof(stu1)=4+20+4 =2828
TKS
8 18:40
9
structstruct {< 成员类型名类型名 1>1> << 成员名成员名 1>1>;; < 成员类型名类型名 2>2> << 成员名成员名 2>2>;; …… …… …… …… < 成员类型名类型名 n>n> << 成员名成员名 n>n>;;};
② 定义无名结构类型的同时定义变量定义无名结构类型的同时定义变量(( 不出现结构类型名不出现结构类型名 ))structstruct { unsigned int num; char name[20]; char sex; int age; float score; char add[30];} stu1,stu2,stu3 ;;
③ 定义结构类型的同时定义变量定义结构类型的同时定义变量structstruct 结构体名结构体名{< 成员类型名类型名 1>1> << 成员名成员名 1>1>;; < 成员类型名类型名 2>2> << 成员名成员名 2>2>;; …… …… …… …… < 成员类型名类型名 n>n> << 成员名成员名 n>n>;;}变量名列表变量名列表;;
structstruct student{unsigned int num; char name[20]; char sex; int age; float score; char add[30]; }stu1,stu2,stu3 ;;TK
S9 18:40
10
2 、结构体变量的初始化 同样,结构变量的初始化是在定义时进行。 structstruct student{unsigned int num; char name[10]; char sex; int age; float score; char add[20]; }stdnt1tdnt1{{1010110101,,“ZhangXi”“ZhangXi”,,’M’’M’,,1818,,90.590.5,,“Shanghai”“Shanghai”}},, stdnt2tdnt2{{1010210102,,“WangLi”“WangLi”,,’F’’F’,,1919,,88.388.3,,“Beijing”“Beijing”}};; 也可以使用以下形式也可以使用以下形式 structstruct student stdnt3tdnt3{{1010310103,,“LiBin”“LiBin”,,’M’’M’,,1717,,79.979.9,,“HuBe“HuBeii}} ;;
hhSS90.590.51818MM\0\0\0\0\0\0iiXXggnnaahhZZusx10101usx10101 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0iiaahhggnnaa
num
name
sexage
score
add
TKS
10 18:40
11
§8.4 §8.4 结构成员的访问11 、结构变量之间的赋值、结构变量之间的赋值 允许允许两个同类型两个同类型的结构变量之间的结构变量之间相互相互赋值赋值。。
#include <iostream>using namespace std;struct student{unsigned int num; char name[20]; char sex; int age; float score;};
int main(void){student s1={10101,“WangLi”, ‘M’,18,89.5}, s2; s2=s1; printf(“student1 :%u ,%s ,%c ,%u ,%5.2f\n”
,s1.num, s1.name,s1.sex,s1.age,s1.score); printf("student2 :%u ,%s ,%c ,%u ,%5.2f\n",s
2.num, s2.name,s2.sex,s2.age,s2.score); return 0;}
例 1 结构变量之间的赋值 C+18_1 例 1 结构变量之间的赋值 C+18_1
TKS
11 18:40
C+18_1.cpp
12
22 、引用结构变量的成员和结构类型数据的输入输出、引用结构变量的成员和结构类型数据的输入输出 但不允许 但不允许 stdnt1=tdnt1={{7010170101,,“ZhangXi”“ZhangXi”,,’M’’M’,,1818,,90.590.5,,“Shanghai”“Shanghai”}};;
struct student{ int num; char name[20]; float score;} stu1,stu2 ;;
stu1..num=70
101
stu1..score=9
5;
stu1..name
="Li Ming";
strcpystrcpy(stu1..name,"Li Ming");
(2) 不能将一个结构变量作为一个整体进体输入输出不能将一个结构变量作为一个整体进体输入输出
printf("%d%s%f", stu1); cin>>stu1;
(1) 引用形式引用形式 结构变量名结构变量名 .. 成员名成员名 “..” 是成员运算符,在所有的运算符中优先级最高。
TKS
12 18:40
13
(3) (3) 成员名也是一个变量成员名也是一个变量 (( 称为称为成员变量成员变量 )) ,具有自己的数据类型,具有自己的数据类型,使用与同类型的变量相同,使用与同类型的变量相同 ((根据其类型决定可以进行的运算根据其类型决定可以进行的运算 )) 。。
stu2=stu1;stu2=stu1;
stu2.num=stu1.num;strcpy(stu2,name,stu1.name);stu2.score=stu1.score;
void fun(void fun(studentstudent px); px); fun(fun(stu1stu1););
(4) (4) 只有在对结构变量只有在对结构变量赋值赋值或作为或作为函数参数函数参数时才可以对一个结构变时才可以对一个结构变量进行整体操作;量进行整体操作; ((赋值时要求具有相同结构赋值时要求具有相同结构 )) 。。
§§补充补充 1 1 嵌套结构体类型 在声明一个结构类型时,可以利用已声明的另一结构类型来定义其成员的类型。这称为嵌套结构类型。
只能对结构中的各个成员分别进行输入输出。只能对结构中的各个成员分别进行输入输出。printf("%d%s%f",stu1stu1..numnum,stu1stu1..namename,stu1stu1..scorescore);
cin>>stu1stu1..numnum; gets(gets(stu1stu1..namename););
TKS
13 18:40
14
structstruct date{ int day; int month; int year;};
struct student{ int num; char name[10]; char sex; date birthday; char addr[20];};sizeof(sizeof(struct studentstruct student)=)= ??
struct student{ int num; char name[10]; char sex; int day; int month; int year; char addr[20];};
11 、定义形式、定义形式
TKS
14 18:40
15
2 、访问规则 如果成员本身又属于一个结构类型,则要用若干个成员运算符,如果成员本身又属于一个结构类型,则要用若干个成员运算符,一级一级的找到最低一级的成员。一级一级的找到最低一级的成员。只能对最低一级的成员进行赋值只能对最低一级的成员进行赋值、存取或运算;、存取或运算; 如:如: student stu1; 则: stu1..birthday.year=1989;3 、补充例 1 嵌套结构变量的访问#include <iostream>using namespace std;struct Date{int month; int day; int year;};
struct Person{char name[20]; char sex; Date birthday; unsigned long num;};
TKS
15 18:40
16
int main(void){Person p1={"WangLi",'M',12,15,1992,111000222}; Person p2; p2=p1; printf("zhang:%s ,%c ,%d-%d-%d ,%lu\n",p1.name,p1.sex, p1.birthday.month,p1.birthday.day, p1.birthday.year,p1.num); printf("zhang:%s ,%c ,%d-%d-%d ,%lu\n",p2.name,p2.sex, p2.birthday.month,p2.birthday.day, p2.birthday.year,p2.num); return 0;}
补充例 1 嵌套结构体变量的访问 C+18_2 补充例 1 嵌套结构体变量的访问 C+18_2
TKS
16 18:40
C+18_2.cpp
17
§§补充补充 2 2 结构数组结构数组
struct studentstruct student{ int num; float score;};
studentstudent stu[34]stu[34];
(1) 先定义结构类型,再定先定义结构类型,再定义结构数组义结构数组 (2) 定义结构类型的同时定义定义结构类型的同时定义
结构数组结构数组struct studentstruct student{ int num; float score;} stu[34]stu[34];
数组的数组的每个每个元素都是结构类型的数据,元素都是结构类型的数据,每个每个元素元素分别包含分别包含各个成各个成员项。员项。§§补充补充 2.1 2.1 结构数组的定义与初始化结构数组的定义与初始化 定义结构数组的方法与定义结构变量的方法类似1 、定义结构数组定义结构数组
TKS
17 18:40
18
(3) 直接定义结构数组直接定义结构数组structstruct{ int num; float score;} stu[30]stu[30];
2 、结构数组的初始化(1) 一般形式一般形式structstruct 结构类型名{ < 成员类型名类型名 1>1> << 成员名成员名 1>1>;; < 成员类型名类型名 2>2> << 成员名成员名 2>2>;; …… …… …… …… < 成员类型名类型名 n>n> << 成员名成员名 n>n>;;}结构数组结构数组 ={{{{数组元素数组元素 00 的各个初值的各个初值 }},,
{{数组元素数组元素 11 的各个初值的各个初值 }} ,,
…… }};;
TKS
18 18:40
19
(2) 示例struct student{unsigned int num; char name[16]; char sex; int age; float score; char addr[30];};student stu[3]={{70101,“ZhangXi",'M',18, 90.5,“103 Bejing Road”}, {70102,“WangLi",‘F',19, 88.3,“130 Shanghai Road”}, {70103,“LiHong",‘M',17, 79.9,"1010 Zhongshan Road"}};
stu[0]
stu[1]
stu[2]
"130 Shanghai Roaad"
88.319F
"WangLi"70102
"103 Bejing Road"
90.518M
" ZhangXi"70101
…
TKS
19 18:40
20
§§补充补充 2.2 2.2 对结构数组元素的操作对结构数组元素的操作 1 、结构数组元素的赋值结构数组元素的赋值 一个结构数组元素一个结构数组元素 (( 结构下标变量结构下标变量 )) 相当于一个结构变量,可以相当于一个结构变量,可以将一个结构数组元素将一个结构数组元素赋值给同一赋值给同一结构类型的数组中的另一个结构类型的数组中的另一个元素元素,,或赋给或赋给同一同一类型的类型的变量变量。。 如:如: student stu[3]student stu[3] ,, student1;student1; 则可以进行下面的赋值。 则可以进行下面的赋值。 student1=stu[0];student1=stu[0]; stu[0]=stu[1];stu[0]=stu[1]; stu[1]=student1;stu[1]=student1;22 、引用结构体数组元素成员、引用结构体数组元素成员 引用结构数组元素的成员的方法与引用结构变量成员的方法引用结构数组元素的成员的方法与引用结构变量成员的方法相同相同。例如。例如 stu[i].numstu[i].num
TKS
20 18:40
21
补充例 2 输入 3 个学生的信息并将它们输出 C+18_3 补充例 2 输入 3 个学生的信息并将它们输出 C+18_3 #include <iostream>using namespace std;
#define stunum 3struct studtype{char name[16]; long num; int age; char sex; float score;};
int main(void){struct StudType stu[stunum]; int i; for(i=0;i<stunum;i++) {printf("enter all data of stu[%d] : \n",i); gets(stu[i].name); cin>>stu[i].num; cin>>stu[i].age;getchar(); cin>>stu[i].sex; cin>>stu[i].score;getchar(); }
TKS
21 18:40
C+18_3.cpp
22
printf("\nrecord name \t \t num\tage\tsex\tscore\n"); for(i=0;i<stunum;i++) printf("%d\t%-16s%-8d%d\t%-c\t%6.2f\n",i,stu[i].name, stu[i].num,stu[i].age,stu[i].sex,stu[i].score); return 0;}
补充例 2 输入 3 个学生的信息并将它们输出 C+18_3 补充例 2 输入 3 个学生的信息并将它们输出 C+18_3
补充例 2 按行输入学生的信息 ( 输入到输入的均为 0 时结束 ),然后将它们输出 C+18_3_1
补充例 2 按行输入学生的信息 ( 输入到输入的均为 0 时结束 ),然后将它们输出 C+18_3_1
TKS
22 18:40
C+18_3.cpp
C+18_3_1.cpp
23
补充例 3 EXCEL 排序问题 (1046) C+18_4补充例 3 EXCEL 排序问题 (1046) C+18_4Excel 可以对一组记录按任意指定列排序。现请你编写程序实现类似功能。Input测试输入包含若干测试用例。每个测试用例的第 1 行包含两个整数 N (<=100000) 和 C ,其中 N 是记录的条数, C 是指定排序的列号。以下有N 行,每行包含一条学生纪录。每条学生记录由学号( 6 位数字,同组测试中没有重复的学号)、姓名(不超过 8 位且不包含空格的字符串)、成绩 ( 闭区间 [0, 100] 内的整数 ) 组成,每个项目间用 1 个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。Output对每个测试用例,首先输出 1 行 "Case i:" ,其中 i 是测试用例的编号(从 1 开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2 时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。注意:对于 C=2 或者 C=3 的情况,如果学生具有相同姓名或者相同成绩,则按他们的学号递增排序。 TK
S23 18:40
24
Sample Input3 1000007 James 85000010 Amy 90000001 Zoe 604 2000007 James 85000010 Amy 90000001 Zoe 60000002 James 984 3000007 James 85000010 Amy 90000001 Zoe 60000002 James 900 0
补充例 3 EXCEL 排序问题 (1046) C+18_4补充例 3 EXCEL 排序问题 (1046) C+18_4Sample OutputCase 1:000001 Zoe 60000007 James 85000010 Amy 90Case 2:000010 Amy 90000002 James 98000007 James 85000001 Zoe 60Case 3:000001 Zoe 60000007 James 85000002 James 90000010 Amy 90
TKS
24 18:40
C+18_4.cpp
25
struct stunode s[100];int main(void){int n,c,i; while(cin>>n>>c) { if(n==0) break; for(i=0;i<n;i++) cin>>s[i].num>>s[i].name>>s[i].score; mysort(s,c,n); printf("Case %d:\n",t++); for(i=0;i<n;i++) printf("%s %s %d\n",s[i].num,s[i].name,s[i].score); } return 0;}
补充例 3 EXCEL 排序问题 (1046) C+18_4补充例 3 EXCEL 排序问题 (1046) C+18_4#include <iostream>using namespace std;struct stunode{char num[7]; char name[9]; int score;};
TKS
25 18:40
C+18_4.cpp
26
void mysort(struct stunode s[],int c,int n){int i,j; stunode temp; for(i=0;i<n-1;i++) for(j=0;j<n-1-i;j++) if( ?
bool cmp(stunode s[],int j,int c){ if(c==1) return strcmp(s[j].num,s[j+1].num)>0; if(c==2) if(strcmp(s[j].name,s[j+1].name)==0) return strcmp(s[j].num,s[j+1].num)>0; else return strcmp(s[j].name,s[j+1].name)>0; if(c==3) if(s[j].score==s[j+1].score) return strcmp(s[j].num,s[j+1].num)>0; else return s[j].score>s[j+1].score; return true;} 补充例 3 EXCEL 排序问题 (1046) C+18_4补充例 3 EXCEL 排序问题 (1046) C+18_4
cmp(s,j,c)) {temp=s[j]; s[j]=s[j+1]; s[j+1]=temp;}}
TKS
26 18:40
C+18_4.cpp
27TKS 27
五、作业与实践:五、作业与实践:1 、上机编程: 6086 、 60872 、实验二 函数程序设计
?
★ 问:若姓名中有空格怎么办?
补充例 4 在线做题排名问题 C+18_4_1
补充例 4 在线做题排名问题 C+18_4_1
输入:cin>>s[i].num;getchar();gets(s[i].name); s[i].score=separate(s[i].name);
int separate(char s1[]){int k,m=0,d=1;; k=strlen(s1)-1; while(k>=0&&s1[k]!=' ') {m=m+(s1[k]-48)*d; d=d*10;k--; } s1[k]='\0'; return m;}
测试数据 C+18_4_1.DOC测试数据 C+18_4_1.DOC
C+18_4_1.cpp
C18_4_1.doc.DOC