南昌航空大学-21207132-张瑞彬-JAVA第一次Blog作业

发布时间 2023-10-06 22:22:22作者: 前有CV

前言:

       本学期第一次接触JAVA,也是我学习的第一门面向对象语言。相比于面向过程,我认为面向对象对框架结构的要求更高,提前处理好各个对象以及它们之间的联系可以让代码的编写事半功倍。在第一堂JAVA课上老师就对我们说“务必在写代码之前设计好类图”,我没有贯彻这一点(悲),在第三次题目集的第二题吃了大亏,后面细嗦。

       第一次题目集没什么好说的,全部是一些简单的语法题,基本不涉及算法,注意一下浮点误差就好,输出在这一点上做了限制。第二次题目集则放入了两道相对有难度的题目,我想大多数同学应该也是在这里第一次明显感受到面向过程和面向对象之间的差异。第三次作业可以说是给了我当头一棒,建议不要参考我的代码,第二题作为一道高难度大题分值有足足65分,我只过了20分的测试点,从通过率上看大伙应该也是感同身受的。


 

题目集1:

7-1 身体质量指数(BMI)测算

体重是反映和衡量一个人健康状况的重要标志之一,过胖和过瘦都不利于健康,BMI(身体质量指数)计算方法:体重(以千克为单位)除以身高(以米为单位)的平方。中国成人正常的BMI应在18.5-24之间,如果小于18.5为体重不足,如果大于等于24为超重,大于等于28为肥胖。请编写程序,测算身体状态。

输入格式:

两个数值:体重(以千克为单位),身高(以米为单位),数值间以空格分隔。例如:65.5 1.75。
注意:体重的世界纪录是727公斤,身高的世界纪录是2.72米。输入数据上限不得超过纪录,下限不得小于等于0;

输出格式:

输入数值超出范围 :输出“input out of range”。例如:-2 3或者125 5。
BMI小于18.5 :输出“thin”。
BMI大于等于18.5小于24 :输出“fit”。
BMI大于等于24小于28 :输出“overweight”。
BMII大于等于28 :输出“fat”。

输入样例0:

在这里给出一组输入。例如:

-2  8

输出样例0:

在这里给出相应的输出。例如:

input out of range

输入样例1:

在这里给出一组输入。例如:

70 1.75

输出样例1:

在这里给出相应的输出。例如:

fit
代码长度限制
20 KB
时间限制
400 ms
内存限制
64 MB
 
套公式就可以了,注意输出是float类型
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
       double weight,hight,BMS;
        Scanner input = new Scanner(System.in);
        weight=input.nextDouble();
        hight= input.nextDouble();
        System.out.printf((float)weight/0.45359237+" "+(float)hight/0.0254);
    }
}

7-2 长度质量计量单位换算

两个浮点数,以空格分隔,第一个是质量(以千克为单位)、第二个是长度(以米为单位)。例如:0.45359237 0.0254。

输出格式:

两个浮点数,以空格分隔,第一个是质量(以磅为单位)、第二个是长度(以英寸为单位)。例如:1.0 1.0。

输入样例:

在这里给出一组输入。例如:

0.45359237 0.0254

输出样例:

在这里给出相应的输出。例如:

1.0 1.0
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
       double weight,hight;
        Scanner input = new Scanner(System.in);
        weight=input.nextDouble()/0.45359237;
        hight= input.nextDouble()/0.0254;
        System.out.printf((float)weight+" "+(float)hight);
    }
}

7-3 NCHU_奇数求和

计算一个数列中所有奇数的和。

输入格式:

十个整数,以空格分隔。例如:1 2 3 4 5 6 7 8 9 0。

输出格式:

输入数列中所有奇数之和。例如:25。

输入样例:

在这里给出一组输入。例如:

1 2 3 4 5 6 7 8 9 0

输出样例:

在这里给出相应的输出。例如:

25
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
 
注意一下负数的存在即可
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int res=0;
        for(int i=0;i<10;i++)
        {
            int num;
            num=input.nextInt();
            if(num%2==1||num%2==-1) res+=num;
        }
        System.out.print(res);
    }
}

7-4 NCHU_房产税费计算

 

房屋交易在日常生活中非常常见的事情,房屋交易时要额外支付各种税费,按2022年房产交易新政策的规定买房人应缴纳税费包括:

1、契税:首次购房评估额90平(含)内1%、90平-144平(含)内1.5%,超过144平或非首 次3%,买方缴纳。

2、印花税:房款的0.05%。

3、交易费:3元/平方米。

4、测绘费:1.36元/平方米。

5、权属登记费及取证费:一般情况是在200元内。

输入格式:

四个数据,以空格分隔:
1、第几次购房(整数)
2、房款(整数/单位万元)
3、评估价(整数/单位万元)
4、房屋面积(浮点数/单位平方米)。
例如:1 100 100 90。

输出格式:

契税、印花税、交易费、测绘费(以元为单位),以空格分隔。例如:10000.0 500.0 270.0 122.4

输入样例:

在这里给出一组输入。例如:

1 100 100 90

输出样例:

在这里给出相应的输出。例如:

10000.0 500.0 270.0 122.4
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        double ex;
        int count=input.nextInt();
        int cost=input.nextInt()*10000;
        int estimate=input.nextInt()*10000;
        double s=input.nextDouble();
        if(count==1){
            if(s<=90) ex=estimate*0.01;
            else if(s<=144) ex=estimate*0.015;
            else ex=estimate*0.03;
        }
        else ex=estimate*0.03;
        double a=cost*0.0005,b=3*s,c=1.36*s;
        System.out.println((float)ex+" "+(float)a+" "+(float)b+" "+(float)c);
    }
}

7-5 游戏角色选择

import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        int a=input.nextInt();
        int b=input.nextInt();
        if(b!=1&&b!=2&&b!=3)
        {
            System.out.printf("Wrong Format");
            return;
        }
        if(a==1) System.out.printf("人类 ");
        else if(a==2) System.out.printf("精灵 ");
        else if(a==3) System.out.printf("兽人 ");
        else if(a==4) System.out.printf("暗精灵 ");
        else{
            System.out.printf("Wrong Format");
            return;
        }
        if(b==1) System.out.printf("战士");
        else if(b==2) System.out.printf("法师");
        else if(b==3) System.out.printf("射手");
        else{
            System.out.printf("Wrong Format");
            return;
        }
    }
}

7-6 NCHU_学号识别

 

学校的学号由8位数字组成,前两位是入学年份(省略了20);第3、4位是学院编号,01代表材料学院,02代表机械学院,03代表外语学院,20代表软件学院;第5、6位是学院内部班级编号,最后两位是班级内部学号。如:18011103,入学年份是2018年,材料学院,11班,03号

输入格式:

8位数字组成的学号。例如:18011103
注意:输入学号不是8位或者学院编号不是01、02、03、20其中之一,属于非法输入

输出格式:

学号每一项的完整说明。例如:
入学年份:2018年
学院:材料学院
班级:11
学号:03

注意:如非法输入,输出“Wrong Format"

输入样例:

在这里给出一组输入。例如:

18011103

输出样例:

在这里给出相应的输出。例如:

入学年份:2018年
学院:材料学院
班级:11
学号:03

输入样例1:

在这里给出一组输入。例如:

18013

输出样例1:

