算法笔记习题 2-8小节

算法笔记@Ada_Lake

算法笔记代码保留地~~~

结构体

结构体初始化 即 构造函数 不需要写返回类型,函数名与结构体名相同

这里后面定义的pt[10]其实就是把结构体当作一个数组,后面要用到的那个数组就是pt[10]。而对其初始化后,需要用到结构体内的数时就相当于对构造的函数传参

在此写下算法笔记中的一个应用实例
结构体Point用于存放平面点的坐标x, y

// Ada
#include<stdio.h>
struct Point {
	int x, y;
	// 不经初始化定义pt[10]
	Point (){}
	//提供x, y的初始化
	Point (int _x, int _y) : x(_x), y(_y) {}
	//OR 
	//Point (int _x, int _y) { x = _x; y = _y; }
}pt[10];

int main(){
	int num = 0;
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < 3; j++){
				pt[num++] = Point(i, j);
			}
	}
	for(int i = 0; i < num; i++){
		printf("%d, %d", pt[i].x, pt[i].y);
}
	return 0;
}

2.8小节——C/C++快速入门->结构体(struct)的使用

问题 A: C语言11.1
  1. 题目描述 ,完成一个对候选人得票的统计程序。假设有3个候选人,名字分别为Li,Zhang和Fun。使用结构体存储每一个候选人的名字和得票数。记录每一张选票的得票人名,输出每个候选人最终的得票数。结构体可以定义成如下的格式:
    struct person {
    char name[20];
    int count;
    }leader[3] = {“Li”, 0, “Zhang”, 0, “Fun”, 0};
  2. 输入,第一行有一个整数n,表示以下有n张选票信息将会输入。保证n不大于100。以后的n行中,每一行包含一个人名,为选票的得票人。保证每一个人名都是Li,Zhang和Fun中的某一个。
  3. 输出,有三行,分别为Li,Zhang和Fun每人的得票数。格式为首先输出人名,其后输出一个冒号,最后输出候选人的得票数。
    请注意行尾输出换行。
  4. 样例输入,
    10
    Li
    Li
    Fun
    Zhang
    Zhang
    Fun
    Li
    Fun
    Zhang
    Li
  5. 样例输出,
    Li:4
    Zhang:3
    Fun:3

我的理解
1.结构体已经给出
2.两个数组之间相比较,用strcmp(a, b)== 0

**以下是代码**
// Ada
#include<stdio.h>
#include<string.h>

struct person {
	char name[20];
	int count;
}leader[3] = {"Li", 0, "Zhang", 0, "Fun", 0};

int main() {
	int n;
	scanf("%d", &n);
	if(n <= 100) {
		while(n--) {
			char str[30];
			scanf("%s", str);
			if(strcmp(str, "Li") == 0) {
				leader[0].count++;
			}
			else if(strcmp(str, "Zhang") == 0){
				leader[1].count++;
			}
			else if(strcmp(str, "Fun") == 0) {
				leader[2].count++;
			}
			else{
				printf("请输入“Li”或“Zhang”或“Fun”");
				n++;
				continue;
			}
		}
	}
	for(int i = 0; i < 3; i++) {
		printf("%s:%d\n", leader[i].name, leader[i].count);
	}
	
	return 0;
}
问题 B: C语言11.2 - [x] 二刷
  1. 题目描述 ,定义一个结构体student,存储学生的学号、名字、性别和年龄,读入每个学生的所有信息,保存在结构体中,并输出。结构体student的定义如下:
    struct student {
    int num;
    char name[20];
    char sex;
    int age;
    };
    本题要求使用指向结构体数组的指针进行输入和输出。
  2. 输入,第一行有一个整数n,表示以下有n个学生的信息将会输入。保证n不大于20。
    以后的n行中,每一行包含对应学生的学号、名字、性别和年龄,用空格隔开。保证每一个人名都不包含空格且长度不超过15,性别用M和F两个字符来表示。
  3. 输出,有n行,每行输出一个学生的学号、名字、性别和年龄,用空格隔开。请注意行尾输出换行。
  4. 样例输入,
    3
    10101 LiLin M 18
    10102 ZhangFun M 19
    10104 WangMin F 20
  5. 样例输出,
    10101 LiLin M 18
    10102 ZhangFun M 19
    10104 WangMin F 20

