题目集1~3的总结性Blog

一、前言

题目集一

知识点考察:Java基本语法,简单运算,逻辑判断,数组基本操作。
题量:适中偏多
难度:简单,基础

题目集二

知识点考察:Java字符串与数组的基本处理,Java对象,类和方法基础
题量:适中
难度:简单,基础操作模拟和逻辑判断,部分类与对象的使用

题目集三

知识点考察:类的处理,使用,面向对象思想,正则表达式匹配字符串,输出处理
题量:适中
难度:前两题简单,基础类处理和使用,最后一题中等,需要用到正则

二、设计与分析

题目集一

7-8 判断三角形类型 (20 分)

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

输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[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
结尾无空行

代码

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner =new Scanner(System.in);
        double a,b,c,temp;
        a=scanner.nextDouble();
        b= scanner.nextDouble();
        c= scanner.nextDouble();
        if(a>b)
        {
            temp=a;a=b;b=temp;
        }
        if(a>c){
            temp=a;a=c;c=temp;
        }
        if(b>c){
            temp=b;b=c;c=temp;
        }
        if(a>=1&&a<=200&b>=1&&b<=200&&c>=1&&c<=200)
        {
            if(a+b>c)
            {
                if(a==b&&b==c)
                {
                    System.out.println("Equilateral triangle");
                }
                else if(a==b&& a*a+b*b-c*c<0.00000001)
                {
                    System.out.println("Isosceles right-angled triangle");
                }
                else if(a==b||a==c||b==c)
                {
                    System.out.println("Isosceles triangle");
                }
                else if(a*a+b*b==c*c)
                {
                    System.out.println("Right-angled triangle");
                }
                else
                {
                    System.out.println("General triangle");
                }
            }
            else
                System.out.println("Not a triangle");
        }
        else
            System.out.println("Wrong Format");

}
}

代码分析图

image

题目思路

先进行输入数据的排序,将三条边排序,得到两条短边,减少程序判断,再进行逻辑判断输出。
注意判断直角时不能直接用相等,用a*a+b*b-c*c<0.00000001,避免计算精度不足导致的判断输出错误

题目集二

7-4 求下一天 (30 分)

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。

要求:Main类中必须含有如下方法,签名如下:

public static void main(String[] args);//主方法 
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型 
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天

输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:
当输入数据非法及输入日期不存在时,输出“Wrong Format”;
当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
输入样例1:
在这里给出一组输入。例如:

2020 3 10
结尾无空行

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

Next date is:2020-3-11
结尾无空行

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

2025 2 10
结尾无空行

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

Wrong Format
结尾无空行
代码


import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int year=scanner.nextInt();
        int month=scanner.nextInt();
        int day=scanner.nextInt();
        if(!checkInputValidity(year,month,day))
        {
            System.out.println("Wrong Format");
        }
        else
        {
            nextDate(year,month,day);

        }
    }
    public static boolean checkInputValidity(int year,int month,int day) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        return year >= 1820 && year <= 2020 && month <= 12 && month >= 1 && day <= a[month] && day > 0;
    }
    public static boolean isLeapYear(int year) {
        return (year%4==0&&year%100!=0)||year%400==0;
    }

    public static void nextDate(int year,int month,int day) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        day++;
        if(day>a[month])
        {
            month++;
            day=1;
        }
        if(month>12)
        {
            year++;
            month=1;
        }
        System.out.println("Next date is:"+year+"-"+month+"-"+day);
    }

}

代码分析图

image

题目思路

  1. 先进行输入数据的合法性判断,如果不合法则直接输出Wrong Format
  2. 创建一个数组存每个月的天数,下标对应月数,当为闰年时month[2]++
  3. 特判加一天后day>month[month]month>12的情况
  4. 按格式输出即可

7-5 求前N天 (30 分)

输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。

输出格式:
当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
当输入数据合法时,输出“n days ago is:年-月-日”

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

2018 6 19 8
结尾无空行

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

8 days ago is:2018-6-11
结尾无空行

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

2018 6 19 -8
结尾无空行

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