在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        String year,collage,cla,num;
        String s=input.next();
        if(s.length()!=8){
            System.out.printf("Wrong Format");
            return;
        }
        year=s.substring(0,2);
        collage=s.substring(2,4);
        cla=s.substring(4,6);
        num=s.substring(6,8);
        if(collage.equals("01")) collage="材料学院";
        else if(collage.equals("02")) collage="机械学院";
        else if(collage.equals("03")) collage="外语学院";
        else if(collage.equals("20")) collage="软件学院";
        else{
            System.out.printf("Wrong Format");
            return;
        }
        System.out.printf("入学年份:20"+year+"年\n"+"学院:"+collage+"\n"+"班级:"+cla+"\n"+"学号:"+num);
    }
}

7-8 NCHU_巴比伦法求平方根近似值

 

巴比伦法求n的近似值可以用以下公式:
nextGuess = (lastGuess+n/lastGuess)/2
程序初始运行时lastGuess可赋予一个最初的猜测值。当由公式求得的nextGuess和lastGuess相差较大时,把nextGuess的值赋给lastGuess,继续以上过程,直至nextGuess和lastGuess几乎相同,此时lastGuess或者nextGuess就是平方根的近似值。
本题要求:nextGuess和lastGuess的差值小于0.00001时认为两者几乎相同

输入格式:

1、两个浮点数,以空格分隔,第一个是n,第二个是lastGuess最初的猜测值。例如:2 1。
2、若输入的两个数中包含负数或者lastGuess初始输入为0,认定为非法输入

输出格式:

1、输出n的平方根近似值:lastGuess。例如:1.4142157
2、非法输入时输出:"Wrong Format"

输入样例:

在这里给出一组输入。例如:

2 1

输出样例:

在这里给出相应的输出。例如:

1.4142157

输入样例1:

在这里给出一组输入1。例如:

2 -1

输出样例:

在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        float n,last,next;
        n=input.nextFloat();
        if(n<=0){
            System.out.print("Wrong Format");
            return;
        }
        last= input.nextFloat();
        if(last<=0){
            System.out.print("Wrong Format");
            return;
        }
        next=(last+n/last)/2;
        while(Math.abs(next-last)>=0.00001)
        {
            last=next;
            next=(last+n/last)/2;
        }
        System.out.print(last);
    }
}

7-9 二进制数值提取

 

在一个字符串中提取出其中的二进制数值序列,。

输入格式:

一个由0、1构成的序列,以-1为结束符,非0、1字符视为正常输入,但忽略不计,未包含结束符的序列视为非法输入。例如:abc00aj014421-1

输出格式:

将输入的序列去掉非0、1字符以及结尾符的数据内容,
注:结束符-1之后的0\1字符忽略不计。
例如:00011。

输入样例:

在这里给出一组输入。例如:

abc00aj014421-1

输出样例:

在这里给出相应的输出。例如:

00011

输入样例1:

在这里给出一组输入。例如:

a0571-1k001y

输出样例1:

在这里给出相应的输出。例如:

01
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        String s,n="";
        s=input.nextLine();
        for(int i=0;i<s.length();i++)
        {
            if(s.charAt(i)=='0'||s.charAt(i)=='1') n+=s.charAt(i);
            if(s.charAt(i)=='-'&&s.charAt(i+1)=='1') {
                System.out.print(n);
                return;
            }
        }
        System.out.print("Wrong Format");
    }
}

7-7 判断三角形类型

输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。

输出格式:

