【日撸 Java 三百行】综合任务 1

news2025/5/11 12:03:43

目录

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/2373097.html

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

相关文章

华为私有协议Hybrid

实验top图 理论环节 1. 基本概念 Hybrid接口&#xff1a; 支持同时处理多个VLAN流量&#xff0c;且能针对不同VLAN配置是否携带标签&#xff08;Tagged/Untagged&#xff09;。 核心特性&#xff1a; 灵活控制数据帧的标签处理方式&#xff0c;适用于复杂网络场景。 2. 工作…

数据库实验10

设计性实验 1&#xff0e;实验要求 1.编写函数FsumXXX&#xff0c;1~n&#xff08;参数&#xff09;求和&#xff1b; GO CREATE FUNCTION Fsum065 (n INT) RETURNS INT AS BEGIN DECLARE sum INT 0 WHILE n > 0 BEGIN SET sum sum n SET n n - 1 END RETURN sum END …

jflash下载时出现 Could not read unit serial number! 的解决方法

出现的原因是由于Jlink原厂固件SN码是-1 我用的版本是v6.40 解决方法&#xff1a;添加序列号 1.打开&#xff1a;J-Link commander 之后在命令栏输入&#xff1a;exec setsnxxxxxxxx 2.添加序列号到license&#xff0c;打开J-Link License Manager V6.40 jlink-v640下载软件…

Linux 信号终篇(总结)

前文&#xff1a;本文是对信号从产生到被处理的过程中的概念和原理的总结&#xff0c;如果想了解具体实现&#xff0c;请查看前两篇博客&#xff1a;Linux 信号-CSDN博客、Linux 信号&#xff08;下篇&#xff09;-CSDN博客 一、信号的产生 1.1 信号产生的五种条件 ①键盘组…

LVGL对象(Objects)

文章目录 &#x1f9f1; 一、LVGL 中的对象&#xff08;lv\_obj&#xff09;&#x1f539; lv\_obj\_t 的作用 &#x1f9e9; 二、对象的分类结构&#xff08;类比继承&#xff09;&#x1f9f0; 三、对象的创建与销毁✅ 创建对象示例&#xff1a;创建一个按钮❌ 删除对象 &…

服务器配置错误导致SSL/TLS出现安全漏洞,如何进行排查?

SSL/TLS 安全漏洞排查与修复指南 一、常见配置错误类型‌ 弱加密算法与密钥问题‌ 使用弱密码套件&#xff08;如DES、RC4&#xff09;或密钥长度不足&#xff08;如RSA密钥长度<2048位&#xff09;&#xff0c;导致加密强度不足。 密钥管理不当&#xff08;如私钥未加密存…

路由重发布

路由重发布 实验目标&#xff1a; 掌握路由重发布的配置方法和技巧&#xff1b; 掌握通过路由重发布方式实现网络的连通性&#xff1b; 熟悉route-pt路由器的使用方法&#xff1b; 实验背景&#xff1a;假设学校的某个分区需要配置简单的rip协议路由信息&#xff0c;而主校…

C++修炼:stack和queue

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞&#xff0c;关注&am…

【计算机视觉】优化MVSNet可微分代价体以提高深度估计精度的关键技术

优化MVSNet可微分代价体以提高深度估计精度的关键技术 1. 代价体基础理论与分析1.1 标准代价体构建1.2 关键问题诊断 2. 特征表示优化2.1 多尺度特征融合2.2 注意力增强匹配 3. 代价体构建优化3.1 自适应深度假设采样3.2 可微分聚合操作改进 4. 正则化与优化策略4.1 多尺度代价…

软考错题集

一个有向图具有拓扑排序序列&#xff0c;则该图的邻接矩阵必定为&#xff08;&#xff09;矩阵。 A.三角 B.一般 C.对称 D.稀疏矩阵的下三角或上三角部分包含非零元素&#xff0c;而其余部分为零。一般矩阵这个术语太过宽泛&#xff0c;不具体指向任何特定性 质的矩阵。对称矩阵…

T2I-R1:通过语义级与图像 token 级协同链式思维强化图像生成

文章目录 速览摘要1 引言2 相关工作统一生成与理解的 LMM(Unified Generation and Understanding LMM.)用于大型推理模型的强化学习(Reinforcement Learning for Large Reasoning Models.)3 方法3.1 预备知识3.2 语义级与令牌级 CoT语义级 CoT(Semantic-level CoT)令牌级…

Dockers部署oscarfonts/geoserver镜像的Geoserver

Dockers部署oscarfonts/geoserver镜像的Geoserver 说实话&#xff0c;最后发现要选择合适的Geoserver镜像才是关键&#xff0c;所以所以所以…&#x1f437; 推荐oscarfonts/geoserver的镜像&#xff01; 一开始用kartoza/geoserver镜像一直提示内存不足&#xff0c;不过还好…

扩增子分析|微生物生态网络稳定性评估之鲁棒性(Robustness)和易损性(Vulnerability)在R中实现

一、引言 周集中老师团队于2021年在Nature climate change发表的文章&#xff0c;阐述了网络稳定性评估的原理算法&#xff0c;并提供了完整的代码。自此对微生物生态网络的评估具有更全面的指标&#xff0c;自此网络稳定性的评估广受大家欢迎。本系列将介绍网络稳定性之鲁棒性…

【含文档+PPT+源码】基于微信小程序的社区便民防诈宣传系统设计与实现

项目介绍 本课程演示的是一款基于微信小程序的社区便民防诈宣传系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套…

【MySQL】存储引擎 - ARCHIVE、BLACKHOLE、MERGE详解

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

代码随想录第41天:图论2(岛屿系列)

一、岛屿数量&#xff08;Kamacoder 99&#xff09; 深度优先搜索&#xff1a; # 定义四个方向&#xff1a;右、下、左、上&#xff0c;用于 DFS 中四向遍历 direction [[0, 1], [1, 0], [0, -1], [-1, 0]]def dfs(grid, visited, x, y):"""对一块陆地进行深度…

VUE CLI - 使用VUE脚手架创建前端项目工程

前言 前端从这里开始&#xff0c;本文将介绍如何使用VUE脚手架创建前端工程项目 1.预准备&#xff08;编辑器和管理器&#xff09; 编辑器&#xff1a;推荐使用Vscode&#xff0c;WebStorm&#xff0c;或者Hbuilder&#xff08;适合刚开始练手使用&#xff09;&#xff0c;个…

Java EE初阶——初识多线程

1. 认识线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 基本概念&#xff1a;一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff0c;如内存空间、文件描述符等&#xff0c;但每个线程都有自己独…

如何删除网上下载的资源后面的文字

这是我在爱给网上下载的音效资源&#xff0c;但是发现资源后面跟了一大段无关紧要的文本&#xff0c;但是修改资源名称后还是有。解决办法是打开属性然后删掉资源的标签即可。

FPGA图像处理(5)------ 图片水平镜像

利用bram形成双缓冲&#xff0c;如下图配置所示&#xff1a; wr_flag 表明 buffer0写 还是 buffer1写 rd_flag 表明 buffer0读 还是 buffer1读 通过写入逻辑控制(结合wr_finish) 写哪个buffer &#xff1b;写地址 进而控制ip的写使能 通过状态缓存来跳转buffer的…