-8 days ago is:2018-6-27
结尾无空行
代码


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int year=scanner.nextInt();
        int month=scanner.nextInt();
        int day=scanner.nextInt();
        int n=scanner.nextInt();
        if(!checkInputValidity(year,month,day)||n>10||n<-10)
        {
            System.out.println("Wrong Format");
        }
        else
        {
            theDate(year,month,day,n);

        }
    }
    public static boolean checkInputValidity(int year,int month,int day) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        return year >= 1820 && year <= 2020 && month <= 12 && month >= 1 && day <= a[month] && day > 0;
    }
    public static boolean isLeapYear(int year) {
        return (year%4==0&&year%100!=0)||year%400==0;
    }

    public static void theDate(int year,int month,int day,int n) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        day-=n;
        if(day>a[month])
        {
            day-=a[month];
            month++;
            if(month>12)
            {
                year++;
                month=1;
            }
        }
        else if(day<1)
        {
            month--;
            if(month<1)
            {
                month=12;
                year--;
            }
            day=a[month]+day;
        }
        System.out.println(n+" days ago is:"+year+"-"+month+"-"+day);
    }
}

代码分析图

image

题目思路

数据处理和上题差不多

  1. 先进行输入数据的合法性判断,如果不合法则直接输出Wrong Format
  2. 创建一个数组存每个月的天数,下标对应月数,当为闰年时month[2]++
  3. 注意特判月和年要出现变化的情况。
  4. 按格式输出即可。

题目集三

7-2 定义日期类 (28 分)

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:

输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:
当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
输入样例1:
在这里给出一组输入。例如:

1912 12 25
结尾无空行

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

Next day is:1912-12-26
结尾无空行

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

2001 2 30
结尾无空行

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

Date Format is Wrong
结尾无空行
代码


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        Date a=new Date(scanner.nextInt(),scanner.nextInt(),scanner.nextInt());
        if(!a.checkInputValidity(a.getYear(),a.getMonth(),a.getDay()))
        {
            System.out.println("Date Format is Wrong");
        }
        else
        {
            a.nextDate(a.getYear(),a.getMonth(),a.getDay());

        }
    }
}
class Date{
    private int year;
    private int month;
    private int day;
    Date(){

    }
    Date(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }
    int getYear(){
        return year;
    }
    void setYear(int year){
        this.year=year;
    }
    int getMonth(){
        return month;
    }
    void setMonth(int month){
        this.month=month;
    }
    int getDay(){
        return day;
    }
    void setDay(int day){
        this.day=day;
    }
    boolean isLeapYear(int year) {
        return (year%4==0&&year%100!=0)||year%400==0;
    }
    boolean checkInputValidity(int year,int month,int day) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
       return year >= 1900 && year <= 2000 && month <= 12 && month >= 1 && day <= a[month] && day > 0;
    }
    void nextDate(int year,int month,int day) {
        int[] a=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            a[2]=29;
        day++;
        if(day>a[month])
        {
            month++;
            day=1;
        }
        if(month>12)
        {
            year++;
            month=1;
        }
        System.out.println("Next day is:"+year+"-"+month+"-"+day);
    }
}

代码分析图

题目思路

注意定义类,使用类将方法封装好
处理方法和题目集二7-4差不多

7-3 一元多项式求导(类设计) (50 分)

编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。

输出格式:
如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
当输出结果第一项系数符号为“+”时,不输出“+”;
当指数符号为“+”时,不输出“+”;
当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可。
输出格式见输入输出示例。

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

-2* x^-2+ 5*x^12-4*x+ 12
结尾无空行

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

4*x^-3+60*x^11-4
结尾无空行

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

2*x^6-0*x^7+5
结尾无空行

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

Wrong Format
结尾无空行