(1)如果输入数据非法,则输出“Wrong Format”;
(2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”;
(3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”;
(3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”;
(5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”;
(6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”;
(7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。

输入样例1:

在这里给出一组输入。例如:

50 50 50.0

输出样例1:

在这里给出相应的输出。例如:

Equilateral triangle

输入样例2:

在这里给出一组输入。例如:

60.2 60.2 80.56

输出样例2:

在这里给出相应的输出。例如:

Isosceles triangle

输入样例3:

在这里给出一组输入。例如:

0.5 20.5 80

输出样例3:

在这里给出相应的输出。例如:

Wrong Format
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
import java.util.Arrays;
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input = new Scanner(System.in);
        float COS;
        float[] num=new float[3];
        num[0]= input.nextFloat();
        num[1]= input.nextFloat();
        num[2]= input.nextFloat();
        Arrays.sort(num);
        COS=(num[0]*num[0]+num[1]*num[1]-num[2]*num[2])/(2*num[0]*num[1]);
        if((1>num[0]||200<num[0])||(1>num[1]||200<num[1])||(1>num[2]||200<num[2]))
        {
            System.out.print("Wrong Format");
            return;
        }
        Arrays.sort(num);
        if((num[1]+num[0])<=num[2]){
            System.out.print("Not a triangle");
            return;
        }
        if(num[0]==num[1]&&num[1]==num[2])
        {
            System.out.print("Equilateral triangle");
            return;
        }
        if(num[0]*num[0]+num[1]*num[1]-num[2]*num[2]<=0.00001&&num[0]==num[1])
        {
            System.out.print("Isosceles right-angled triangle");
            return;
        }
        if(num[0]==num[1]||num[1]==num[2])
        {
            System.out.print("Isosceles triangle");
            return;
        }
        if(COS==0)
        {
            System.out.print("Right-angled triangle");
            return;
        }
        System.out.print("General triangle");
    }
}

这里要注意等腰直角三角形的判断条件,运用勾股定理的部分本应是a^2+b^2=c^2,但我写成了a^2+b^2-c^2<=0.00001,这里也是因为浮点误差,不这样写无法通过测试点


题目集2:

7-1 成绩计算-1-类、数组的基本运用

创建学生类,包含

属性:学号(String)、姓名(String)、语文成绩(int)、数学成绩(int)、物理成绩(int)

方法:计算总分、计算平均分

输入5个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出5个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

浮点数保留小数的相关知识可参考:
https://blog.csdn.net/huaishuming/article/details/17752365


注意:未用学生类对象封装数据的,本题计0分

输入格式:

5个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+语文成绩+英文空格+数学成绩+英文空格+物理成绩
例如:
22201311 张琳 80 80 80

22201312 黄昊 66 82 81

22201313 李少辰 77 76 80

22201314 袁婷 62 79 90

22201315 朱哲一 74 98 94

输出格式:

5个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分

例如:

22201311 张琳 240 80.00

22201312 黄昊 229 76.33

22201313 李少辰 233 77.67

22201314 袁婷 231 77.00

22201315 朱哲一 266 88.67

输入样例:

在这里给出一组输入。例如:

22201311 张琳 80 80 80
22201312 黄昊 66 82 81
22201313 李少辰 77 76 80
22201314 袁婷 62 79 90
22201315 朱哲一 74 98 94

输出样例:

在这里给出相应的输出。例如:

22201311 张琳 240 80.00
22201312 黄昊 229 76.33
22201313 李少辰 233 77.67
22201314 袁婷 231 77.00
22201315 朱哲一 266 88.67
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
一道公式题,题干给的网站值得一看

import java.text.DecimalFormat;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

Student[] student=new Student[5];
Scanner input=new Scanner(System.in);
for(int i=0;i<5;i++)
{ student[i]=new Student();
student[i].ID = input.next();
student[i].Name = input.next();
student[i].Chinese = input.nextInt();
student[i].MATH = input.nextInt();
student[i].Physic = input.nextInt();
System.out.print(student[i].ID+" "+student[i].Name+" "+student[i].getsum()+" "+student[i].getaverage()+"\n");
}
return;
}

}
class Student {
String Name;
String ID;
int Chinese;
int MATH;
int Physic;
public int getsum()
{
return this.Chinese+this.MATH+this.Physic;
}
public String getaverage()
{
float f= (float) this.getsum() /3;
DecimalFormat df = new DecimalFormat("#.00");
return df.format(f);
}
}


7-2 成绩计算-2-关联类

创建成绩类,包含:

属性:平时成绩(int)、期末成绩(int)

方法:计算总成绩(计算规则:平时成绩*0.4+期末成绩*0.6,保留整数部分,小数部分直接丢弃)

创建学生类,包含:

属性:学号(String)、姓名(String)、语文成绩(成绩类)、数学成绩(成绩类)、物理成绩(成绩类)

方法:计算总分、计算平均分

输入3个学生的信息,将每个学生的信息封装在一个学生对象中。

按输入顺序依次输出3个学生的总分、平均分(精确到小数点后两位,舍去部分按四舍五入规则计入最后一位)。

浮点数保留小数的相关知识可参考:https://blog.csdn.net/huaishuming/article/details/17752365


注意:未用学生类对象封装数据的,本题计0分

输入格式:

依次输入3个学生的每门课成绩,每个学生成绩信息格式:

学号+英文空格+姓名+英文空格+课程名+英文空格+平时成绩+英文空格+期末成绩
注:3个学生的课程顺序可能会不一致

例如:
22201311 张琳 语文 70 80

22201311 张琳 数学 85 89

22201311 张琳 物理 75 83

22201312 黄昊 语文 66 78

22201312 黄昊 数学 76 82

22201312 黄昊 物理 83 82

22201313 李少辰 语文 86 76

22201313 李少辰 数学 78 76

22201313 李少辰 物理 87 76

输出格式:

3个学生信息,每个学生信息格式:

学号+英文空格+姓名+英文空格+总成绩+英文空格+平均分

例如:


22201311 张琳 242 80.67

22201312 黄昊 234 78.00

22201313 李少辰 236 78.67

输入样例:

在这里给出一组输入。例如:

22201311 张琳 语文 70 80
22201311 张琳 数学 85 89
22201311 张琳 物理 75 83
22201312 黄昊 语文 66 78
22201312 黄昊 数学 76 82
22201312 黄昊 物理 83 82
22201313 李少辰 语文 86 76
22201313 李少辰 数学 78 76
22201313 李少辰 物理 87 76

输出样例:

在这里给出相应的输出。例如:

22201311 张琳 242 76.67 84.00 80.67
22201312 黄昊 234 75.00 80.67 78.00
22201313 李少辰 236 83.67 76.00 78.67
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
写这道题时思想还大部分是面向过程的,导致写出了很不优雅的JAVA代码,一般来说这道题的主函数最多两三行就够了
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
       Student[] student=new Student[5];
       Scanner input=new Scanner(System.in);
       for(int i=0;i<3;i++)
       {   student[i]=new Student();
           int nomalsum=0,testsum=0;
           for(int j=0;j<3;j++)
           {
               student[i].ID = input.next();
               student[i].Name = input.next();
               String object;
               int nomal,test;
               object=input.next();
               nomal=input.nextInt();
               test=input.nextInt();
               nomalsum+=nomal;
               testsum+=test;
               if(object.equals("语文")){
                   student[i].Chinese=(int)(0.4*nomal+0.6*test);
               }
               if(object.equals("数学")){
                   student[i].MATH=(int)(0.4*nomal+0.6*test);
               }
               if(object.equals("物理")){
                   student[i].Physic=(int)(0.4*nomal+0.6*test);
               }
           }
           System.out.print(student[i].ID+" "+student[i].Name+" "+student[i].getsum(student[i].Chinese,student[i].MATH,student[i].Physic)+" "+student[i].getaverage(nomalsum)+" "+student[i].getaverage(testsum)+" "+student[i].getaverage(student[i].getsum(student[i].Chinese,student[i].MATH,student[i].Physic))+"\n");
       }
       return;
    }

}
class Student {
    String Name;
    String ID;
    int Chinese;
    int MATH;
    int Physic;
    public int getsum(int chinese,int math,int physic)
    {
        return chinese+math+physic;
    }
    public String getaverage(int sum)
    {
        float f= (float) sum/3;
        DecimalFormat df = new DecimalFormat("#.00");
        return df.format(f);
    }
}

本题

7-3 有重复的数据

 

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。

输入格式:

你的程序首先会读到一个正整数n,n[1,100000],然后是n个整数。

输出格式:

如果这些整数中存在重复的,就输出:

YES

否则,就输出:

NO

输入样例:

5
1 2 3 1 4

输出样例:

YES
代码长度限制
16 KB
时间限制
800 ms
内存限制
64 MB
 
先sort再遍历比双层遍历的算法节省很多时间,因为Java中的sort方法使用的是一种高效的排序算法,具体的实现原理取决于排序的数据类型和大小。在Java 7之前,Arrays类使用的是经典的快速排序算法。在Java 7及以后的版本中,Arrays类在排序小型数组时使用的是改进后的快速排序算法,而在排序大型数组时使用的是归并排序算法。Collections类的sort函数底层使用的是TimSort算法,它是归并排序的变种,所以在遭遇需要排序的可能时请毫不犹豫的利用它吧
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Scanner;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
    public static void main(String[] args) {
        // Press Alt+Enter with your caret at the highlighted text to see how
        // IntelliJ IDEA suggests fixing it.
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int num[]=new int[n];
        for(int i=0;i<n;i++){
            num[i]=input.nextInt();
        }
        
        if(n==1) System.out.print("NO");
        else
        {
            Arrays.sort(num);
           for(int i=0;i<n-1;i++)
          {
            if(num[i]==num[i+1])
            {
               System.out.print("YES");
               return;
            }
              
          }
            System.out.print("NO");
            return;
       }
    }
}

 

 7-4 去掉重复的数据
 

在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。

你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,去掉所有重复的数字。最后按照输入顺序输出没有重复数字的数据。所有重复的数字只保留第一次出现的那份。

输入格式:

你的程序首先会读到一个正整数 n,1≤n≤100000。
然后是 n 个整数,这些整数的范围是 [1, 100000]。

输出格式:

在一行中按照输入顺序输出去除重复之后的数据。每两个数据之间有一个空格,行首尾不得有多余空格。

输入样例:

5
1 2 2 1 4

输出样例:

1 2 4
代码长度限制
16 KB
时间限制
1500 ms
内存限制
150 MB
这道题使用了LinkedHash,不使用Hash是因为Hashset会自动给元素排序,在这道题中会导致你后续输出混乱。那么LinkedHash是如何避免破坏输入的有序性的呢,它内部除了哈希表外还存在一条链表来记录存储顺序,从而不会在用户希望使用原输入顺序时产生影响
import java.util.LinkedHashSet;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n;
        n = input.nextInt();
        LinkedHashSet<Integer> hash = new LinkedHashSet<Integer>();
        for (int i = 0;i<n;i++) {
            hash.add(input.nextInt());
        }
        int[] num = hash.stream().mapToInt(Integer::intValue).toArray();
        for(int i=0;i<hash.size();i++){
            if(i==hash.size()-1) System.out.print(num[i]);
            else System.out.print(num[i] + " ");
        }
    }
}

7-5 面向对象编程(封装性)

