【日撸 Java 三百行】Day 10(综合任务 1)

news2025/5/12 0:54:13

目录

Day 10:综合任务 1

 一、题目分析

1. 数据结构

2. 相关函数基本知识

二、模块介绍

1. 初始化与成绩矩阵的构建

2. 创建总成绩数组

3. 寻找成绩极值

三、代码与测试

小结

拓展:关于求极值的相关算法


Day 10:综合任务 1

Task:

        学生的成绩存放于一个矩阵,其中行表示学生,列表示科目。如:第 0 行表示第 0 个学生的数学、语文、英语成绩。要求:

        进行学生成绩的随机生成, 区间为 [50, 100].
        找出成绩最好、最差的同学。但有挂科的同学不参加评比.

  • 实际代码中,for 和 if 是最常见的, switch 和 while 使用少得多.
  • 使用了 continue, 它是指继续跳过本次循环后面的代码,直接进入下一次循环. 而 break 是跳出整个循环体.
  • 为了随机数,迫不得已提前使用了 new 语句生成对象.
  • 通过数据测试找出程序中的 bug.

 一、题目分析

1. 数据结构

        每个学生的科目都是三科,不会多不会少,因此多个学生之间的记录是定长记录,因此可以考虑使用固定的一个m*3二维数组来记录所有学生的成绩。此外,题目要求记录成绩最好和最差的同学,因此,可以考虑使用一个数组记录每个同学的成绩和,然后通过成绩统计最高成绩与最低成绩。

        注:就实现统计最好最差同学来说,这里的求和数组不是必要的,可以在设计学生成绩时就完成相关统计。因此代码是可以简化的,只是此处为了练习java代码内容故尽可能让数据结构完善。

2. 相关函数基本知识

1) Random.nextlnt()
        为避免问题模拟时考虑设置数据的麻烦,这里使用了数据数生成的基本方法。
        java提供了Random库,此库中包含了一些系列可用的随机数生成工具。今天我们将使用如下函数:

java Random.nextInt()方法
public int nextInt(int n)
        该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n

        有几个注意点是使用这个方法要注意的。

  • 此随机数的生成前闭后开的区间是,因此是无法生成n的
  • 此数据生成最低值是0,若要完成指定[a, b)的生成需要额外设计代码:a + temRandom.nextInt(b - a);
  • 数据是整型,不包含浮点(虽然成绩兼容浮点值,我们这暂时就整型来说明)

2)关于循环语句
        参考:【Java 专题补充】流程控制语句-CSDN博客

3)关于 continue 和 break
        参考: 【Java 专题补充】流程控制语句-CSDN博客

二、模块介绍

1. 初始化与成绩矩阵的构建

        初始化定义的上限不是100而是101是因为随机函数的右界是个开区间,因此要取满需要额外加一。
        此外,考虑到学生数量是不确定的,且考虑到成绩表的可扩展性,这里采用的是动态分配的方法创建矩阵。

// Step 1. Generate the date with n student and m course.
		// Set these value by yourself.
		int n = 10;
		int m = 3;
		int lowerBound = 50;
		int upperBound = 101;
		int threshold = 60;

		// Here we have to use an object to generate random numbers
		Random temRandom = new Random();
		int[][] data = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				data[i][j] = lowerBound + temRandom.nextInt(upperBound - lowerBound);
			} // Of for j
		} // Of for i

2. 创建总成绩数组

        创建总成绩数组。再次强调,这个数组不是必须的,此处是为了区分过程为了理清楚原理特别使用的一个存储空间。本质上可以通过成绩矩阵直接获得这一步的结果。
        当某个学生成绩低于及格线时,其总分无效,依据题意,这里令其总成绩为0。
        这里的0更多起了标记这个学生成绩无效的作用。

// Step 2.Compute the total score of each student.
		int[] totalScores = new int[n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (data[i][j] < threshold) {
					totalScores[i] = 0;
					break;
				} // Of if

				totalScores[i] += data[i][j];
			} // Of for j
		} // Of for i

3. 寻找成绩极值

分析代码如下:
        这里统计时将总分数为0(标记的不及格/通过)的学生跳过统计,符合题意要求
        这里使用了编程中常见得不能再常见的求极值方案——通过给预求极值设定一个反方向的最极限值(说人话就是给最大值设定一个能取的最小值为初始值,给最小值设定一个能取的最大值为初始值。这是一个求极值很常见的方法)
        这里能取的最小值就是0,最大值就是m * upperBound,因此只要保证最大值初始值小于等于0即可,最小值初始值大于等于m * upperBound即可。
        但是要说明,这个最值的含义只有在元素集的数目大于0才有意义。