我的理解
本题要求使用指向结构体数组的指针进行输入和输出。
1.指向结构变量的指针
设结构体为stu,数组为str
则 struct stu *pstu;
pstu = &str;
2.指向结构体数组的指针
设结构体为stu,别名为str[10]
则struct stu *pstu;
pstu = str;

**以下是代码**
// Ada

#include<stdio.h>

struct student {
	int num;
	char name[20];
	char sex;
	int age;
}; 

int main(){
	int n;
	struct student *p;
	scanf("%d", &n);
	struct student st[n];

	if(n <= 20) {
		for(p = st; p < st+ n; p++){
			scanf("%d %s %c %d", &(p->num), p->name, &(p->sex), &(p->age));	
		}

	}	

	for(p = st; p < st + n; p++) {
		printf("%d %s %c %d\n", p->num, p->name, p->sex, p->age);
	}
	
	return 0;
}
**
1.定义结构体数组  :	struct student st[n];
2.定义结构体指针 : 	struct student *p;
3.指向结构体数组的指针: p = st
4.指向结构体数组的指针移动和判断 :  p < st+ n;
5.结构体数组的输入 :&(p->num);
==字符串类型的输入不要加&==
6.结构体数组的输出 : p->num;
7.char类型的记得用 %c
**
问题 C: C语言11.4
  1. 题目描述 ,设有若干个人员的数据,其中包含学生和教师。学生的数据中包括:号码、姓名、性别、职业、班级。教师的数据包括:号码、姓名、性别、职业、职务。可以看出,学生和教师所包含的数据是不同的。现在要求把这些数据放在同一个表格中储存,使用结构体中的共用体实现。结构体定义如下:
    struct {
    int num;
    char name[10];
    char sex;
    char job;
    union {
    int class;
    char position[10];
    }category;
    };
    在以上的结构体中,如果job项为s(学生),则第5项为class(班级);如果job项是t(教师),则第5项为position(职务)。
    输入几个人员的数据,将其保存在以上包含共用体的结构体数组中,并输出。
  2. 输入,第一行有一个整数n,表示以下n行分别表示n个人员的数据。保证n不超过100。之后的n行,每行有5项用空格隔开的内容。前4项分别为人员的号码(整数)、姓名(长度不超过9的无空格字符串)、性别(字符,m或f)和职业(字符,s或t)。如果第4项是s,则第5项为一个整数,表示班级;如果第4项是t,则第5项为一个长度不超过9的无空格字符串,表示职务。
  3. 输出,共有n行,与输入格式相同,输出读入的所有内容。请注意行尾输出换行。
  4. 样例输入,
    2
    101 Li f s 501
    102 Wang m t prof
  5. 样例输出,
    101 Li f s 501
    102 Wang m t prof

我的理解
包含共用体的结构体数组 用共用体别名。
st[i].category.position

**以下是代码**
// Ada
#include<stdio.h>

struct st{
	int num;
	char name[10];
	char sex;
	char job;
	union {
		int clas;
		char position[10];
	}category;
}st[10];