Student类具体要求如下:
私有成员变量:学号(sid,String类型),姓名(name,String类型),年龄(age,int类型),专业(major,String类型) 。
提供无参构造和有参构造方法。(注意:有参构造方法中需要对年龄大小进行判定)
普通成员方法:print(),输出格式为“学号:6020203100,姓名:王宝强,年龄:21,专业:计算机科学与技术”。
普通成员方法:提供setXxx和getXxx方法。(注意:setAge()方法中需要对年龄进行判定)
注意:
年龄age不大于0,则不进行赋值。
print()中的“:”和“,”为均为中文冒号和逗号。

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}

/* 请在这里填写答案 */

输入格式:

输出格式:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程

输入样例:

在这里给出一组输入。例如:

6020203110 王宝强 21 计算机科学与技术
6020203119 张三丰 23 软件工程

输出样例:

在这里给出相应的输出。例如:

学号:6020203110,姓名:王宝强,年龄:21,专业:计算机科学与技术
学号:6020203119,姓名:张三丰,年龄:23,专业:软件工程
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
这道题的主函数题干已经给出,类的构造也比较简单,但它很有意义,对面向对象的理解比较有帮助,这应该是第一次写构造函数的代码,在刚刚学习Java时我们可能认为它相比C语言规矩更加繁琐。说句不文雅的话,有种脱裤子放p的感觉,但其实面对大型项目时这样的繁琐是很有必要的,对于合作和维护能够提高很多效率,属于是高瞻远瞩了(大拇指)
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //调用无参构造方法,并通过setter方法进行设值
        String sid1 = sc.next();
        String name1 = sc.next();
        int age1 = sc.nextInt();
        String major1 = sc.next();
        Student student1 = new Student();
        student1.setSid(sid1);
        student1.setName(name1);
        student1.setAge(age1);
        student1.setMajor(major1);
        //调用有参构造方法
        String sid2 = sc.next();
        String name2 = sc.next();
        int age2 = sc.nextInt();
        String major2 = sc.next();
        Student student2 = new Student(sid2, name2, age2, major2);
        //对学生student1和学生student2进行输出
        student1.print();
        student2.print();
    }
}
class Student {
    static String name;
    static String sid;
    static String major;
    static int age;
    public Student(String sid, String name, int age, String major) {
        if(age>0){
            this.sid =sid;
            this.name=name;
            this.age=age;
            this.major=major;
        }
    }

    public Student() {

    }

    public void setSid(String sid) {
        this.sid=sid;
    }

    public void setName(String name) {
        this.name=name;
    }

    public void setAge(int age) {
        if(age>0) this.age=age;
    }

    public void setMajor(String major) {
        this.major=major;
    }

    public void print() {
        System.out.print("学号:"+this.sid+",姓名:"+this.name+",年龄:"+this.age+",专业:"+this.major+"\n");
    }
}

7-6 GPS测绘中度分秒转换

 

在测绘中,获取经度和纬度信息的时候,可以是度分秒格式,也可以是小数点格式。例如一个北纬的纬度信息,30°41′52.37″ ,可以转换为 30.697881。

规则:
(1)度和分都是整数,秒可以含有小数。将用户输入的第一个整数,加上第二个整数除以60,再加上第三个浮点数除以3600,就是最终结果。

(2)在输出结果时,保留6位小数。

(3)题目假定用户输入的数据,一定是合法的数据。

输入格式:

三个数值,数之间用空格分开。

输出格式:

见输出样例。

输入样例:

两个整数后,跟上一个小数。数据之间用空格分开。三个数分别代表度、分、秒。

30 41 52.37

输出样例:

输出经纬度信息的小数点格式,保留6位小数。
注意等号的前后有且仅有一个空格,建议复制下面输出到你的代码中,再进行修改。

30°41′52.37″ = 30.697881
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
和本题集的第一题类型一致,没有需要多赘述的,注意输出规则即可
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        int du,fen;
        double mio,res;
        Scanner input=new Scanner(System.in);
        du=input.nextInt();
        fen=input.nextInt();
        mio=input.nextDouble();
        res=du+ (double) fen /60+mio/3600;
        //30°41′52.37″ = 30.697881
        DecimalFormat ff=new DecimalFormat("#.00"),df = new DecimalFormat("#.000000");

        System.out.print(du+"°"+fen+"′"+mio+"″ = "+String.format("%.6f",res));
    }
}

7-7 菜单计价程序-1

某饭店提供4种菜,每种菜品的基础价格如下:
西红柿炒蛋 15
清炒土豆丝 12
麻婆豆腐 12
油淋生菜 9

设计点菜计价程序,根据输入的订单,计算并输出总价格。
订单由一条或多条点菜记录组成,每条记录一行,最后以"end"结束
每条点菜记录包含:菜名、份额两个信息。
份额可选项包括:1、2、3,分别代表小、中、大份)

不同份额菜价的计算方法:
小份菜的价格=菜品的基础价格。
中份菜的价格=菜品的基础价格1.5。
小份菜的价格=菜品的基础价格
2。
如果计算出现小数,按四舍五入的规则进行处理。

参考以下类的模板进行设计:
菜品类:对应菜谱上一道菜的信息。
Dish {
String name;//菜品名称
int unit_price; //单价
int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
}

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。
Menu {
Dish[] dishs ;//菜品数组,保存所有菜品信息
Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
}

点菜记录类:保存订单上的一道菜品记录
Record {
Dish d;//菜品
int portion;//份额(1/2/3代表小/中/大份)
int getPrice()//计价,计算本条记录的价格
}

订单类:保存用户点的所有菜的信息。
Order {
Record[] records;//保存订单上每一道的记录
int getTotalPrice()//计算订单的总价
Record addARecord(String dishName,int portion)
//添加一条菜品信息到订单中。
}

输入格式:

每条点菜记录的格式:
菜名+空格(英文)+份额
注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。
最后一条记录以“end”结束。

输出格式:

订单上所有菜品的总价(整数数值),每份菜
如果订单中包含不能识别的菜名,则在总价之前输出“** does not exist”,**是不能识别的菜名

输入样例:

在这里给出一组输入。例如:

麻婆豆腐 2
西红柿炒蛋 3
end

输出样例:

在这里给出相应的输出。例如:

48

输入样例1:

订单中包含不存在的菜品记录。例如:

麻婆豆腐 2
炒脆肚 2
西红柿炒蛋 3
end

输出样例1:

在这里给出相应的输出。例如:

炒脆肚 does not exist
48
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
这道题是我第一次写相对复杂的面向对象程序,主要难点在于类之间的联系和配合,我们需要一个记录所有菜品的菜单,需要记录顾客点单的订单,需要菜品的各种信息等等,在本题中我第一次使用了List,涉及动态的增删改查时List是很好用的工具,在后面的题目中它也会是常客
类图:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
           Scanner input = new Scanner(System.in);

           Menu menu=new Menu();
           menu.dishes =new Dish[4];
           for (int i=0;i<4;i++) menu.dishes[i]=new Dish();
           menu.dishes[0].name="西红柿炒蛋";
           menu.dishes[0].unit_price=15;
           menu.dishes[1].name="清炒土豆丝";
           menu.dishes[1].unit_price=12;
           menu.dishes[2].name="麻婆豆腐";
           menu.dishes[2].unit_price=12;
           menu.dishes[3].name="油淋生菜";
           menu.dishes[3].unit_price=9;
        String name;
        name=input.next();
        Order order=new Order();

           while (name.equals("end")==false)
           {
               int portion;
               portion=input.nextInt();
               if(menu.searthDish(name)!=null)
               {
                 Record record=new Record(menu.searthDish(name),portion );
                 order.addARecord(record.d, portion);
               }
               else if (name.equals("end")==false) System.out.print(name+" does not exist\n");
               name=input.next();
           }
        System.out.println(order.sum);
    }
}
   class Dish
   {
        String name;//菜品名称
        int unit_price; //单价
       int getPrice(int portion)
       {
           float[] n = {1, 1.5f, 2};
           return Math.round((unit_price * n[portion - 1]));
       }
   }

    class Menu
    {
        Dish[] dishes;//菜品数组,保存所有菜品信息
        Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。
        {
             for(int i = 0; i< dishes.length; i++)
             {
                 if(dishName.equals(dishes[i].name)) return dishes[i];
             }

            return null;
        }
    }

    class Record
    {
        Dish d;//菜品
        int portion;//份额(1/2/3代表小/中/大份)

        public Record(Dish dish, int portion) {
            this.d=dish;
            this.portion=portion;
        }

        int getPrice()//计价,计算本条记录的价格
        {
            return d.getPrice(portion);
        }
    }

    class Order
    {
        List<Record> records = new ArrayList<>();//保存订单上每一道的记录
        int sum=0;
        void addARecord(Dish dish, int portion) {
            Record record = new Record(dish, portion);
            sum+=record.getPrice();
            records.add(record);
        }
//添加一条菜品信息到订单中。
    }

7-8 jmu-java-日期类的基本使用

  1. 给定一个日期,判定是否为合法日期。如果合法,判断该年是否闰年,该日期是当年第几天、当月第几天、当周第几天、。
  2. 给定起始日期与结束日期,判定日期是否合法且结束日期是否早于起始日期。如果均合法,输出结束日期与起始日期之间的相差的天数、月数、念书。

输入格式:

第一行输入一个日期字符串,格式为"YYYY-MM-dd"
第二行输入两个日期字符串,中间使用空格隔开。分别代表开始日期与结束日期。

输出格式:

如果第一行日期字符串非法,输出自定义的错误信息。
如果第一行日期有效,输出相关信息,如果是闰年要输出是闰年。
如果第二行两个日期,只要有一个无效。就输出相关错误信息。
如果第二行两个日期有效且结束日期不早于开始日期,输出相关信息。

输入样例1:

第一行日期非法、第二行有日期非法

2020-02-30
2020-02-30 2020-01-02

输出样例1:

2020-02-30无效!
2020-02-30或2020-01-02中有不合法的日期.

输入样例2:

均有效且合法

2021-02-28
2019-08-01 2020-01-02

输出样例2:

2021-02-28是当年第59天,当月第28天,当周第7天.
2020-01-02与2019-08-01之间相差154天,所在月份相差-7,所在年份相差1.

输入样例3:

日期均有效,但结束日期早于开始日期

2020-02-28
2020-02-02 2020-02-01

输出样例3:

2020-02-28是闰年.
2020-02-28是当年第59天,当月第28天,当周第5天.
2020-02-01早于2020-02-02,不合法!
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
本题难度较高,由于我开始的时间较晚,到最后还有一个测试点没能过去

 本题促使我去学习了很多的日期类,其中本题的MVP我认为是Calendar,但最大的坑货也是它。Calendar可以记录年、月、日并用于后续的计算,其中获取天数的day of系统可以用于获取年、月、周的天数,大大为我们节省了时间。还可以将年月日转化成毫秒数,便于我们计算。

但它bug实在太多了,输入月份时应该输入实际月份-1,否则天数的计算是错误的,而这又会影响后续月份的输出,很不方便。而且它用于比较日期早晚的compareTo方法也有bug,我只好用getTime方法分别获取毫秒数来比较大小。如果用getTime获取毫秒数再通过计算转化成天数,也会造成误差。希望日后我或诸位可以开发出更优秀的日期类

import java.util.Date;
import java.util.Scanner;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        Date date=new Date();
        Check god=new Check();
        Calendar acal = Calendar.getInstance(),bcal=Calendar.getInstance(),ccal=Calendar.getInstance();
        String sa,sb,sc;
        int flag1=0,flag2=0;
        sa=input.next();
        if(god.law(sa)) {
            acal.set(Calendar.YEAR, Integer.parseInt(sa.substring(0, 4)));
            acal.set(Calendar.MONTH, Integer.parseInt(sa.substring(5, 7))-1);
            acal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(sa.substring(8, 10)));
            DateFormat a = new SimpleDateFormat(sa);
        }

        else {
            flag1=1;
            System.out.print(sa+"无效!\n");
        }
        sb=input.next();
        if(god.law(sb)==true) {
            bcal.set(Calendar.YEAR, Integer.parseInt(sb.substring(0, 4)));
            bcal.set(Calendar.MONTH, Integer.parseInt(sb.substring(5, 7)) -1);
            bcal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(sb.substring(8, 10)));
            DateFormat b = new SimpleDateFormat(sb);
        }
        else flag2=1;
        sc=input.next();
        if(god.law(sc)) {
            ccal.set(Calendar.YEAR, Integer.parseInt(sc.substring(0, 4)));
            ccal.set(Calendar.MONTH, Integer.parseInt(sc.substring(5, 7)) -1);
            ccal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(sc.substring(8, 10)));
            DateFormat c = new SimpleDateFormat(sc);
        }
        else flag2=1;
        if(flag2==1){
            System.out.print(sb+"或"+sc+"中有不合法的日期.");
            return;
        }
        if(god.ifrun(acal)) System.out.print(sa+"是闰年.\n");
        int dayofweek;
        if (acal.get(Calendar.DAY_OF_WEEK) == 1) {
            dayofweek = 7;
        } else {
            dayofweek = acal.get(Calendar.DAY_OF_WEEK) - 1;
        }

        if(flag1==0) System.out.print(sa+"是当年第"+acal.get(Calendar.DAY_OF_YEAR)
                +"天,当月第"+acal.get(Calendar.DAY_OF_MONTH)
                +"天,当周第"+dayofweek+"天.\n");

        if(bcal.before(ccal)==false) System.out.print(sc+"早于"+sb+",不合法!");
        else {
            int year=ccal.get(Calendar.YEAR)-bcal.get(Calendar.YEAR);

            bcal.set(Calendar.MONTH, Integer.parseInt(sb.substring(5, 7)));
            ccal.set(Calendar.MONTH, Integer.parseInt(sc.substring(5, 7)));
            int month=ccal.get(Calendar.MONTH)-bcal.get(Calendar.MONTH);
            System.out.print(sc+"与"+sb+"之间相差"+god.allday(sb,bcal,ccal)+"天,所在月份相差"+month+",所在年份相差"+year+".");
        }
    }
}
class Check
{

