270 likes | 400 Vues
TKS. 1. 高级语言. (第十八讲). 在线做题排名 --EXCEL 排序问题. -- 结构数组程序设计. 绍兴文理学院. 计算机系计算机应用教研室. 第八章 结构与联合 (1). 一、教学目的: 明确结构数据类型的概念;掌握结构类型变量的定义方法、引用和初始化;掌握结构变量的操作方法;利用结构类型数据进行算法和程序设计能力的训练。. 二、教学重点: 结构类型变量的定义方法、引用和初始化;结构变量的操作方法;结构类型算法和程序设计能力的训练。. 三、教学难点: 结构变量的操作方法;结构体类型算法和程序设计能力的训练。 四、教学过程:.
E N D
TKS 1 高级语言 (第十八讲) 在线做题排名--EXCEL排序问题 --结构数组程序设计 绍兴文理学院 计算机系计算机应用教研室
第八章 结构与联合(1) 一、教学目的:明确结构数据类型的概念;掌握结构类型变量的定义方法、引用和初始化;掌握结构变量的操作方法;利用结构类型数据进行算法和程序设计能力的训练。 二、教学重点:结构类型变量的定义方法、引用和初始化;结构变量的操作方法;结构类型算法和程序设计能力的训练。 三、教学难点:结构变量的操作方法;结构体类型算法和程序设计能力的训练。 四、教学过程:
在线做题排名--EXCEL排序问题(1046) ? TKS 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的情况,如果学生具有相同姓名或者相同成绩,则按他们的学号递增排序。 —结构数组程序设计 04:36
§8.1 结构和联合的概念 TKS 4 C++语言还允许程序员在一定的框架范围内定制所需要的数据类型。定义了类型之后,程序员就可以使用它们来自定义变量,如同使用系统所提供的int、char、float、double、bool类型等一样。 C++语言允许用户自定义数据类型,自定义类型包括: 结构(struct)、枚举(enum)、联合(union)(也称共用体)和类(class)。 本课程主要讲解结构的使用。 §8.2 结构的定义 1、结构的引入 在实际应用中,有时候需要将不同类型的数据组合成一个有机的整体,这些组合在一个整体中的数据是互相联系的。 04:36
TKS 5 如一个学生的信息包括学号、姓名、性别、年龄、成绩、地址等。 int num; 应当把它们组织成一个组合项,在一个组合项内包含若干个类型不同(或相同)的数据项。 char name[20]; char sex; C++语言提供了这种数据结构:允许用户将不同类型的数据组合成一个有机的整体,这些数据互相联系;这种数据结构称为结构(structure)。 int age; float score; char addr[30]; 04:36
2、结构的定义格式 TKS 6 (1) 概述 所谓结构的定义,是指定义相应的数据结构,即创建一个新的数据类型。 因为只有数据类型才能去定义变量等。 (2) 定义一个结构体类型的一般形式 如: struct<结构类型名> { <成员类型名1><成员名1>; <成员类型名2><成员名2>; ………… <成员类型名n><成员名n>; }; structstudent {int num; char name[20]; char sex; int age; float score; char addr[30]; } ; ; 04:36
3、结构定义说明 ① struct是关键字,不能省略,表示将要进行结构的定义; ② student是用户自己定义的结构类型名的标志,即该结构类型名,由用户自己命名,用它可以定义相应的结构体变量; ③ {}内是该结构中的各个成员,由它们组成一个结构;在结构内对各成员都应进行类型声明; ④“成员表列”也称为域表。每个成员也称为结构的一个域,成员名命名规则与变量名一样; TKS 7 structstudent {int num; char name[20]; char sex; int age; float score; char addr[30]; }; ④每个成员名前的类型标识符可以为已定义了的任意类型,也可以是结构类型标识符,即结构成员也可以是另一个结构变量。 ⑤ 此处只是构造出一个新的类型,并没有定义该类型的变量,因此在内存中并没有开辟任何存储空间; ⑥ 在程序中可以定义多个结构体类型,不同结构体类型用不同的结构体名来区分。 04:36
§8.3 定义变量的定义和初始化 TKS 8 1、用结构类型名定义变量 (1) 定义形式 [struct]<结构类型名><变量名>[={<初始化数据>}],…; 注意:这里的结构类型名是已经定义了的。 (2) 定义结构体变量的三种方法 ① 用结构类型名定义变量 structstudent { int num; char name[20]; float score; }; studentstu1,stu2; 结构体类型名 结构体变量名 stu1 stu2 在定义了结构体变量后,系统会为之分配内存单元。 sizeof(stu1)= 4+ 20+ 4 =28 04:36
②定义无名结构类型的同时定义变量 (不出现结构类型名) TKS 9 struct { unsigned int num; char name[20]; char sex; int age; float score; char add[30]; }stu1,stu2,stu3; struct {<成员类型名1><成员名1>; <成员类型名2><成员名2>; ………… <成员类型名n><成员名n>; }; ③ 定义结构类型的同时定义变量 structstudent {unsigned int num; char name[20]; char sex; int age; float score; char add[30]; }stu1,stu2,stu3; struct结构体名 {<成员类型名1><成员名1>; <成员类型名2><成员名2>; ………… <成员类型名n><成员名n>; }变量名列表; 04:36
2、结构体变量的初始化 usx10101 Z h a n g X i \0 \0 \0 M 18 90.5 S h a n g h a i \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 TKS 10 同样,结构变量的初始化是在定义时进行。 structstudent {unsigned int num; char name[10]; char sex; int age; float score; char add[20]; }stdnt1{10101,“ZhangXi”,’M’,18,90.5,“Shanghai”}, stdnt2{10102,“WangLi”,’F’,19,88.3,“Beijing”}; 也可以使用以下形式 structstudentstdnt3{10103,“LiBin”,’M’,17,79.9,“HuBei}; num name sex age score add 04:36
§8.4 结构成员的访问 #include <iostream> using namespace std; struct student {unsigned int num; char name[20]; char sex; int age; float score; }; TKS 11 1、结构变量之间的赋值 允许两个同类型的结构变量之间相互赋值。 例1 结构变量之间的赋值C+18_1 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",s2.num, s2.name,s2.sex,s2.age,s2.score); return 0; } 04:36
但不允许 stdnt1={70101,“ZhangXi”,’M’,18,90.5,“Shanghai”}; TKS 12 2、引用结构变量的成员和结构类型数据的输入输出 (1) 引用形式 结构变量名.成员名 “.”是成员运算符,在所有的运算符中优先级最高。 structstudent {int num; char name[20]; float score; }stu1,stu2; stu1.num=70101 stu1.score=95; stu1.name ="Li Ming"; strcpy(stu1.name,"Li Ming"); (2) 不能将一个结构变量作为一个整体进体输入输出 printf("%d%s%f", stu1); cin>>stu1; 04:36
只能对结构中的各个成员分别进行输入输出。 TKS 13 printf("%d%s%f",stu1.num,stu1.name,stu1.score); cin>>stu1.num; gets(stu1.name); (3) 成员名也是一个变量(称为成员变量),具有自己的数据类型,使用与同类型的变量相同(根据其类型决定可以进行的运算)。 (4) 只有在对结构变量赋值或作为函数参数时才可以对一个结构变量进行整体操作;(赋值时要求具有相同结构)。 stu2.num=stu1.num; strcpy(stu2,name,stu1.name); stu2.score=stu1.score; stu2=stu1; void fun(student px); fun(stu1); §补充1 嵌套结构体类型 在声明一个结构类型时,可以利用已声明的另一结构类型来定义其成员的类型。这称为嵌套结构类型。 04:36
1、定义形式 TKS 14 structdate { int day; int month; int year; }; struct student { int num; char name[10]; char sex; int day; int month; int year; char addr[20]; }; struct student { int num; char name[10]; char sex; date birthday; char addr[20]; }; sizeof(struct student)=? 04:36
2、访问规则 TKS 15 如果成员本身又属于一个结构类型,则要用若干个成员运算符,一级一级的找到最低一级的成员。只能对最低一级的成员进行赋值、存取或运算; 如: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; }; 04:36
TKS 16 补充例1 嵌套结构体变量的访问C+18_2 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; } 04:36
§补充2 结构数组 TKS 17 数组的每个元素都是结构类型的数据,每个元素分别包含各个成员项。 §补充2.1 结构数组的定义与初始化 定义结构数组的方法与定义结构变量的方法类似 1、定义结构数组 (1) 先定义结构类型,再定义结构数组 (2) 定义结构类型的同时定义结构数组 struct student { int num; float score; } stu[34]; struct student { int num; float score; }; studentstu[34]; 04:36
2、结构数组的初始化 (1) 一般形式 (3) 直接定义结构数组 TKS 18 struct { int num; float score; } stu[30]; struct结构类型名 { <成员类型名1><成员名1>; <成员类型名2><成员名2>; ………… <成员类型名n><成员名n>; }结构数组={{数组元素0的各个初值}, {数组元素1的各个初值}, ……}; 04:36
(2) 示例 70101 " ZhangXi" M 18 90.5 "103 Bejing Road" 70102 "WangLi" F 19 88.3 "130 Shanghai Roaad" TKS 19 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] 04:36
§补充2.2 对结构数组元素的操作 TKS 20 1、结构数组元素的赋值 一个结构数组元素(结构下标变量)相当于一个结构变量,可以将一个结构数组元素赋值给同一结构类型的数组中的另一个元素,或赋给同一类型的变量。 如:student stu[3],student1; 则可以进行下面的赋值。 student1=stu[0]; stu[0]=stu[1]; stu[1]=student1; 2、引用结构体数组元素成员 引用结构数组元素的成员的方法与引用结构变量成员的方法相同。例如 stu[i].num 04:36
补充例2 输入3个学生的信息并将它们输出C+18_3 TKS 21 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(); } #include <iostream> using namespace std; #define stunum 3 struct studtype {char name[16]; long num; int age; char sex; float score; }; 04:36
补充例2 输入3个学生的信息并将它们输出C+18_3 TKS 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 按行输入学生的信息(输入到输入的均为0时结束),然后将它们输出C+18_3_1 04:36
补充例3 EXCEL排序问题(1046) C+18_4 TKS 23 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的情况,如果学生具有相同姓名或者相同成绩,则按他们的学号递增排序。 04:36
补充例3 EXCEL排序问题(1046) C+18_4 TKS 24 Sample Input 3 1 000007 James 85 000010 Amy 90 000001 Zoe 60 4 2 000007 James 85 000010 Amy 90 000001 Zoe 60 000002 James 98 4 3 000007 James 85 000010 Amy 90 000001 Zoe 60 000002 James 90 0 0 Sample Output Case 1: 000001 Zoe 60 000007 James 85 000010 Amy 90 Case 2: 000010 Amy 90 000002 James 98 000007 James 85 000001 Zoe 60 Case 3: 000001 Zoe 60 000007 James 85 000002 James 90 000010 Amy 90 04:36
补充例3 EXCEL排序问题(1046) C+18_4 #include <iostream> using namespace std; struct stunode {char num[7]; char name[9]; int score; }; TKS 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; } 04:36
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; } TKS 26 补充例3 EXCEL排序问题(1046) C+18_4 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( ? cmp(s,j,c)) {temp=s[j]; s[j]=s[j+1]; s[j+1]=temp;} } 04:36
★问:若姓名中有空格怎么办? 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; } TKS 27 输入: cin>>s[i].num;getchar(); gets(s[i].name); s[i].score=separate(s[i].name); 补充例4 在线做题排名问题 C+18_4_1 测试数据C+18_4_1.DOC ? 五、作业与实践: 1、上机编程: 6086、6087 2、实验二 函数程序设计