int main(){
	int n;
	scanf("%d", &n);
	if((n >= 0) &&( n <=100)){
		for(int i = 0; i < n; i++){
			scanf("%d %s %c %c", &(st[i].num), st[i].name, &(st[i].sex), &(st[i].job));
			if((st[i].job) == 's') {
			scanf(" %d", &st[i].category.clas);
		}
			if((st[i].job) == 't') {
			scanf(" %s", st[i].category.position);
			}
		}
	
	}
	for(int i = 0; i < n; i++) {
		printf("%d %s %c %c ", st[i].num, st[i].name, st[i].sex, st[i].job); 
		if((st[i].job) == 's') {
			printf("%d\n", st[i].category.clas);
		}
		if((st[i].job) == 't') {
			printf("%s\n", st[i].category.position);
		}
	}
	
	return 0;
}
**
1.结构体要有名字  :	struct st{};
2.class是类名,不能当做变量名使用,会当作又写了一个类型 
3.看清题意,s和t都是要算的
4.共用体有别名 st[i].category.position
5.非字符串的输入 : &(st[i].num)
6.字符串的输入 : st[i].name
7.非字符串的输出 : st[i].num
8.字符串的输出 : st[i].name
**
问题 D: C语言11.7
  1. 题目描述 ,编写两个函数input和print,分别用来输入5个学生的数据记录和打印这5个学生的记录。对于每一个学生,其记录包含了学号、名字、3门课程的成绩共5项。用主函数分别调用input和print函数进行输入和输出。
    要求使用结构体数组实现,结构体中包括了每个学生的5项记录。
  2. 输入,共有5行,每行包含了一个学生的学号(整数)、名字(长度不超过19的无空格字符串)和3门课程的成绩(0至100之间的整数),用空格隔开。
  3. 输出,与输入格式相同,每行输出一个学生的所有记录。请注意行尾输出换行。
  4. 样例输入,
    101 AAA 80 81 82
    102 BBB 83 84 85
    103 CCC 86 87 88
    104 DDD 89 90 91
    105 EEE 92 93 94
  5. 样例输出,
    101 AAA 80 81 82
    102 BBB 83 84 85
    103 CCC 86 87 88
    104 DDD 89 90 91
    105 EEE 92 93 94
    我的理解
    没什么好说的,结构体加函数
    以下是代码
// Ada
#include<stdio.h>

struct student{
	int num;
	char name[20];
	int grade1;
	int grade2;
	int grade3;
}st[10];

int main(){
	
	void input();
	void print();
	
	input();
	print();
	
	return 0;
}

void input(){
	for(int i = 0; i < 5; i++) {
		scanf("%d %s %d %d %d", &st[i].num, st[i].name, &st[i].grade1, &st[i].grade2, &st[i].grade3);
	}
}

void print(){
	for(int i = 0; i < 5; i++) {
		printf("%d %s %d %d %d\n", st[i].num, st[i].name, st[i].grade1, st[i].grade2, st[i].grade3);
	}
}

写成指向结构体数组的指针,即
以下是代码

// Ada
	#include<stdio.h>

struct student{
	int num;
	char name[20];
	int grade1;
	int grade2;
	int grade3;
}st[10];

int main(){
	void input(struct student*);
	void print(struct student*);
	
	struct student* p;
	p = st;
	
	input(p);
	print(p);
	
	return 0;
}

void input(struct student* p){
	for(int i = 0; i < 5; i++) {
		scanf("%d %s %d %d %d", &(p + i)->num, (p + i)->name, &(p + i)->grade1, &(p + i)->grade2, &(p + i)->grade3);
	}
}

void print(struct student* p){
	for(int i = 0; i < 5; i++) {
		printf("%d %s %d %d %d\n", (p + i)->num, (p + i)->name, (p + i)->grade1, (p + i)->grade2, (p + i)->grade3);
	}
}
问题 E: C语言11.8
  1. 题目描述 ,有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩。读入这10个学生的数据,要求输出3门课程的总平均成绩,以及个人平均分最高的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。
  2. 输入,共有10行,每行包含了一个学生的学号(整数)、名字(长度不超过19的无空格字符串)和3门课程的成绩(0至100之间的整数),用空格隔开。
  3. 输出,第一行包含了3个实数,分别表示3门课程的总平均成绩,保留2位小数,每个数之后输出一个空格。
    第二行输出个人平均分最高的学生的数据,与输入数据格式相同。如果有多位个人平均分最高的学生,输出按照输入顺序第一个最高分的学生数据。
    请注意行尾输出换行。
  4. 样例输入,
    101 AAA 80 81 82
    102 BBB 83 84 85
    103 CCC 86 87 88
    104 DDD 89 90 91
    105 EEE 92 93 94
    106 FFF 80 90 100
    107 GGG 85 90 95
    108 HHH 80 85 90
    109 III 90 91 92
    110 JJJ 91 88 87
  5. 样例输出,
    85.60 87.90 90.40
    105 EEE 92 93 94
    我的理解
    1.函数一:输入10个数
    2.函数二:处理10个数
    3.函数三:输出10个数
