题目集1~3总结

一.前言

题目集一:

难度较小,较适合初学者进行编程训练,大部分题目的知识点也只是一些简单语法,以及一些简单的计算号的训练,但对于我们初学者来说,题量和难度都差不多刚刚好,只有7-3与7-8两题较为困难。

题目集二:

难度较题目集一有较大提升,好在题量方面有所减少,但任然花费了题目集一数倍的时间去完成。

题目集二的知识点有字符串方面的转换·运算,还有对java中数组的训练。

题目集二后三题中,都在考察java日期方面的运算,虽然c语言做过了,但java来实现还是有很大不一样,而且三题的难度梯度很好,基本都是有关联的,不会说突然来一个比其他题难很多的题目。

题目集三:

题目集三相比一二难度又上了一个梯度,像第三题需要使用正则表达式,第一题训练了构造方法的使用,第二题虽然是原题,但需要遵守封装性,将题目改进,对能力也是一个提升。

二.设计与分析

题目集一7-8:

题目集一的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) {
        Scanner myscan  = new Scanner(System.in);
        double a=myscan.nextDouble();
        double b=myscan.nextDouble();
        double c=myscan.nextDouble();
        
    
        if {
            if(a+b<=c||a+c<=b||b+c<=a) {
                System.out.print("Not a triangle");
            }
            else {
                if(a==b&&a==c) {
                    System.out.print("Equilateral triangle");
                }
                else if((a==b||a==c||b==c)&&((a*a+b*b-c*c<0.000001)||(a*a+c*c-b*b<0.000001)||(b*b+c*c-a*a<0.000001))) {
                    System.out.print("Isosceles right-angled triangle");
                }
                else if(a==b||a==c||b==c) {
                    System.out.print("Isosceles triangle");
                }
                else if((a*a+b*b-c*c<0.000001)||(a*a+c*c-b*b<0.000001)||(b*b+c*c-a*a<0.000001)) {
                    System.out.print("Right-angled triangle");
                }
                else {
                    System.out.print("General triangle");
                }
            }
        }
    }
    else    {
        if(a<1||a>200||b<1||b>200||c<1||c>200) 
            System.out.print("Wrong Format");
        }
}

 

题目集二7-4:

题目集二7-4考察了类与对象,这对当时的我来说还很困难,很难考虑出所有的情况,也难以通过创造类去解决问题。好在老师给了在题目中给了很多提示,否则要我自己去建立并调用这些类,恐怕要就很难完成了。最后在一次一次的试错中完成了题目集二中的7-4。

求下一天

输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[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) ; //求输入日期的下一天
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int year = in.nextInt();
        int month = in.nextInt();
        int day = in.nextInt();
        Main.nextDate(year,month,day);

    }
    public static boolean isLeapYear(int year) {
        boolean isLeapYear;
        if( isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0);
        return true;
    }
    
    public static boolean checkInputValidity(int year,int month,int day) {
            int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
            if(isLeapYear(year))
                aa[2] = 29;
            boolean checkInputValidity;
       if(  checkInputValidity   = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=aa[month]&&day>0));
                return true;
    }
    
    public static void nextDate(int year,int month,int day) {
        int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            aa[2] = 29;
        int a = 0,b = 0,c = 0;
        if(checkInputValidity(year,month,day)) {
            if(month==12) {
                if(day==aa[month]) {
                a = year++;
                b = 1;
                c = 1;}
            if(day>0&&day<aa[month]) 
                    {a = year;
                    b = month;
                    c =day ++;
                    }
            if(month<=12) {
                if(day==aa[month]) {
                    a = year;
                    b = month ++;
                    c = 1;}
                if(day>0&&day<aa[month]) 
                        {a = year;
                        b = month;
                        c = day++;
                        }
            }
            System.out.println("Next date is:"+a+"-"+b+"-"+c);
            }
        else System.out.println("Wrong Format");
    }}

 

 

题目集二7-5:

7-5是7-4的升级版,我们需要在7-4的基础上去增加代码来实现7-5,但是老师也希望我们能通过7-4的训练,在7-5中写出更加简洁的代码,然而我当时也不知道如何再去简化,所以我只是将nextdate中的代码改了,通过加强判断月份与n的大小的可能性去完成题目。

求前n天

 