代码

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.math.BigInteger;
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String initExpress = input.nextLine();
        String express = initExpress.replaceAll(" ", "");
        Express textExpress = new Express(express);
        if (textExpress.check())
        {
            if(textExpress.checkNum())
                System.out.println("0");
            else
                textExpress.show();
        }
        else
            System.out.println("Wrong Format");
    }
}
class Express {
    private final String express;
    public Express(String express) {
        this.express = express;
    }
    String termExpress = "([+-]?[1-9][0-9]*)?(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?";
    String wholeExpress = "(([+-]?[1-9][0-9]*)?(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?)+";
    String constNum = "[+-]?[0-9]+";
    public boolean check() {
        return Pattern.matches(wholeExpress, express);
    }
    public boolean checkNum(){
        return Pattern.matches(constNum,express);
    }
    public void show() {
        Pattern p = Pattern.compile(termExpress);
        Matcher m = p.matcher(express);
        boolean flag = false;
        while (m.find()) {
            String ratStr = m.group(1);
            String indexStr = m.group(4);
            BigInteger rat = BigInteger.valueOf(1);
            if (ratStr != null ) {
                rat = new BigInteger(ratStr);
                if(m.group(2) != null)
                {
                    if ( m.group(2).startsWith("-"))
                        rat = BigInteger.valueOf(-1);
                    else if( m.group(2).startsWith("+"))
                        rat = BigInteger.valueOf(1);
                }
            }
            else {
                if(m.group() != null){
                    if (m.group().startsWith("-")) {
                        rat = BigInteger.valueOf(-1);
                    }
                    else if(m.group().startsWith("+"))
                        rat = BigInteger.valueOf(1);
                }
            }
            if (indexStr != null) {
                BigInteger index = new BigInteger(indexStr);
                rat = rat.multiply(index);
                index = index.subtract(new BigInteger("1"));
                String s1 = rat.equals(new BigInteger("-1"))? "-x" : rat + "*x";
                String s = index.equals(new BigInteger("1"))? "" : ("^" + index);
                if (rat.compareTo(new BigInteger("0"))>0 && flag)
                    System.out.print("+" + s1 + s);
                else {
                    flag = true;
                    System.out.print(s1 + s);
                }
            } else if (m.group(2) != null) {
                if(flag&& rat.compareTo(new BigInteger("0")) > 0)
                    //System.out.print("+"+ rat);
                    System.out.print(rat);
                else{
                    flag = true;
                    System.out.print(rat);
                }
            }
        }
    }
}

代码分析图

题目思路

主要用正则表达式匹配字符串去控制输入,手动做模拟太麻烦了,正则匹配也可以更方便处理数据
完整的用来匹配项的正则表达式:
String a = "([+-]?[1-9][0-9]*)?(\\*?[+-]?x(\\^([+-]?[1-9][0-9]*))?)?";
通过group()来取出系数和指数来进行处理,同时使用大数做系数指数的处理(测试数据需要使用大数)
注意最后一个测试点加号输入有问题
2*x^3+2*x^6

带+
输出: 6x^2+12x^5

不带+
输出: 6x^212x^5

最后一个测试点: 输出× 不输出√

三、踩坑心得

7-8 判断三角形类型
做直角三角形判断处理时不能直接用a*a+b*b==c*c需要使用a*a+b*b-c*c<0.00000001来进行相等判断
否则会因为计算精度不足而导致错一个测试点
题目集二7-4以及7-5写时尽量细心看自己的逻辑处理判断是否有误,同时用数组存储每月对应天数,方便处理,不用使用过多if elsedebug时也相对直观
题目集三7-2同上,7-3使用正则表达式做字符匹配比手动做模拟方便很多,一定一定要注意最后一个测试点的+的输出,否则debug怎么都de不出来。
正则基础

四、改进建议

写java时还是有些面向过程,同时代码的书写不够规范,对于类的设计不够清晰有序,应当做到单一职责原则,以及耦合度需要注意,还有很多的java方法使用不熟练,不了解,在书写时都需要上网查询如何使用,应当进一步的学习。

五、总结

学会了Java的环境配置
通过题目集1~3的学习,学习了java的基本语法,学习了正则表达式的使用,进一步了解了面向对象,对于java的各种方法还需要更多更深入的练习和学习去熟悉,不停留在面向过程,让自己的书写代码时更加面向对象,建议课程没必要强制观看慕课,慕课应作为课后查漏补缺的补足。作业题目难度循序渐进。
希望能修改题目集三最后一题的测试点

posted @ 2021-10-15 23:55  Kerom  阅读(73)  评论(0)    收藏  举报