// Ada
#include<stdio.h>

struct student{
	int num;
	char name[10];
	int grade[3];
	double avegrade[3];
}st[10], stu;

int main(){
	int flag = 0;
	double max = 0;
	
	for(int i = 0; i < 10; i++) {
		scanf("%d %s %d %d %d", &st[i].num, st[i].name, &st[i].grade[0], &st[i].grade[1], &st[i].grade[2]);
	}
	
	for(int i = 0; i < 3; i++) {
		double sum = 0;
		for( int j = 0; j < 10; j++) {
			sum = sum + st[j].grade[i];
		}
		stu.avegrade[i] = sum / 10;	
	}
	
	for( int j = 0; j < 10; j++ ) {
		double avemax = 0;
		for( int i = 0; i < 3; i++ ) {
			avemax = avemax + st[j].grade[i];
		}
		if(max < avemax ){
			flag = j;
			max = avemax; 
		}
	}
	
	for(int i = 0; i < 3; i++){
		printf("%.2f ", stu.avegrade[i]); 
	} 
	printf("\n");
	printf("%d %s %d %d %d", st[flag].num, st[flag].name, st[flag].grade[0], st[flag].grade[1], st[flag].grade[2]);
	
	return 0;
} 

将其改为函数进一步优化

// Ada
#include<stdio.h>

struct student{
	int num;
	char name[10];
	int grade[3];
	double avegrade[3];
}st[10], stu;

int main(){
	int flag = 0;
	void scan();
	void grade();
	int max();
	void prin(int);
	 
	scan();
	grade();
	flag = max();
	prin(flag);

	return 0;
} 

void scan(){
	for(int i = 0; i < 10; i++) {
		scanf("%d %s %d %d %d", &st[i].num, st[i].name, &st[i].grade[0], &st[i].grade[1], &st[i].grade[2]);
	}
}

void grade(){
	for(int i = 0; i < 3; i++) {
		double sum = 0;
		for( int j = 0; j < 10; j++) {
			sum = sum + st[j].grade[i];
		}
		stu.avegrade[i] = sum / 10;	
	}
}

int max(){
	double max = 0;
	int flag = 0;
	for( int j = 0; j < 10; j++ ) {
			double avemax = 0;
		for( int i = 0; i < 3; i++ ) {
			avemax = avemax + st[j].grade[i];
		}
		if(max < avemax ){
			flag = j;
			max = avemax; 
		}
	}
	return flag; 
} 

void prin(int flag){
	for(int i = 0; i < 3; i++){
		printf("%.2f ", stu.avegrade[i]); 
	} 
	printf("\n");
	printf("%d %s %d %d %d", st[flag].num, st[flag].name, st[flag].grade[0], st[flag].grade[1], st[flag].grade[2]);
	
}

自己绕了一大圈,神经。。。没必要全部分开。代码少了快一半了

// Ada
#include<stdio.h>

struct student{
	int num;
	char name[10];
	int grade[3];
	double avegrade[3];
}st[10], stu;

int main(){
	int flag = 0;
	double max = 0, s1 = 0, s2 = 0, s3 = 0, avemax;
	
	for( int i = 0; i < 10; i++ ) {
		scanf("%d %s %d %d %d", &st[i].num, st[i].name, &st[i].grade[0], &st[i].grade[1], &st[i].grade[2]);
		s1 = s1 + st[i].grade[0];
		s2 = s2 + st[i].grade[1];
		s3 = s3 + st[i].grade[2];
		avemax = ( st[i].grade[0] + st[i].grade[1] + st[i].grade[2] ) / 3;
		if( max < avemax ) {
			flag = i;
			max = avemax; 
		}
	}
	s1 /= 10;
	s2 /= 10;
	s3 /= 10;

	printf("%.2f %.2f %.2f\n", s1, s2, s3); 

	printf("%d %s %d %d %d", st[flag].num, st[flag].name, st[flag].grade[0], st[flag].grade[1], st[flag].grade[2]);
	
	return 0;
} 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值