// Step 3. Find the best and worst student.
		// Typical initialization for index: invalid value.
		int tempBestIndex = -1;
		int tempWorstIndex = -1;
		// Typical initialization for best and worst values.
		// They must be replaced by valid values.
		int tempBestScore = 0;
		int tempWorstScore = m * upperBound + 1;
		for (int i = 0; i < n; i++) {
			// Do not consider failed students.
			if (totalScores[i] == 0) {
				continue;
			} // Of if
			
			if (tempBestScore < totalScores[i]) {
				tempBestScore = totalScores[i];
				tempBestIndex = i;
			} // Of if

			// Attention: This if statememt cannot be combined with the last one
			// using "else if",because a student can be both the best and the
			// worst. I found this bug while setting upperBound = 65.
			if (tempWorstScore > totalScores[i]) {
				tempWorstScore = totalScores[i];
				tempWorstIndex = i;
			} // Of if
		} // Of for i

三、代码与测试

package basic;

import java.util.Arrays;
import java.util.Random;

/**
 * The usage of sth.
 *
 * @author: Changyang Hu joe03@foxmail.com
 * @date created: 2025-05-10
 */
public class Task1 {

	/**
	 * 
	 *********************
	 * @Title: main
	 * @Description: The entrance of the program.
	 *
	 * @param args Not used now.
	 * @return void 
	 *********************
	 */
	public static void main(String args[]) {
		task1();
	}// Of main

	/**
	 * 
	 *********************
	 * @Title: task1
	 * @Description: Method unit test.
	 * 
	 * @return void 
	 *********************
	 */
	public static void task1() {
		// Step 1. Generate the data with n student and m courses.
		// Set these values by yourself
		int n = 10;
		int m = 3;
		int lowerBound = 50;
		int upperBound = 101; // Should be 100. I use this value for testing
		int threshold = 60;

		// Here we have to use an object to generate random numbers.
		Random tempRandom = new Random();
		int[][] data = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				data[i][j] = lowerBound + tempRandom.nextInt(upperBound - lowerBound);
			} // Of for j
		} // Of for i

		System.out.println("The data is:\r\n" + Arrays.deepToString(data));

		// Step 2. Compute the total score of each student.
		int[] totalScores = new int[n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (data[i][j] < threshold) {
					totalScores[i] = 0;
					break;
				} // Of if

				totalScores[i] += data[i][j];
			} // Of for j
		} // Of for i

		System.out.println("The total scores are:\r\n" + Arrays.toString(totalScores));

		// Step 3. Find the best and worst student.
		// Typical initialization for index: invalid value.
		int tempBestIndex = -1;
		int tempWorstIndex = -1;
		// Typical initialization for best and worst value.
		// They must be replaced by valid values.
		int tempBestScore = 0;
		int tempWorstScore = m * upperBound + 1;
		for (int i = 0; i < n; i++) {
			// Do not consider failed students.
			if (totalScores[i] == 0) {
				continue;
			} // Of if

			if (tempBestScore < totalScores[i]) {
				tempBestScore = totalScores[i];
				tempBestIndex = i;
			} // Of if

			// Attention: This if statement cannot be combined with the last one
			// using "else if", because a student can be both the best and the
			// worst. I found this bug while setting upperBound = 65.
			if (tempWorstScore > totalScores[i]) {
				tempWorstScore = totalScores[i];
				tempWorstIndex = i;
			} // Of if
		} // Of for i

		// Step 4. Output the student number and score.
		if (tempBestIndex == -1) {
			System.out.println("Cannot find best student. ALL students have failed.");
		} else {
			System.out.println("The best student is No." + tempBestIndex + " with scores: "
					+ Arrays.toString(data[tempBestIndex]));
		} // Of if

		if (tempWorstIndex == -1) {
			System.out.println("Cannot find worst student. All students have failed.");
		} else {
			System.out.println("The worst student is No." + tempWorstIndex + " with scores: "
					+ Arrays.toString(data[tempWorstIndex]));
		} // Of if
	}// Of task1

}// Of class Task1

 第一次运行结果:upperBound = 101

在一次运行后数据如我们预期那样,对于不及格的学生,其总分是按照0处理的。
为了验证我们预先的特殊情况,我们先将随机生成的分数上限下调到66,让我们的分数随机数更容易落到不及格:upperBound = 66

可以发现,因为每个人存在不及格学科(由于是随机生成,所以也存在第一张图片所示,仍然有结果),因此大家总分都不及格,因此,这里大家的分数在比较时都跳过了,出现了“无最高分,无最低分”的人为规定条件。 


小结

        本篇展示了数据处理中很多比较常见的方法,包括总分求和、极值的计算与分析等。要注意的点就是灵活对于数据进行分析,合理利用数据结构即可,属于是基础的表格数据的应用。
        但是引起我思考的是其中求极值的方法。本篇代码中我们使用的是一种给极值赋相反的极限值的一种无效赋值法,我提到了“ 数据集合元素要大于0时,极值才有意义 ”。

