题目集1~3总结

(1)前言:

题目集01:知识点多为基础知识,如顺序结构,选择结构,循环结构等,要求对else if语句的使用需掌握较好。一共八道题,其中第八题涉及的情况较多,容易遗漏。

题目集02:知识点为对方法、一维数组的运用。共五道题,其中7-1 7-4 7-5难度较大,一些错误较难发现。

题目集03:考察了对定义类的掌握,三道题目,第三题分值最高,涉及了正则表达式的运用,较难。

(2)设计与分析:

题目集01:7-8判断三角形类型输入三角形三条边,判断该三角形为什么类型的三角形。

输入格式:

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

提交源码:

 

import java.util.Scanner;

public class Main {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner input = new Scanner(System.in);

double a = input.nextDouble();

double b = input.nextDouble();

double c = input.nextDouble();

if((a >= 1 && a<=200) && (b >= 1 && b <=200) && (c >= 1 && c <= 200))

{

if((a + b > c) && (a + c > b) && (b + c > a))//panduan

{

if(a == b && b == c)//

 

System.out.println("Equilateral triangle");

else if((a == b && a*a + b*b == c*c) || (b == c && b*b + c*c == a*a) || (a == c && a*a + c*c == b*b))

 

System.out.println("Isosceles right-angled triangle");

 

else if((a*a + b*b == c*c) || (b*b + c*c == a*a) || (a*a + c*c == b*b))

 

System.out.println("Right-angled triangle");

 

else if((a == b) || (b == c) || (a == c))

 

System.out.println("Isosceles triangle");

else

 

System.out.println("General triangle");

}

else

{

System.out.println("Not a triangle");

}

}

else

{

System.out.println("Wrong Format");

}

}

}

在设计判断时,应注意判断三角形类别的先后顺序。例如:应先判断是否为等腰三角形,再判断是否为等腰直角三角形。此外,还应注意各种条件时彼此的关系(&& 与 ||的使用)、对三角形成立的条件(数学逻辑)、边的满足范围、等腰、直角、等边成立的条件清晰。另外的细节就是,不能把不满足三角形成立的情况与非法输入的情况混淆,这两种情况的输出是不同的。

题目集02: 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) ; //求输入日期的下一天

输入格式:

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

输出格式:

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

提交源码:

 

import java.util.Scanner;

 

public class Main {

public static boolean isLeapYear(int year)//判断year是否为闰年,返回boolean类型;

{

boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

return isLeapYear;

}

public static boolean checkInputValidity(int year,int month,int day)//判断输入日期是否合法,返回布尔值

{

int []MONTH=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};

if(isLeapYear(year))

{

MONTH[1]=29;

}

boolean checkInputValidity = (year>=1820&&year<=2020)&&(month<=12&&month>=1)&&(day>0&&day<=MONTH[month-1]);

return checkInputValidity;

}

public static void nextDate(int year,int month,int day)//求输入日期的下一天,跨年,月,平年二月

{

int []MONTH=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};

if(isLeapYear(year))

{

MONTH[1]=29;

}

int x=0,y=0,z=0;

if(checkInputValidity(year,month,day))

{

if(month==12)

{

if(day==MONTH[11])

{

x=year+1;

y=1;

z=1;

}

if(day>0&&day<MONTH[month-1])

{

x=year;

y=month;

z=day+1;

}

}

if(month!=12)

{

if(day==MONTH[month-1])

{

x=year;

y=month+1;

z=1;

}

if(day>0&&day<MONTH[month-1])

{

x=year;

y=month;

z=day+1;

}

}

System.out.println("Next date is:"+x+"-"+y+"-"+z);

}

else

{

System.out.println("Wrong Format");

}

}

public static void main(String[] args)//主方法

{

Scanner input = new Scanner(System.in);

int a = input.nextInt();

int b = input.nextInt();

int c = input.nextInt();

nextDate(a,b,c);

}

}

题目的要求是求下一天,应将跨月,跨年的特殊情况单独罗列讨论,而跨月应注意闰年二月有29天,以及其他月份的天数(30/31)。因此,闰年的判断条件也应注意,闰年的判断条件为(year % 4 == 0 && year % 100 != 0) || year % 400 == 0。还需要注意的有年份的区间范围为[1820,2020],月为[1,12],日期根据各月天数创建数组。