    public  boolean law(String s) {

        if (!((s.charAt(0) >= 48 && s.charAt(0) <= 57) &&
                (s.charAt(1) >= 48 && s.charAt(1) <= 57) &&
                (s.charAt(2) >= 48 && s.charAt(2) <= 57) &&
                (s.charAt(3) >= 48 && s.charAt(3) <= 57) &&
                (s.charAt(4) == '-') &&
                (s.charAt(5) >= 48 && s.charAt(5) <= 49) &&
                (s.charAt(6) >= 48 && s.charAt(6) <= 57) &&
                (s.charAt(7) == '-') &&
                (s.charAt(8) >= 48 && s.charAt(8) <= 51) &&
                (s.charAt(9) >= 48 && s.charAt(9) <= 57))) return false;
        int year=Integer.parseInt(s.substring(0,4)),month=Integer.parseInt(s.substring(5,7)),day=Integer.parseInt(s.substring(8,10));
        if(year%4==0&&year%100==0||year%400==0) {
            if (month == 2 && (day < 0 || day > 28)) return false;
        }
        else if (month == 2 && (day < 0 || day > 29)) return false;
        if(s.charAt(1) == 48 && s.charAt(2) == 48&&s.charAt(3) == 48 && s.charAt(0) == 48) return false;
        if(s.charAt(5) == 48 && s.charAt(6) == 48) return false;
        if(s.charAt(8) == 48 && s.charAt(9) == 48) return false;
        return true;
    }
    public boolean ifrun(Calendar calendar)
    {
        if(calendar.get(Calendar.YEAR)%4==0
                &&calendar.get(Calendar.YEAR)%100!=0
                ||calendar.get(Calendar.YEAR)%400==0) return true;
        else return false;
    }
    public long allday(String s,Calendar acal,Calendar bcal)
    {
        long differenceInMillis = Math.abs(acal.getTimeInMillis() - bcal.getTimeInMillis());
        long differenceInDays = differenceInMillis / (24 * 60 * 60 * 1000);

        return differenceInDays;
    }
}

题目集3:

7-1 jmu-java-日期类的基本使用

和上一题集的最后一题一样

 7-2 课程成绩统计程序-1
 

某高校课程从性质上分为:必修课、选修课,从考核方式上分为:考试、考察。

考试的总成绩由平时成绩、期末成绩分别乘以权重值得出,比如平时成绩权重0.3,期末成绩权重0.7,总成绩=平时成绩*0.3+期末成绩*0.7。

考察的总成绩直接等于期末成绩

必修课的考核方式必须为考试,选修课可以选择考试、考察任一考核方式。

1、输入:

包括课程、课程成绩两类信息。

课程信息包括:课程名称、课程性质、考核方式(可选,如果性质是必修课,考核方式可以没有)三个数据项。

课程信息格式:课程名称+英文空格+课程性质+英文空格+考核方式

课程性质输入项:必修、选修

考核方式输入选项:考试、考察

课程成绩信息包括:学号、姓名、课程名称、平时成绩(可选)、期末成绩

课程信息格式:学号+英文空格+姓名+英文空格+课程名称+英文空格+平时成绩+英文空格+期末成绩

以上信息的相关约束:

1)平时成绩和期末成绩的权重默认为0.3、0.7

2)成绩是整数,不包含小数部分,成绩的取值范围是【0,100】

3)学号由8位数字组成

4)姓名不超过10个字符

5)课程名称不超过10个字符

6)不特别输入班级信息,班级号是学号的前6位。

2、输出:

输出包含三个部分,包括学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分。

为避免误差,平均分的计算方法为累加所有符合条件的单个成绩,最后除以总数。

1)学生课程总成绩平均分按学号由低到高排序输出

格式:学号+英文空格+姓名+英文空格+总成绩平均分

如果某个学生没有任何成绩信息,输出:学号+英文空格+姓名+英文空格+"did not take any exams"

2)单门课程成绩平均分分为三个分值:平时成绩平均分(可选)、期末考试平均分、总成绩平均分,按课程名称的字符顺序输出

格式:课程名称+英文空格+平时成绩平均分+英文空格+期末考试平均分+英文空格+总成绩平均分

如果某门课程没有任何成绩信息,输出:课程名称+英文空格+"has no grades yet"

3)班级所有课程总成绩平均分按班级由低到高排序输出

格式:班级号+英文空格+总成绩平均分

如果某个班级没有任何成绩信息,输出:班级名称+英文空格+ "has no grades yet"

异常情况:

1)如果解析某个成绩信息时,课程名称不在已输入的课程列表中,输出:学号+英文空格+姓名+英文空格+":"+课程名称+英文空格+"does not exist"

2)如果解析某个成绩信息时,输入的成绩数量和课程的考核方式不匹配,输出:学号+英文空格+姓名+英文空格+": access mode mismatch"

以上两种情况如果同时出现,按第一种情况输出结果。

3)如果解析某个课程信息时,输入的课程性质和课程的考核方式不匹配,输出:课程名称+" : course type & access mode mismatch"

4)格式错误以及其他信息异常如成绩超出范围等,均按格式错误处理,输出"wrong format"

5)若出现重复的课程/成绩信息,只保留第一个课程信息,忽略后面输入的。

信息约束:

1)成绩平均分只取整数部分,小数部分丢弃

参考类图:


image.png

输入样例1:

仅有课程。例如:

java 必修 考试
数据结构 选修 考试
形式与政治 选修 考察
end

输出样例1:

在这里给出相应的输出。例如:

java has no grades yet
数据结构 has no grades yet
形式与政治 has no grades yet

输入样例2:

单门考试课程 单个学生。例如:

java 必修 考试
20201103 张三 java 20 40
end

输出样例2:

在这里给出相应的输出。例如:

20201103 张三 34
java 20 40 34
202011 34

输入样例3:

单门考察课程 单个学生。例如:

java 选修 考察
20201103 张三 java 40
end

输出样例3:

在这里给出相应的输出。例如:

20201103 张三 40
java 40 40
202011 40

输入样例4:

考试课程 单个学生 不匹配的考核方式。例如:

java 必修 考试
20201103 张三 java 20
end

输出样例4:

在这里给出相应的输出。例如:

20201103 张三 : access mode mismatch
20201103 张三 did not take any exams
java has no grades yet
202011 has no grades yet

输入样例5:

单门课程,单个学生,课程类型与考核类型不匹配。例如:

java 必修 考察
20201103 张三 java 40
end

输出样例5:

在这里给出相应的输出。例如:

java : course type & access mode mismatch
java does not exist
20201103 张三 did not take any exams
202011 has no grades yet

输入样例6:

单门课程,多个学生。例如:

java 选修 考察
20201103 李四 java 60
20201104 王五 java 60
20201101 张三 java 40
end

输出样例6:

在这里给出相应的输出。例如:

20201101 张三 40
20201103 李四 60
20201104 王五 60
java 53 53
202011 53

输入样例7:

单门课程,单个学生,课程类型与考核类型不匹配。例如:

形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201103 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201103 李四 java 60
20201103 李四 数据库 70 78
end

输出样例7:

在这里给出相应的输出。例如:

20201103 李四 73
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73

输入样例8:

单门课程,单个学生,成绩越界。例如:

数据结构 选修 考察
20201103 李四 数据结构 101
end

输出样例8:

在这里给出相应的输出。例如:

wrong format
数据结构 has no grades yet

输入样例9:

多门课程,多个学生,多个成绩。例如:

形式与政治 必修 考试
数据库 选修 考试
java 选修 考察
数据结构 选修 考察
20201205 李四 数据结构 70
20201103 李四 形式与政治 80 90
20201102 王五 java 60
20201211 张三 数据库 70 78
end

输出样例9:

在这里给出相应的输出。例如:

20201102 王五 60
20201103 李四 87
20201205 李四 70
20201211 张三 75
java 60 60
数据结构 70 70
数据库 70 78 75
形式与政治 80 90 87
202011 73
202012 72
代码长度限制
16 KB
时间限制
1000 ms
内存限制
64 MB
这道题更是重量级!65分的题目我写了三天最终只过了20分(大悲)。我的思路是创建一个总类School来记录具有唯一性的数据,比如开设的科目、所有班级,还有一些设计多个子类的方法。班级类Class用于记录班级平均分、班号和班内学生,学生类Student用于记录学生的个人信息、此学生的选课表、学生成绩。课程类Lesson则用于记录课程信息、学科平均分。用于记录的各种表都使用List来完成。
在编写这道程序的过程中我深刻体会到了设计的重要性,在动“键”之前一定要打好草图,理清各个类之间的联系,不然会在编程的过程中越写越乱,而且修改bug时难以找到病灶,无从下手。
import java.util.*;
import java.util.regex.Pattern;
public class Main {
    public static void main(String[] args) {
        School school=new School();
        school.Input();
        school.output();
    }
}
class School {
    static List<Class> classes = new ArrayList<>();//记录所有班级
    static List<Lesson> lessons = new ArrayList<>();//记录所有科目
    public Lesson searchlessons(String s) {//传入学科名
        for (int i=0;i<lessons.size();i++) {
            if (lessons.get(i).namelesson.equals(s))
                return lessons.get(i);
        }
        return null;
    }
    public void addlesson(String s) {//传入输入源码
        Lesson lesson = new Lesson();
        lesson.setlesson(s);
        this.lessons.add(lesson);
    }
    public Class searchClass(String s) {//传入班号
        for (int i=0;i< classes.size();i++) {
            if (classes.get(i).numclass.equals(s))
                return classes.get(i);
        }
        return null;
    }
    public void addClass(String s) {//传入输入源码
        Class cla = new Class();
        cla.setclass(s);
        this.classes.add(cla);
    }
    public void Input() {
        Scanner input = new Scanner(System.in);
        String s;
        s = input.nextLine();
        while (s.equals("end") == false) {
            String[] part = new String[]{};
            part = s.split(" ");
            if (part[1].equals("必修") && part[2].equals("考察")) {
                System.out.print(part[0] + " : course type & access mode mismatch\n");
            }
            if (!School.Lesson.allowlesson(s) && School.Student.allowstudent(s) == 0)
                System.out.print("wrong format\n");
            else {
                if (School.Lesson.allowlesson(s)) {//第一类输入
                    //若没有此科目,向学校添加科目,已经有了就不管
                    if (School.Student.searchsiglessons(part[0]) == null) this.addlesson(s);
                }
                if (School.Student.allowstudent(s) != 0) {//第二类输入
                    //学生所有课程总成绩的平均分、单门课程成绩平均分、单门课程总成绩平均分、班级所有课程总成绩平均分
                    if (this.searchClass(part[0].substring(0, 6)) == null) {
                        //若没有此班级,向学校添加班级
                        this.addClass(s);
                    }
                    else if (this.searchClass(part[0].substring(0, 6)).searchstudents(part[0]) == null) {
                        //若没有此学生,向班级添加学生
                        this.searchClass(part[0].substring(0, 6)).addstudent(s);
                    }
//                    else if (this.searchClass(part[0].substring(0, 6)).searchstudents(part[0]).searchsiglessons(part[2]) == null) {
//                        //若学生没有此科目,向学生添加科目,已经有了就不管
//                        this.searchClass(part[0].substring(0, 6)).searchstudents(part[0]).addlesson(s);
//                    }
                }
            }
            s = input.nextLine();
        }
    }
    public void output()
    {
        for (Lesson allles: this.lessons){
            allles.nomal=0;
            allles.last=0;
        }
        for (School.Class clasS : this.classes) {//遍历班级
            if(this.classes.isEmpty()) System.out.print(clasS.numclass+" has no grades yet\n");
            int classaverage=0;
            for (Student stu: clasS.students) {//遍历学生
                int studentaverage=0;
                for (Lesson sigles: stu.siglessons) {//遍历学生所修科目
                    int flag=0;
                    if(stu.siglessons.isEmpty()) System.out.print(stu.idnum+" "+stu.namestudent+" did not take any exams\n");
                    else for (Lesson allles: this.lessons){//遍历所有科目
                         if(sigles.namelesson.equals(allles.namelesson)){
                             allles.count++;
                             flag=1;
                             if((allles.flag.equals("必修")||allles.flag.equals("选修"))&&allles.test.equals("考试")) {
                                 sigles.grade = (int) (0.3 * sigles.nomal + 0.7 * sigles.last);
                                 allles.nomal+=sigles.nomal;
                                 allles.last+=sigles.nomal;
                                 allles.grade+=sigles.grade;
                             }
                             if(allles.flag.equals("选修")&&allles.test.equals("考察")) {
                                 sigles.grade = (int) (sigles.nomal);
                                 allles.nomal+=sigles.nomal;
                                 allles.grade+=sigles.grade;
                             }
                             if(allles.test.equals("考察")&&sigles.nomal!=-1) {
                                 System.out.print(stu.idnum + " " + stu.namestudent + " : access mode mismatch\n");
                             }
                             if(allles.flag.equals("必修")&&allles.test.equals("考察")) {
                                 System.out.print(allles.namelesson + " : course type & access mode mismatch\n");
                             }
                             studentaverage+=sigles.grade;
                         }
                    }
                    if(flag==0) System.out.print(stu.idnum+" "+stu.namestudent+" : "+sigles.namelesson+"does not exist\n");

                }
                studentaverage=studentaverage/stu.siglessons.size();
                classaverage+=studentaverage;
                System.out.print(stu.idnum+" "+stu.namestudent+" "+studentaverage+"\n");
            }
            for (Lesson les: this.lessons){//遍历

            }
            System.out.print(clasS.numclass+" "+classaverage+"\n");
        }
        for (Lesson allles: this.lessons){
            if(allles.count==0) System.out.print(allles.namelesson+" has no grades yet\n");
            else if(allles.nomal!=-1)
                System.out.print(allles.namelesson+" "+allles.nomal/allles.count+" "+allles.last/allles.count+" "+allles.grade/allles.count+ "\n");
            else System.out.print(allles.namelesson+" "+allles.last/allles.count+" "+allles.grade/allles.count+ "\n");
        }
    }
    public static class Class {
        String numclass;
        int average;
        List<Student> students = new ArrayList<>();//记录班内学生

        public Student searchstudents(String s) {//传入学号
            for (int i=0;i<students.size();i++) {
                if (students.get(i).idnum.equals(s))
                    return students.get(i);
            }
            return null;
        }
        public void addstudent(String s) {//传入输入源码
            Student student = new Student();
            student.setstudent(s);
            this.students.add(student);
        }
        public void setclass(String s) {
            String[] part = new String[]{};
            part = s.split(" ");
            this.numclass=part[0].substring(0,6);
        }
    }
    static class Lesson {
        String namelesson;
        String flag;//0为选修,1为必修
        String test;//0为考察,1为考试
        int nomal;
        int last=-1;
        int grade;
        int count=0;
        public static boolean allowlesson(String s) {
            String regex;
            regex = "\\S{1,10}" + " " + "(必修|选修)" + " " + "(考试|考察)";
            boolean isValid = s.matches(regex);
            return isValid;
        }