拓展:关于求极值的相关算法

        任何最大值最小值的含义都是在元素集大于0才有意义,这个不言而喻。
        也是因为这个原因,还有另一种设置初值的方案是——将第一个元素的值设定给初始极值,并由此衍生——只记录最大值的下标而不记录最大值本身,然后下标初始值为0(就是默认为第一个元素的值)。如果这么做了,我们设定的变量似乎就更少了呢,而且,对于随机存取的数组来说,下标的信息熵比元素本身要多***(知道极值下标的话,在知道数据顺序之余还能以O(1)速度立马知道数据,而只知道数据最大值本身的话,那也就知道数据本身而已了)***。
        但是事物要辩证看待,本代码使用的无效赋值方法其实可以让数据本身起到一种标签的作用,若比大小时候有特殊处理时(比如这里的0分不统计),通过判断极值是否有效也可以用以断定“ 是不是所有大小判断都已经跳过 ”这种极特殊情景。

        除此之外,一般常见的求极值的算法还有:三分、二元函数、退火求极值的方法。更详细的可以参考如下博文:
优化算法:一元与二元函数极值求解与退火方法-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

macOS 15.4.1 Chrome不能访问本地网络

前言 最近使用macmini m4&#xff0c;自带macOS15系统&#xff0c;对于开发者简直是一言难尽&#xff0c;Chrome浏览器的本地网络有bug&#xff0c;可以访问本机&#xff0c;但是不能访问路由器上的其他机器&#xff0c;路由器提供的页面也不能访问&#xff0c;如下是折腾解决…

【Hive入门】Hive增量数据导入:基于Sqoop的关系型数据库同步方案深度解析

目录 引言 1 增量数据导入概述 1.1 增量同步与全量同步对比 1.2 增量同步技术选型矩阵 2 Sqoop增量导入原理剖析 2.1 Sqoop架构设计 2.2 增量同步核心机制 3 Sqoop增量模式详解 3.1 append模式&#xff08;基于自增ID&#xff09; 3.2 lastmodified模式&#xff08;基…

Dify使用总结

最近完成了一个Dify的项目简单进行总结下搭建服务按照官方文档操作就行就不写了。 进入首页之后由以下组成&#xff1a; 探索、工作室、知识库、工具 探索&#xff1a; 可以展示自己创建的所有应用&#xff0c;一个应用就是一个APP&#xff0c;可以进行测试使用 工作室包含…

MATLAB导出和导入Excel文件表格数据并处理

20250507 1.MATLAB使用table函数和writetable函数将数据导出Excel表格文件 我们以高斯函数为例子&#xff0c;高斯函数在数学和工程领域有着广泛的应用&#xff0c;它的一般形式为&#xff1a; 其中是均值&#xff0c;决定了函数的中心位置&#xff1b; 是标准差&#xff0c;决…

分书问题的递归枚举算法

分数问题的递归枚举算法 一、问题引入二、解题步骤1.问题分析思维导图2.解题步骤 三、代码实现1.代码2.复杂度分析 四、个人总结 一、问题引入 分书问题是指&#xff1a;已知 n 个人对 m 本书的喜好&#xff08;n≤m&#xff09;&#xff0c;现要将 m 本书分给 n 个人&#xf…

Unity WebGL、js发布交互

