Java程序设计实验2 | Java语言基础(1)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
*本文是博主对Java各种实验的再整理与详解除了代码部分和解析部分一些题目还增加了拓展部分⭐。拓展部分不是实验报告中原有的内容而是博主本人自己的补充以方便大家额外学习、参考。
目录
1分别用do-while和for循环计算1+1/2!-1/3!+1/4!-1/5!…的前20项之和。
2实现会员注册要求用户名长度不小于3密码长度不小于6若不满足需有提示信息提示输入有误注册时两次输入密码必须相同字符串
3找出两个分教最高的学生编写程序提示输入学生的个数、每个学生的名字及其分数最后显示获得最高分的学生和第二高分的学生
4定义一维数组并初始化通过键盘任意输入一个数查找该数是否存在结果返回下标值
5编写一个程序将二维数组a转置后存入数组b所谓转置就是行列互换
一、实验目的
1、掌握变量的命名是否符合Java关于标识符的命名规则。
2、掌握8种基本数据类型和3种类型转换的方法。
3、熟悉各种运算符的优先级和结合方向。
4、掌握控制结构的3种语句。
5、掌握Java输入数据的基本方法Scanner。
6、掌握方法的定义、调用格式理解方法调用和参数传递的原理掌握方法的重载理解方法的递归调用。
7、掌握数组的定义、动态和静态初始化格式数组的遍历和应用Array工具类的使用。
二、实验内容
1、实验题目基本语法
1求任意输入的10个数的和。
源代码
常规方式for循环输入并求和。该题逻辑非常基础不作过多说明。对于Scanner不了解的同学可以查看该文档Scanner
import java.util.Scanner;
public class S2_1_1 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in); //创建Scanner对象
int sum = 0;
for(int i = 1; i <= 10; i++) { //连续输入10个数
System.out.println("请输入第"+i+"个数");
int n = reader.nextInt();
sum += n; //累加求和
}
reader.close(); //记得关闭
System.out.println(sum);
}
}
列出测试数据和实验结果截图
2实验题目获取三个整数中的最大值用三元运算符
源代码
代码1直接使用三目运算符。
import java.util.Scanner;
public class S2_1_2 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int a = reader.nextInt();
int b = reader.nextInt();
int c = reader.nextInt();
int temp = (a > b) ? a : b;
//若a大于b则三目运算符表达式值为a否则为b
int max = (temp > c) ? temp : c;
//若temp大于c则三目运算符表达式值为temp否则为c
System.out.println("max = " + max);
}
}
代码2将求最大值的程序封装成方法通过调用方法获取最大值。
import java.util.Scanner;
public class S2_1_2 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int a = reader.nextInt();
int b = reader.nextInt();
int c = reader.nextInt();
int temp = max(a,b); //调用方法
int max = max(temp,c);
System.out.println("max = " + max);
}
public static int max(int x, int y){
return x > y ? x : y;
}
}
列出测试数据和实验结果截图
⭐拓展-通过泛型类获取任意类型的三个数的最大值
提问如果想要比较的对象不仅是整数而是任意的基本数据类型那该怎么办呢
当然我们可以采用方法重载枚举多种情况、写多个方法。但这样依旧有些费劲毕竟光是可以比较的数值类型就有7种更何况可能还需要比较自定义类型。这时我们可以借助泛型来实现。详解部分可以查阅下面这篇文章
🔗Java初识泛型 | 如何通过泛型类/泛型方法获取任意类型的三个数的最大值
2、实验题目选择结构的应用
1键盘录入月份的值输出对应的季节
源代码
用switch或if来进行分支判断都是简便且可行的这里给出用if实现的代码。
import java.util.Scanner ;
public class S2_2_1 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in) ;
System.out.println("请输入一个月份的值:") ;
int month = sc.nextInt() ;
if(month > 12 || month < 1){
System.out.println("您输入的月份不合法") ;
}else if(month >= 3 && month <= 5){
System.out.println("春季") ;
}else if(month >= 6 && month <= 8){
System.out.println("夏季") ;
}else if(month >= 9 && month <= 11){
System.out.println("秋季") ;
}else{
System.out.println("冬季") ;
}
}
}
列出测试数据和实验结果截图
2输入年份和月份输出该年月的天数
import java.util.Scanner;
public class S2_2_2 {
public static void main(String[] args){
Scanner s =new Scanner (System.in);
System.out.println("请输入年份:");
int year= s.nextInt();
System.out.println("请输入月份:");
int month= s.nextInt();
int day = 0;
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
if(year%4 == 0 && year%100 != 0 || year%400==0){
day=29;
}else{
day=28;
}
break;
}
System.out.println(year+"年"+month+"月有"+day+"天");
}
}
⭐拓展-输入年、月、日输出这天是该年的第几天
我们写分支结构时当发现既可以使用switch-case同时switch中表达式的取值情况不太多又可以使用if-else时我们可以优先选择使用switch-case因为switch-case的执行效率稍高。
import java.util.Scanner;
public class YearDayTest {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入year");
int year = reader.nextInt();
System.out.println("请输入month");
int month = reader.nextInt();
System.out.println("请输入day");
int day = reader.nextInt();
//定义一个变量来保存天数
int sumDays = 0;
//不加break达到逐月累加的效果
switch(month) {
case 12:
sumDays += 30; //加的是上个月也就是11月的天数
case 11:
sumDays += 31;
case 10:
sumDays += 30;
case 9:
sumDays += 31;
case 8:
sumDays += 31;
case 7:
sumDays += 30;
case 6:
sumDays += 31;
case 5:
sumDays += 30;
case 4:
sumDays += 31;
case 3:
if(year%4 == 0 && year%100 != 0 || year%400==0){
sumDays += 29;
}else{
sumDays += 28;
}
case 2:
sumDays += 31;
case 1:
sumDays += day; //最后加上当月的天数
}
System.out.println(year + "年" + month + "月" + day + "日是当年的第" + sumDays + "天" );
}
}
3出租车计费问题
• KF市的出租车计费方式为起步2公里内5元2公里以上每公里收费1.3元9公里以上每公里收费2元燃油附加费1元。
• 编写程序输入公里数计算出所需的出租车费用。
源代码
import java.util.Scanner;
public class S2_2_3 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
double price = 0.0;
System.out.println("请输入里程数");
double mile = reader.nextDouble();
if(mile <= 2 && mile > 0){
price = 5;
} else if (mile > 2 && mile <= 9) {
price = (mile-2) * 1.3 + 5;
} else if (mile > 9) {
price = 5 + 7 * 1.3 + (mile-9) * 2 + 1;
}
System.out.println("价格为" + price + "元。");
}
}
列出测试数据和实验结果截图
3、实验题目循环结构的应用
1分别用do-while和for循环计算1+1/2!-1/3!+1/4!-1/5!…的前20项之和。
本题是基础的累加、阶乘的运用。较为基础故不多作说明。
源代码
for循环实现
public class S2_3_1 {
public static void main(String[] args) {
double sum = 0;
double fact = 1;
for(int i = 1; i <= 20; i++){
fact *= i; //求每项中的阶乘
sum += 1/fact; //将各项累加
}
System.out.println(sum);
}
}
do-while循环实现
public class S2_3_1 {
public static void main(String[] args) {
double sum = 0;
double fact = 1;
int i = 1;
do {
fact *= i++;
sum += 1/fact;
}while(i <= 20);
System.out.println(sum);
}
}
列出测试数据和实验结果截图
2求1000以内的完全数一个数等于它的因子之和称为完全数
通过试除法找到数n所有的因子并相加最后作判断即可。
源代码
public class S2_3_2 {
//判断是否是完全数的方法
public static boolean isPerfectNumber(int n){
//一个数等于它的因子之和称为完全数
int sum = 0; //用于记录因子之和
for(int i = 1; i <= n/2; i++){ //试除法寻找因子
if(n%i == 0){
sum += i; //此处i即n的因子
}
}
//比较因子之和与这个数本身是否相等
if(sum == n){
return true;
}else{
return false;
}
}
public static void main(String[] args) {
for(int n = 6; n <= 1000; n++){
if(isPerfectNumber(n)){
System.out.println(n);
}
}
}
}
3微信中的一个拿鸡蛋问题
一筐鸡蛋1个1个拿正好拿完。
2个2个拿还剩1个。
3个3个拿正好拿完。
4个4个拿还剩1个。
5个5个拿还差1个。
6个6个拿还剩3个。
7个7个拿正好拿完。
8个8个拿还剩1个。
9个9个拿正好拿完。
问筐里最少有多少鸡蛋
这个问题非常简单但必须注意细节5个5个拿时是还“差”一个而不是还“剩”一个。假设有4个鸡蛋那么此时5个5个拿就是还差一个的情景。因此此时的鸡蛋数加上差的1个恰好是5的倍数。
源代码
public class S2_3_3 {
public static void main(String[] args) {
int i = 0;
while(true) {
i++;
if(i%2==1 && i%3==0 && i%4==1 && (i+1)%5==0 && i%6==3 && i%7==0 && i%8==1 && i%9==0){
System.out.println(i);
break;
}
}
}
}
列出测试数据和实验结果截图
5、实验题目课后作业题
1求六边形面积六边形面积可以通过下面公式计算s是边长)
注使用Math类中的方法计算tan值。
2实现会员注册要求用户名长度不小于3密码长度不小于6若不满足需有提示信息提示输入有误注册时两次输入密码必须相同字符串
本题的关键是字符串的输入与两个字符串之间的比较方法equals的运用。注意若要求忽略大小写比较则用到equalsIgnoreCase()方法。
源代码
import java.util.Scanner;
public class S2_5_2 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入用户名");
String userName = reader.next();
while(userName.length() < 3) {
System.out.println("用户名长度不可小于3请重新输入");
userName = reader.next();
}
System.out.println("请输入密码");
String password = reader.next();
while(password.length() < 6) {
System.out.println("密码长度不可小于6请重新输入");
password = reader.next();
}
System.out.println("请确认密码");
String confirmPassword = reader.next();
if(confirmPassword.equals(password)) {
System.out.println("注册成功");
}else {
System.out.println("两次密码不一致");
}
}
}
列出测试数据和实验结果截图
3找出两个分教最高的学生编写程序提示输入学生的个数、每个学生的名字及其分数最后显示获得最高分的学生和第二高分的学生
方法一直接求解
该代码没有用到面向对象的思想编程思路是分别创建两个数组分数数组与姓名数组进行分开存储。通过排序代码以分数为标准对姓名数组进行排序最后输出前两项的姓名。
源代码
import java.util.Scanner;
public class S2_5_3 {
public static void main(String[] args) {
Scanner reader=new Scanner(System.in);
System.out.println("请输入学生个数");
int num = reader.nextInt();
//创建分数数组和姓名数组进行分开存储
int[] score = new int[num];
String[] name = new String[num];
for(int i=0;i<num;i++)
{
System.out.println("请输入第"+(i+1)+"个学生的名字");
name[i]= reader.next();
System.out.println("请输入第"+(i+1)+"个学生的成绩");
score[i]=reader.nextInt();
}
//直接选择排序
for(int i=0;i<num;i++)
{
for(int j=i+1;j<num;j++)
{
if(score[i]<score[j])
{
String tmp = name[i];
name[i] = name[j];
name[j] = tmp;
}
}
}
System.out.println("第一名为:"+name[0]+"。第二名为:"+name[1]);
}
}
列出测试数据和实验结果截图
方法二面向对象
该方法是上一种方式的优化核心思路是实现Student类创建Student数组并通过直接对Student数组排序的方式最高分的Student对象与第二高分的Student对象。
注意由于数组排序的过程中设计对象的比较因此需要重写compareTo()方法才能进行Student数组的排序。
源代码
import java.util.Arrays;
import java.util.Scanner;
public class S2_5_3 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入学生的个数");
int num = reader.nextInt();
Student[] students = new Student[num];
System.out.println("请依次输入学生的姓名与分数");
for (int i = 0; i < students.length; i++){
System.out.println("学生"+(i+1));
String namei = reader.next(); //① 注意写成.next()和.nextLine()在此有区别
int scorei = reader.nextInt(); //②
students[i] = new Student(namei,scorei); //③
}
Arrays.sort(students); //④
System.out.println("获得最高分的学生是" + students[0]);
System.out.println("获得第二高分的学生是" + students[1]);
}
}
class Student implements Comparable<Student>{ //⑤
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
//重写compareTo方法以数组排序
@Override
public int compareTo(Student o) {
return o.score-this.score;
}
//重写toString方法以打印对象
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
代码详解
- 注释①处写成.next()和.nextLine()在此是有区别的。正确的方式应当是写成reader.next(); 一方面.next()不会因为获取到上一个输入遗留下来的换行空白符而停止读取另一方面在用户实际输入的时候既可以将“姓名”和“分数”用换行隔开也可以用空格等非换行符隔开。若写成.nextLine()。则会有上面的两个问题会抛出InputMismatchException
- ③处代码是创建新的Student对象。注意在创建Student数组的时候并没有实例化Student对象。数组没有初始化因此Student数组内均为null。通过构造方法给Student对象的name和score赋值并实例化数组中的元素。
- ④直接调用Arrays中的方法sort给数组中的元素进行排序。注意该数组是引用类型要实现排序必须重写Comparable或Comparator接口并重写相应的比较方法也就是指定比较的规则。
- ⑤处实现了Comparable接口。
列出测试数据和实验结果截图
4定义一维数组并初始化通过键盘任意输入一个数查找该数是否存在结果返回下标值
源代码
import java.util.Arrays;
import java.util.Scanner;
public class S2_5_44 {
public static void main(String[] args) {
Scanner reader=new Scanner(System.in);
int[] array={0,1,2,3,4,5,6,7,8,9};
System.out.println("数组为");
System.out.println(Arrays.toString(array));
System.out.println("请输入一个数");
int num = reader.nextInt();
int i = 0;
for(; i < array.length; i++)
{
if(num == array[i])
{
break;
}
}
if(i < array.length){
System.out.println("该数存在,下标为" + i);
}else{
System.out.println("没有找到");
}
}
}
列出测试数据和实验结果截图
5编写一个程序将二维数组a转置后存入数组b所谓转置就是行列互换
例如
源代码
import java.util.Arrays;
import java.util.Scanner;
public class S2_5_5 {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.println("请输入数组的行数n与列数m");
int n = reader.nextInt();
int m = reader.nextInt();
int[][] src = new int[n][m];
int[][] dst = new int[m][n];
System.out.printf("请输入一个%d*%d的数组\n",n,m);
for(int i = 0; i < src.length;i++)
{
for(int j = 0; j < src[i].length; j++)
{
src[i][j] = reader.nextInt();
}
}
for(int i = 0; i < dst.length; i++)
{
for(int j = 0; j < dst[i].length; j++)
{
dst[i][j] = src[j][i];
}
}
System.out.println("转制后的二位数组为");
//System.out.println(Arrays.deepToString(dst));
for(int i = 0; i < dst.length; i++)
{
for(int j = 0; j < dst[i].length; j++)
{
System.out.print(dst[i][j] + " ");
}
System.out.println();
}
}
}
列出测试数据和实验结果截图
三、实验总结
- 完成上述实验我更熟地掌握了Java的基础语法包括
- Java关于标识符的命名规则Java标识符可以字母、数字、下划线和美元符构成且数字不能开头。类名用大驼峰变量名、方法名用小驼峰。
- 掌握了8种基本数据类型intbyteshortcharlongfloatdoubleBoolean的使用情况和相应的类型转换方法。
- 我熟悉了各种运算符包括自增、自减、三目运算符等的优先级和结合方向。
- 我掌握了控制结构的3种语句包括if、switch选择语句、while、do-while、for、for-in循环语句。
- 我掌握了Java输入数据的基本方法Scanner。我可以熟练地通过调用Scanner对象输入各种数据类型的数据进行编程。
- 我掌握了方法的定义和调用格式能正确写出Java定义方法的语法。也理解了方法调用和参数传递的原理包括值传递和址传递。
- 我掌握了方法的重载重载的条件是方法的名称必须相同参数列表必须不同返回值类型不做要求。
- 我也理解了方法的递归调用递归就是方法自己调用自己会在虚拟机栈中建立栈帧。
-
在与数组相关的实验中我掌握了数组的定义、动态和静态初始化格式。我能通过for循环对一维数组和二维数组进行遍历能完成数组的转置、数组的排序构建引用类型的数组。也可以熟练通过Array工具类直接调用Arrays中的方法进行数组排序和逆序。
- 在编程中我没有遇到难以解决的问题。遇到唯一的问题是在求完数时本来需要对一个数进行试除然后计算该数的所有因子之和。我在for循环判断试除因子范围时将i的界限写成了i <=Math.sqrt(n)但输出结果有误什么也没输出。通过调试后来我将i 改为 i <= n/2就能正确输出结果了。这是因为我一开始没有意识到因子有对称性这个特点。
- 最后通过实验我对基础算法进行了很好的复习。