        public void setlesson(String s) {
            String[] part = new String[]{};
            part = s.split(" ");
            if(this.allowlesson(s)) {
                this.namelesson = part[0];
                this.flag = part[1];
                this.test = part[2];
            }
        }
    }
    public static class Student {
        String idnum;
        String numclass;
        String namestudent;
        String namelesson;
        static List<Lesson> siglessons = new ArrayList<>();//记录个体学生所修科目
        int nomal=-1;
        int last;
        public static Lesson searchsiglessons(String s) {//传入学科名
            for (int i=0;i<lessons.size();i++) {
                if (lessons.get(i).namelesson.equals(s))
                    return lessons.get(i);
            }
            return null;
        }
        public void addlesson(String s) {//传入输入源码
            Lesson lesson = new Lesson();
            lesson.setlesson(s);
            this.siglessons.add(lesson);
        }
        public static int allowstudent(String s) {
            String regex1, regex2;
            regex1 = "[0-9]{8}" + " " + "\\S{1,10}" + " " + "\\S{1,10}" +" " + "([1-9]?[0-9]|100)";
            regex2 = "[0-9]{8}" + " " + "\\S{1,10}" + " " + "\\S{1,10}" + " " + "([1-9]?[0-9]|100)" + " " + "([1-9]?[0-9]|100)";
            boolean isValid1 = Pattern.matches(regex1, s), isValid2 = Pattern.matches(regex2, s);
            if (isValid1) return 1;
            if (isValid2) return 2;
            return 0;
        }
        public  void setstudent(String s) {
            String[] part = new String[]{};
            String namelesson = null;
            part = s.split(" ");
            if(searchsiglessons(part[2])==null) this.addlesson(s);
            if (this.allowstudent(s) == 1) {
                this.idnum = part[0];
                this.numclass = part[0].substring(0, 6);
                this.namestudent = part[1];
                this.namelesson=part[2];
                for (Lesson les: lessons) {
                    if (les.namelesson.equals(s)){
                        les.last=Integer.parseInt(part[3]);
                    }
                }
            }
            if (this.allowstudent(s) == 2) {
                this.idnum = part[0];
                this.numclass = part[0].substring(0, 6);
                this.namestudent = part[1];
                this.namelesson=part[2];
                for (Lesson les: lessons) {
                    if (les.namelesson.equals(s)){
                        les.nomal=Integer.parseInt(part[3]);
                        les.last=Integer.parseInt(part[4]);
                    }
                }
            }
        }
    }
}

7-3 面向对象编程(封装性)

和上一题集中的第五题一样
7-4 判断两个日期的先后,计算间隔天数、周数

从键盘输入两个日期,格式如:2022-06-18。判断两个日期的先后,并输出它们之间间隔的天数、周数(不足一周按0计算)。

预备知识:通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。

输入格式:

输入两行,每行输入一个日期,日期格式如:2022-06-18

输出格式:

第一行输出:第一个日期比第二个日期更早(晚)
第二行输出:两个日期间隔XX天
第三行输出:两个日期间隔XX周

输入样例1:

2000-02-18
2000-03-15

输出样例1:

第一个日期比第二个日期更早
两个日期间隔26天
两个日期间隔3周

输入样例2:

2022-6-18
2022-6-1

输出样例2:

第一个日期比第二个日期更晚
两个日期间隔17天
两个日期间隔2周
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
这道题是第一题的变种,只有两个测试点而且比较宽松(感谢老师!),在第一题中我说过Calender类中用getTime方法获取毫秒数再通过计算转化为天数会造成误差,但是在这道题的测试中却通过了,可见本次题集由于1、2题难度过高,老师还是设置了一些送分项的。
import java.util.Date;
import java.util.Scanner;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        Date date=new Date();
        Check god=new Check();
        Calendar acal = Calendar.getInstance(),bcal=Calendar.getInstance(),ccal=Calendar.getInstance();
        String sa,sb;
        int year,month,day;
        sa=input.nextLine();
        sb=input.nextLine();
        String[] a=sa.split("-"),b=sb.split("-");
        year=Integer.parseInt(a[0]);
        month=Integer.parseInt(a[1]);
        day=Integer.parseInt(a[2]);
        acal.set(Calendar.YEAR,year);
        acal.set(Calendar.MONTH,month);
        acal.set(Calendar.DAY_OF_MONTH,day);
        year=Integer.parseInt(b[0]);
        month=Integer.parseInt(b[1]);
        day=Integer.parseInt(b[2]);
        bcal.set(Calendar.YEAR,year);
        bcal.set(Calendar.MONTH,month);
        bcal.set(Calendar.DAY_OF_MONTH,day);
        int dayofweek;
        if (acal.get(Calendar.DAY_OF_WEEK) == 1) {
            dayofweek = 7;
        } else {
            dayofweek = acal.get(Calendar.DAY_OF_WEEK) - 1;
        }

        if(god.allday(acal)-god.allday(bcal)>0) System.out.print("第一个日期比第二个日期更晚\n");
        else System.out.print("第一个日期比第二个日期更早\n");
            //System.out.print(sc+"与"+sb+"之间相差"+(god.allday(sc,bcal,ccal)-god.allday(sb,bcal,ccal))+"天,所在月份相差"+month+",所在年份相差"+year+".");
            System.out.print("两个日期间隔"+Math.abs(god.allday(acal)-god.allday(bcal))+"天\n");
            System.out.print("两个日期间隔"+Math.abs(god.allday(acal)-god.allday(bcal))/7+"周\n");
    }
}
class Check
{


    public boolean ifrun(Calendar calendar)
    {
        if(calendar.get(Calendar.YEAR)%4==0
                &&calendar.get(Calendar.YEAR)%100!=0
                ||calendar.get(Calendar.YEAR)%400==0) return true;
        else return false;
    }
    public long allday(Calendar acal)
    {
        int year = acal.get(Calendar.YEAR);
        int month = acal.get(Calendar.MONTH);
        int day = acal.get(Calendar.DAY_OF_MONTH);
        int sum = 0;
        int[] monthes= {0,31,28,31,30,31,30,31,31,30,31,30,31};
        for(int i=1;i<year;i++)
            if(i%4==0&&i%100!=0||i%400 ==0)  sum += 366;
            else sum += 365;
        if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0) monthes[2] = 29;
        for(int i = 1;i < month;i++)
            sum += monthes[i];
        sum += day;
        return sum;
    }
}

采坑心得:

       写面向对象的程序设计一定不能怕“繁琐”,很多所谓繁琐的步骤都是为了提高对象之间的配合效率以及维护效率来准备的,而对象之间的联系和配合正是面向对象的重点,在题集3的第二题的代码可以看出我的思路是十分混乱的,一定要提前设计好,代码的实现工作只是设计的体现罢了,好的设计会大大简化编程工作,反之则可能导致编程一塌糊涂。

主要困难以及改进建议:

           我认为我的困难主要在于由于初次学习面向对象程序设计语言,适应性较慢,而题目集的难度坡度较大。造成这种现象的原因我认为还是写代码过少,希望老师可以减轻题目集的难度,增加题量,让学生的学习过程更加平滑。还希望老师在课上讲解一些题目集会使用的知识,避免学生在面对题目时“现学现卖”的现象。

总结:

         这三次作业,我学到了很多Java的知识,认识了很多好用的方法、好用的库......,对面向对象有了更深刻的切身体会,逐步脱离了面向过程思维的影响。我认识到代码能力没有天赋可言,才能是靠键盘敲出来的,一定要多做题目,只有上手才能提升,切忌纸上谈兵。在设计程序之前一定要打好草图,做好设计,程序设计中“设计”才是重中之重。写题目集不能拖沓,一定要尽早开始,留好充足的时间,紧迫感会影响思维,浪费题目的锻炼效果。