官网参考 Unity3D开发之WebGL平台上 unity和js前端通信交互 WebFun.jslib mergeInto(LibraryManager.library, {JSLog: function (str) { var strsUTF8ToString(str); Log(str); Log(strs);}, Hello: function () {var strs"Hello, world!"; Log(strs); Log(UTF8ToS…

Linux复习笔记(一)基础命令和操作

遇到的问题&#xff0c;都有解决方案&#xff0c;希望我的博客能为你提供一点帮助。 一、Linux中的基础命令和操作&#xff08;约30%-40%) 1.用户和组&#xff08;5%左右&#xff09; 1.1用户简介&#xff08;了解&#xff09; 要求&#xff1a;了解&#xff0c;知道有三个用户…

uniapp使用ui.request 请求流式输出

正文&#xff1a; 在现代Web开发中&#xff0c;实时数据流和长时间运行的请求变得越来越常见&#xff0c;尤其是在处理大量数据或进行实时通信时。在这种情况下&#xff0c;uniapp 提供的 ui.request 请求方法可以帮助我们轻松实现流式输出请求。本文将介绍如何使用 uni.reques…

20250506让NanoPi NEO core开发板使用Ubuntu core16.04系统的TF卡启动

1、h3-sd-friendlycore-xenial-4.14-armhf-20210618.img.gz 在WIN10下使用7-ZIP解压缩/ubuntu20.04下使用tar 2、Win32DiskImager.exe 写如32GB的TF卡。【以管理员身份运行】 3、TF卡如果已经做过会有3个磁盘分区&#xff0c;可以使用SD Card Formatter/SDCardFormatterv5_WinE…

快速上手 Docker:从入门到安装的简易指南(Mac、Windows、Ubuntu)

PS&#xff1a;笔者在五一刚回来一直搞Docker部署AI项目&#xff0c;发现从开发环境迁移到生成环境时&#xff0c;Docker非常好用。但真的有一定上手难度&#xff0c;推荐读者多自己尝试踩踩坑。 本篇幅有限&#xff0c;使用与修改另起篇幅。 一、Docker是什么 #1. Docker是什…

MySQL + Elasticsearch:为什么要使用ES,使用场景与架构设计详解

MySQL Elasticsearch&#xff1a;为什么要使用ES&#xff0c;使用场景与架构设计详解 前言一、MySQL Elasticsearch的背景与需求1.1 为什么要使用Elasticsearch&#xff08;ES&#xff09;&#xff1f;1.2 为什么MySQL在某些场景下不足以满足需求&#xff1f;1.3 MySQL Elas…

从投入产出、效率、上手难易度等角度综合对比 pytest 和 unittest 框架

对于选择python作为测试脚本开发的同学来说&#xff0c;pytest和python unittest是必需了解的两个框架。那么他们有什么区别&#xff1f;我们该怎么选&#xff1f;让我们一起来了解一下吧&#xff01; 我们从投入产出、效率、上手难易度等角度综合对比 pytest 和 unittest 框架…

关于汇编语言与程序设计——单总线温度采集与显示的应用

一、实验要求 (1)握码管的使用方式 (2)掌握DS18B20温度传感器的工作原理 (3)掌握单总线通信方式实现 MCU与DS18B20数据传输 二、设计思路 1.整体思路 通过编写数码管显示程序和单总线温度采集程序&#xff0c;结合温度传感报警&#xff0c;利用手指触碰传感器&#xff0c;当…

spring中的@Inject注解详情

在 Spring 框架中&#xff0c;Inject 是 Java 依赖注入标准&#xff08;JSR-330&#xff09; 的核心注解&#xff0c;与 Spring 原生的 Autowired 类似&#xff0c;但具备更标准化的跨框架特性。以下从功能特性、使用场景及与 Spring 原生注解的对比进行详细解析&#xff1a; 一…

Vue基础(8)_监视属性、深度监视、监视的简写形式

监视属性(watch)&#xff1a; 1.当被监视的属性变化时&#xff0c;回调函数(handler)自动调用&#xff0c;进行相关操作。 2.监视的属性必须存在&#xff0c;才能进行监视&#xff01;&#xff01; 3.监视的两种写法&#xff1a; (1).new Vue时传入watch配置 (2).通过vm.$watc…

TCP IP

TCP/IP 通信协议&#xff0c;不是单一协议&#xff0c;是一组协议的集合 TCP IP UDP 1.建立链接 三次握手 第一步&#xff1a;客户端发送一个FIN报文&#xff0c;SEQX,等待服务器回应 第二步&#xff1a;服务器端受到&#xff0c;发送ackx1,seqy, 等待客户端回应 第三步&am…

(四)毛子整洁架构(Presentation层/Authentiacation/Authorization)

文章目录 项目地址一、Presentation 层1.1 数据库migration1. 添加数据库连接字符串2. 创建自动Migration/Seed3.修改Entity添加private 构造函数4. 执行迁移 1.2 全局错误处理中间件1.3 Controller 添加1. Apartments2. Bookings3. 测试 二、Authentiacation2.1 添加Keycloak服…

K8S服务的请求访问转发原理

开启 K8s 服务异常排障过程前&#xff0c;须对 K8s 服务的访问路径有一个全面的了解&#xff0c;下面我们先介绍目前常用的 K8s 服务访问方式&#xff08;不同云原生平台实现方式可能基于部署方案、性能优化等情况会存在一些差异&#xff0c;但是如要运维 K8s 服务&#xff0c;…

20250510解决NanoPi NEO core开发板在Ubuntu core22.04.3系统下适配移远的4G模块EC200A-CN的问题

1、h3-eflasher-friendlycore-jammy-4.14-armhf-20250402.img.gz 在WIN10下使用7-ZIP解压缩/ubuntu20.04下使用tar 2、Win32DiskImager.exe 写如32GB的TF卡。【以管理员身份运行】 3、TF卡如果已经做过会有3个磁盘分区&#xff0c;可以使用SD Card Formatter/SDCardFormatterv5…

Linux系统之----模拟实现shell

在前面一个阶段的学习中&#xff0c;我们已经学习了环境变量、进程控制等等一系列知识&#xff0c;也许有人会问&#xff0c;学这个东西有啥用&#xff1f;那么&#xff0c;今天我就和大家一起综合运用一下这些知识&#xff0c;模拟实现下shell&#xff01; 首先我们来看一看我…