题目集02:7-5 求前N天 (30 分)

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

输入格式:

在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。

输出格式:

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

提交源码:

 

 

import java.util.Scanner;

import java.lang.*;

 

public class Main {

public static boolean isLeapYear(int year)//判断year是否为闰年,返回boolean类型;

{

boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

return isLeapYear;

}

public static boolean checkInputValidity(int year,int month,int day,int n)//判断输入日期是否合法,返回布尔值

{

int []MONTH=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};

if(isLeapYear(year))

{

MONTH[1]=29;

}

boolean checkInputValidity = (year>=1820&&year<=2020)&&(month<=12&&month>=1)&&(day>0&&day<=MONTH[month-1])&&(n>=-10&&n<=10);

return checkInputValidity;

}

public static void nextDate(int year,int month,int day,int n)//求输入日期的后n天(n<0),跨年,月,平年二月

{

int []MONTH=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};

if(isLeapYear(year))

{

MONTH[1]=29;

}

int x=0,y=0,z=0;

if(checkInputValidity(year,month,day,n))

{

if(month==12)//跨年

{

if((day-n)>MONTH[11])

{

x=year+1;

y=1;

z=(day-n)-31;

}

if(day>0&&(day-n)<=MONTH[month-1])//不跨年

{

x=year;

y=month;

z=day-n;

}

}

if(month!=12)

{

if((day-n)>MONTH[month-1])

{

x=year;

y=month+1;

z=(day-n)-MONTH[month-1];

}

if(day>0&&(day-n)<=MONTH[month-1])

{

x=year;

y=month;

z=day-n;

}

}

System.out.println(n+" days ago is:"+x+"-"+y+"-"+z);

}

else

{

System.out.println("Wrong Format");

}

}

public static void ndaysago(int year,int month,int day,int n)//n为正数

{

int []MONTH=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};

if(isLeapYear(year))

{

MONTH[1]=29;

}

int x=0,y=0,z=0;

if(checkInputValidity(year,month,day,n))

{

if(month==1)//倒退一年

{

if((day-n)<=0)

{

x=year-1;

y=12;

z=31-(n-day);

}

if(day>0&&(day-n)>0)//1月不退年

{

x=year;

y=month;

z=day-n;

}

}

if(month!=1)

{

if((day-n)<=0)

{

x=year;

y=month-1;

z=MONTH[month-2]-(n-day);

}

if(day>0&&(day-n)>0)

{

x=year;

y=month;

z=day-n;

}

}

System.out.println(n+" days ago is:"+x+"-"+y+"-"+z);

}

else

{

System.out.println("Wrong Format");

}

}

public static void main(String[] args) {

Scanner input = new Scanner (System.in);

int year = input.nextInt();

int month = input.nextInt();

int day = input.nextInt();

int n = input.nextInt();

if(n>0)

{

ndaysago(year,month,day,n);

}

else if(n<0)

{

nextDate(year,month,day,n);

}

else

{

System.out.println(n+" days ago is:"+year+"-"+month+"-"+day);

}

 

}

}

此题相比上题虽有较多重复,但新涉及了求过去的日期。根据n的正负,分两种情况进行讨论。前/后n天就要判断输入+/-n天是否会跨月,跨年,闰年情况与上题相同,也应考虑在内。

题目集03:7-2 定义日期类 (28 分)

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

要求:Date类结构如下图所示:

输入格式:

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

输出格式:

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

提交源码:

import java.time.LocalDate;

import java.util.Scanner;

class Date {

    private int year;

    private int month;

    private int day;

 

    //无参构造

    public Date() {

    }

 

    //构造方法

    public Date(int year, int month, int day) {

        this.year = year;

        this.month = month;

        this.day = day;

    }

 

    public int getYear() {

        return year;

    }

 

    public void setYear() {

        this.year = year;

    }

 

    public int getMonth() {

        return month;

    }

 

    public void setMonth(int month) {

        this.month = month;

    }

 

    public int getDay() {

        return day;

    }

 

    public void setDay(int day) {

        this.day = day;

    }

 

    public static boolean isLeapYear(int year)//判断year是否为闰年,返回boolean类型;