输入年月日的值(均为整型数),同时输入一个取值范围在[-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;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int year = in.nextInt();
        int month = in.nextInt();
        int day = in.nextInt();
        int n = in.nextInt();
        Main.nextDate(year,month,day,n);

    }
    public static boolean isLeapYear(int year) {
        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[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
            if(isLeapYear(year))
                aa[2] = 29;
            boolean checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=aa[month]&&day>0&&Math.abs(n)<=10&&Math.abs(n)>=0);
                return checkInputValidity;
    }
    
    public static void nextDate(int year,int month,int day,int n) {
        int[] d=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year))
            d[2] = 29;
        int a = 0,b = 0,c = 0;
        if(checkInputValidity(year,month,day,n)) {
            if (n==0) {
                a = year;
                b = month;
                c = day;
                System.out.println(n+" days ago is:"+a+"-"+b+"-"+c);
            }
            
            if(month==12&&n>0) {
                if(day-n<=d[month]) {
                    if(day-n>0) {
                        a = year;
                        b = month;
                        c = day-n;}
                    if(day-n<0) {
                        a = year;
                        b = month-1;
                        c = d[b]-n+day;
                    }
                    if(day-n<=d[month]&&day-n==0) {
                        a = year;
                        b = month-1;
                        c = d[b]-n+day;
                    }
                }
            }
            if(month==12&&n<0) {
                if(day-n>d[month]) {
                    a = year +1;
                    b = 1;
                    c =day - n -d[month];
                }
                if(day-n<=d[month]) {
                    a = year;
                    b = month;
                    c =day - n;
                }
            }
            if(month>1&&month<12&&n>0) {
                if(day-n<=d[month]) {
                    if(day-n>0) {
                        a = year;
                        b = month;
                        c = day-n;}
                    if(day-n<=d[month]&&day-n<0) {
                        a = year;
                        b = month-1;
                        c = d[b]-n+day;
                    }
                    if(day-n<=d[month]&&day-n==0) {
                        a = year;
                        b = month-1;
                        c = d[b]-n+day;
                    }
                }
            }
            if(month<12&&month>1&&n<0) {
                if(day-n>d[month]) {
                    a = year;
                    b = month+1;
                    c =day - n -d[month];
                }
                if(day-n<=d[month]) {
                    a = year;
                    b = month;
                    c =day - n;
                }
            }
            if(month == 1&&n>0) {
                if(day-n<=d[month]&&day-n>0) {
                    a = year;
                    b = month;
                    c = day-n;
                }
                if(day-n<=d[month]&&day-n<0) {
                    a = year-1;
                    b = 12;
                    c = d[b]-n+day;
                }
                if(day-n<=d[month]&&day-n==0) {
                    a = year-1;
                    b = 12;
                    c = d[b]-n+day;
                }
            }
            if(month==1&&n<0) {
                if(day-n>d[month]) {
                    a = year;
                    b = month+1;
                    c =day - n -d[month];
                }
                if(day-n<=d[month]) {
                    a = year;
                    b = month;
                    c =day - n;
                }
            }
            System.out.println(n+" days ago is:"+a+"-"+b+"-"+c);
            }
        else System.out.println("Wrong Format");
    }



}

 

题目集三7-2

虽然要实现的功能与题目集二的7-4相同,但是老师提出了要考虑封装性的要求,于是我通过this关键字把当前对象传递给其他方法来实现封装性。

7-2 定义日期类 
 

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

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

 

 

import java.util.Scanner;

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 date = new Date();
        date.setYear(year);
        date.setMonth(month);
        date.setDay(day);
        
        boolean flag = false;
        flag = date.checkInputValidity();
        if(flag) {
            date.getNextDate();
        }
        else {
            System.out.println("Date Format is Wrong");
        }
        
    }
}

class Date {
    private int year;
    private int month;
    private int day;
    private int[] mon_maxnum = new int[] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    public Date() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Date(int year, int month, int day) {
        super();
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        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 boolean isLeapYear(int year) {
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return true;
        } else {
            return false;
        }
    }

    public boolean checkInputValidity() {
        if (year < 1900 || year > 2000 || month < 1 || month > 12 || day < 1 || day > 31) {
            return false;
        } else {
            boolean flag = false;
            flag = isLeapYear(year);
            if (flag) {
                switch (month) {
                case 4:
                case 6:
                case 9:
                case 11:
                    if (day > mon_maxnum[4]) {
                        return false;
                    } else {
                        return true;
                    }
                case 2:
                    if (day > 29) {
                        return false;
                    } else {
                        return true;
                    }
                default:
                    return true;
                }
            } else {
                switch (month) {
                case 4:
                case 6:
                case 9:
                case 11:
                    if (day > mon_maxnum[4]) {
                        return false;
                    } else {
                        return true;
                    }
                case 2:
                    if (day > 28) {
                        return false;
                    } else {
                        return true;
                    }
                default:
                    return true;
                }
            }
        }
    }

    public void getNextDate() {
        if(this.month==2){
            if(isLeapYear(this.year)){
            switch(this.month){
                case 2:if(this.day!=29){
                           this.day++;
                }else{
                             this.month++;this.day = 1;
                }
            }
        }
        else{
            switch(this.month){
                case 2:if(this.day!=28){
                            this.day++;
                }else{
                    this.month++;this.day = 1;}
             }
        }}else{
            switch(this.month){
                    case 1:if(this.day!=31){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 3:if(this.day!=31){
                        this.day++;}else{
                        this.month++;day = 1;}break;
                    case 4:if(this.day!=30){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 5:if(this.day!=31){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 6:if(this.day!=30){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 7:if(this.day!=31){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 8:if(this.day!=31){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 9:if(this.day!=30){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 10:if(this.day!=31){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 11:if(this.day!=30){
                        this.day++;}else{
                        this.month++;this.day = 1;}break;
                    case 12:if(this.day!=31){
                        this.day++;}else{
                        this.year++;this.month=1;this.day = 1;}break;
            }}           System.out.print("Next day is:"+year+"-"+month+"-"+day);
    }

}

题目集三7-3:

很惭愧由于对正则表达式的不重视这道题到最后都没能很好的完成,然而最后还是完成了一部份功能。

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

编写程序性,实现对简单多项式的导函数进行求解。

输入格式:

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

输出格式:

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

 

 

 

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        String ss = s.replaceAll(" ","");
        int n = 0;
        int i = 0;
        String regex = "([-+]?([0-9]*\\.?[0-9]\\*)x\\^([+-]?[0-9]*\\.?[0-9]))|([-+]?([0-9]*\\.?[0-9]\\*)x)|([+-]?[0-9]*\\.?[0-9]+$)|([-+]?x\\^([+-]?[0-9]*\\.?[0-9]))|([-+]?x)";
        String regex0 = "([-+]?[0-9]*\\.?[0-9])";
        Pattern p = Pattern.compile(regex);
        Pattern p0 = Pattern.compile(regex0);
        Matcher m = p.matcher(ss);
        Matcher m0 = p0.matcher(ss);
        while (m0.find()){
            int s0 =Integer.parseInt (m0.group(0));
            if(s0==0)
                i++;
        }     
        if(i>0) {
            System.out.print("Wrong Format");
        }else
        while (m.find()){
            String s1 = m.group(0);
            //System.out.print(s1+" ");
            Derivation d = new Derivation(s1);
            d.sucu(n);
            n++;
        }       
    }
}
class Derivation{
    private String s;
    
    public Derivation() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Derivation(String s) {
        super();
        this.s = s;
    }

    public String getS() {
        return s;
    }

    public void setS(String s) {
        this.s = s;
    }

    public void sucu(int n) {
        String regex1 = "([-+]?[0-9]*\\.?[0-9])\\*";
        String regex2 = "x\\^([+-]?[0-9]*\\.?[0-9])";
        String regex3 = "([-+]?[0-9]*\\.?[0-9])\\*x$";
        String regex4 = "(^[+-]?[0-9]*\\.?[0-9]$)";
        String regex5 = "^([+-]?)x";
        Pattern p1 = Pattern.compile(regex1);
        Pattern p2 = Pattern.compile(regex2);
        Pattern p3 = Pattern.compile(regex3);
        Pattern p4 = Pattern.compile(regex4);
        Pattern p5 = Pattern.compile(regex5);
        Matcher m1 = p1.matcher(this.s);
        Matcher m2 = p2.matcher(this.s);
        Matcher m3 = p3.matcher(this.s);
        Matcher m4 = p4.matcher(this.s);
        Matcher m5 = p5.matcher(this.s);
        while (m1.find()&&m2.find()){
            int s1 =Integer.parseInt (m1.group(1));//字符串转化为整数
            int s2 =Integer.parseInt (m2.group(1));
            if(n>0&&s1*s2>0&&(s2-1)==1) {
                System.out.print("+"+s1*s2+"*x");
            }else if(n>0&&s1*s2>0) {
                System.out.print("+"+s1*s2+"*x^"+(s2-1));
            }else if((s2-1)==1){
                System.out.print(s1*s2+"*x");
            }else {
                System.out.print(s1*s2+"*x^"+(s2-1));
            }
        } 
        while(m3.find()) {
            int s3 =Integer.parseInt (m3.group(1));
            if(s3>0)
                System.out.print("+"+s3);
            else
                System.out.print(s3);
        }
        while(m4.find()) {
            int s4 =Integer.parseInt (m4.group(1));
            if(n==0)
                System.out.print("0");
            else
                System.out.print("");
        }
        while(m2.find()&&m5.find()) {
            int s2 =Integer.parseInt (m2.group(1));
            String ss =m5.group(1);
            int s5 = 0;
            if(m5.group(0).charAt(0)=='-') {
                s5 = -1;
            }else {
                s5 = 1;
            }
            if(n>0&&s5*s2>0&&(s2-1)==1) {
                System.out.print("+"+s5*s2+"*x");
            }else if(n>0&&s5*s2>0) {
                System.out.print("+"+s5*s2+"*x^"+(s2-1));
            }else if((s2-1)==1){
                System.out.print(s5*s2+"*x");
            }else {
                System.out.print(s5*s2+"*x^"+(s2-1));
            }
        }
        while(!m2.find()&&m5.find()) {
            String s5 =m5.group(1);
            if(n>0&&s5=="-") {
                System.out.print(s5+"1");
            }else if(n>0) {
                System.out.print("+"+"1");
            }else {
                System.out.print(s5+"1");
            }
        }
    }
}

 

三·踩坑心得

 

1.浮点数比较大小,这个我算是被坑了好多次才长记性,如,0.9循环和1相比哪个更大

这似乎显而易见,但实际上他们一样大,后来我为了应付这些情况去学了向下取整与向上取整的操作就很少会踩这种坑了。

2.要注意nextline与next的区别,next()读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后输入的空格键、Tab键或Enter键等视为分隔符或结束符。
nextLine()方法的结束符只是Enter键,即nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的.

因为这没注意两点的区别我得到过好几次空的输出。

3.java中一定要注意每个数值的类型,我常常因为这些类型用的不对而报错。

四·改进建议

题目集二7-3及7-4,7-5中的代码,当时没有想那么多,就单纯的用if else不断来判断,但现在想想的话,这似乎是我目前所以题目的通病,代码不够简洁,所以我应该多用像switch这样的语句,来减少代码的复杂度,增加可读性

 

import java.util.Scanner;

public class Main {

    
    public static int numOfDays(int year,int month ,int day) {
         int days=0;
         int i ;
          int []aa = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
          for(i=1;i<year;i++){
                if(i%4==0&&i%100!=0||i%400==0) {
                    days+=366;}
                else 
                    days+=365;
                }
         if((year % 4 == 0 && year % 100 !=0 )||year % 400 == 0) 
                aa[2]=29;
            for(i = 1;i<month;i++){
                days+=aa[i];}
                days+=day;
                return days;
    }
        public static boolean isLeapYear(int year) {
        boolean isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0;
        return isLeapYear;
    }
    public static String getWhatDay(int days) {
        int t=(days%7);
        switch(t) {
        case 0:return "Sunday";
        case 1:return "Monday";
        case 2:return "Tuesday";
        case 3:return "Wednesday";
        case 4:return "Thursday";
        case 5:return "Friday";
        default :return "Saturday";
        }}
     public static int pd(int year,int month,int day)
    {
           int pf=0;
           int[] mon1=new int[]{0,31,29,31,30,31,30,31,31,30,31,30,31};
           int[] mon2=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
           
           if(year<1820||year>2020)
           {return pf;
         
           }
           else  if(month>0&&month<=12)
              { 
                 if(isLeapYear(year))
                 {
                   if((day<=mon1[month]&&day>0)||(day<=mon2[month]&&day>0))
                   pf=1;
                 }
           }
              
              return pf;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int year =in.nextInt();
        int month = in.nextInt();
        int day = in.nextInt();
        int days = numOfDays(year,month ,day);
        if(pd(year,month,day)==1) {
        if(Main.isLeapYear(year)) {
            System.out.println(year+" is a leap year.");
            System.out.println(year+"-"+month+"-"+day+" is "+Main.getWhatDay(days)+".");
        }
        else {
            System.out.println(year+" is not a leap year.");
            System.out.println(year+"-"+month+"-"+day+" is "+Main.getWhatDay(days)+".");
             }
        }
        else System.out.println("Wrong Format");
    }

}

 

还有就是应该多使用类,不把所有的代码堆在一个函数里,要做好类的封装性,像从题目集二7-4到题目集三7-2的转变,就是一次对代码的一次很好的改进。

还要多学习一些新的java中的方法,这都是减少代码复杂度的重要方法。

五·总结

这三次题目集做下来,最大的感受就是自己的学习习惯太差了,稍微难点的题目集就有点跟不上了,向题目集三就完成的不好,需要对java这门课程付出更多努力。而在这三次训练中,我也算是有了一个蜕变,对java字符串有了入门的理解,还学会了如何比较好的完成类的封装性,对类的用法也有了更深的理解,但是我对类与类之间的其他属性也要继续学习,争取能对类有一个很好的理解。

 

posted @ 2021-04-04 22:35  shadou  阅读(101)  评论(0)    收藏  举报