    {

        boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

        return isLeapYear;

    }

 

    public static boolean checkInputValidity(int year, int month, int day)//判断输入日期是否合法,返回布尔值

    {

        int[] MONTH = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        if (isLeapYear(year)) {

            MONTH[1] = 29;

        }

        boolean checkInputValidity = (year >= 1900 && year <= 2000) && (month <= 12 && month >= 1) && (day > 0 && day <= MONTH[month - 1]);

        return checkInputValidity;

    }

 

    public void getNextDate(int year, int month, int day)//求输入日期的下一天,跨年,月,平年二月

    {

        int[] MONTH = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

        if (isLeapYear(year)) {

            MONTH[1] = 29;

        }

        int x = 0, y = 0, z = 0;

        if (checkInputValidity(year, month, day)) {

            if (month == 12) {

                if (day == MONTH[11]) {

                    x = year + 1;

                    y = 1;

                    z = 1;

                }

                if (day > 0 && day < MONTH[month - 1]) {

                    x = year;

                    y = month;

                    z = day + 1;

                }

            }

            if (month != 12) {

                if (day == MONTH[month - 1]) {

                    x = year;

                    y = month + 1;

                    z = 1;

                }

                if (day > 0 && day < MONTH[month - 1]) {

                    x = year;

                    y = month;

                    z = day + 1;

                }

            }

            System.out.println("Next day is:" + x + "-" + y + "-" + z);

        } else {

            System.out.println("Date Format is Wrong");

        }

    }

}

public class Main{

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        int year = input.nextInt();

        int month = input.nextInt();

        int day = input.nextInt();

        Date yxf = new Date(year,month,day);

        yxf.getNextDate(year,month,day);

    }

}

根据题目要求,可知题目要求有<constructor>的两个方法,一个是无参构造方法,一个是实参构造方法,还包括三个私有属性(注意是私有属性,应用private定义)的访问器和修改器方法,而判断闰年,检查输入合法性,求下一天日期的方法可以从题目集02 7-4中拷贝,省时省力。要注意访问器和修改器方法的返回类型。

题目集03:7-3 一元多项式求导(类设计) (50 分)

编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf

输入格式:

在一行内输入一个待计算导函数的表达式,以回车符结束。

输出格式:

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

该题目难度较大,搜索资料也没完全掌握正则表达式用法,未提交源码。

(3)踩坑心得:

题目集01 7-8的三角形判断似乎存在浮点型误差问题,我认为我的逻辑没有错误,输入各种情况的三条边长都能输出正确的结果,但就是有一个点过不去。。然后问了同学,似乎是条件中忽略了对浮点型误差的考虑。

题目集02 7-4 7-5日期类的题目月份数组应注意二月应该是数组month[1]而不是[2],当然,也可以在数组前加一个数字,使二月对应的元素的索引为2;7-5要注意n天后是否已经跨月、跨年,求过去N天要注意1月的特殊情况(我一开始忘记了)。

题目集03 7-1注意保留两位小数的方法,我用的是String format,java中保留两位小数的方法有很多种,可以在csdn上学习,包括获取当地时间的方法。然后要注意要在主方法种创建对象。在7-2中同样需要注意这点,若不创建则无法调用方法。

(4)改进建议:对题目集02中合并数组的方法我觉得有所改进,我采用的使arraycopy的方法,将a数组复制给c,再将b数组复制给c(通过java自带的arraycopy方法),然后将c数组选择排序,形成了有序的新数组。但我觉得这样做有点麻烦,是否有更简便方法?直接将b数组接在a数组后,再排序。或许更快,代码量更小。

(5)总结:通过本阶段三次题目集的综合性训练,我学习了很多的知识:数据类型转换,随机产生数字,获取本地时间,统计本地时间距1970/1/1多少秒,保留小数等细节方法,对java的编程风格有了进一步的认识和熟悉,在题目集03中,体会到了java与c语言的不同之处,在进阶知识方面,我应该提前学习,进行深入研究,以防下次碰到难题大脑一片空白,不知从何下手(例如题目集03 7-3)。

 

posted @ 2021-04-04 21:12  MUNICH25  阅读(86)  评论(0)    收藏  举报