题目集4~6的总结性Blog

Posted fengyufeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题目集4~6的总结性Blog相关的知识,希望对你有一定的参考价值。

目录

 

1.前言

2.设计与分析

3.踩坑心得

4.改进建议

5.总结

 

1.前言

题目集4:  (训练自我学习能力,例如treeset与hashset用法,了解一些类中的方法)

 菜单计价程序-3

 有重复的数据

 有重复的数据

 单词统计与排序

 面向对象编程(封装性)

 GPS测绘中度分秒转换

 判断两个日期的先后,计算间隔天数、周数

题目集5: (熟练正则表达式,并初步了解聚合)

 正则表达式训练-QQ号校验

 字符串训练-字符排序

 正则表达式训练-验证码校验

 正则表达式训练-学号校验

 日期问题面向对象设计(聚合一)

 日期问题面向对象设计(聚合二)

题目集6: (题目集4的迭代)

 菜单计价程序-4

 

第四次题目集,听到同学说需要使用hashset与treeset时,我不知所措,后来在csdn查它们的用法,发现会用即可,不需要了解它们的底层代码。在最后一道题我才发现其实老师提醒我们需要自学一些,初步了解了日期中有许多好用的类,为后面题目集4第一题与题目集6第一题提供了求日期的思路。

第五次题目集,主要看到前几题是属于正则表达式的,我去看了一下慕课,发现并没有主要交我们代码格式,我是通过b站自主学习,慢慢了解了方法,做了笔记,出的这些题目没有拐弯抹角,直接输出即可。主要的boss是2道聚合题,但我写时,最后还时有些瑕疵。

第六次题目集,是题目集4第一题的迭代,难度直线飙升,我开始做了4天,但都是错的,根本第一个样例都实现不了,听到老师说要写1600行代码加上好多同学都没做,直接摆烂了。

 

2.设计与分析

  7-3 去掉重复的数据
 

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

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

import java.util.LinkedHashSet;
import java.util.Scanner;
public class Main 
    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);
        int a,c=0;
        a= in.nextInt();
        int[] b=new int[a];
        int i;
        for(i=0;i<=a-1;i++)
        
            b[i]=in.nextInt();
        
        LinkedHashSet<Integer> list =new LinkedHashSet<>();
        for(i=0;i<b.length;i++)
        
            list.add(b[i]);
        
        boolean flag = true;
        for(Integer number:list)
        
            if(flag)
                System.out.print(number);
                flag = false;
            
            else
                System.out.print(" "+number);
        
    

  

这道题刚好满足hashset的基本算法用途,所以不需要在写自己的构造器,不像下一题,不满足treeset的基本算法,所以要自己写构造器来满足题目的排序要求。

7-4 单词统计与排序
 

  从键盘录入一段英文文本(句子之间的标点符号只包括“,”或“.”,单词之间、单词与标点之间都以" "分割。
  要求:按照每个单词的长度由高到低输出各个单词(重复单词只输出一次),如果单词长度相同,则按照单词的首字母顺序(不区分大小写,首字母相同的比较第二个字母,以此类推)升序输出。

 

import java.util.*;

public class Main 

    public static void main(String[] args) 

        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        String[] strr = str.split(",|\\\\ |\\\\.");
        TreeSet<String> ts=new TreeSet<String>(new MyCompartor());
        int i;
        for(i = 0;i < strr.length;i++)
            if(strr[i] != null&&strr[i].length() != 0)
                ts.add(strr[i]);
            //System.out.printf(String.valueOf(ts));
        
        //System.out.printf(String.valueOf(ts));
        //System.out.println();
        for (Iterator itr = ts.iterator(); itr.hasNext();)
            System.out.println(itr.next());
    

class MyCompartor  implements Comparator<String>


    public int compare(String o1, String o2) 
        if(o1.length() > o2.length())
            return -1;
        else if (o1.length() == o2.length())
            return o1.compareToIgnoreCase(o2);
        
        else
            return 1;
    

  这里需要查一下treeset的基本原理(先按照字典来排大写字母,再按照字典来排小写字母,不满足题目要求,所以要自己写构造器来满足题目的排序要求),写这个构造器时,ideal直接给了一些代码,自己填空即可,不是很难、

    面向对象编程(封装性) 太简单,不讲。

 GPS测绘中度分秒转换太简单,不讲。

 

判断两个日期的先后,计算间隔天数、周数
 

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

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

import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.time.*;
public class Main 
    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);
        String date1= in.nextLine();
        String date2= in.nextLine();
        String[] split = date1.split("-",4);
        String[] split1 = date2.split("-",4);
        int i;
        int[] a = new int[3];
        for(i = 0;i < 3;i++)
             a[i] = Integer.parseInt(split[i]);
            //System.out.print(a[i]);
        
        int[] b = new int[3];
        for(i = 0;i < 3;i++)
            b[i] = Integer.parseInt(split1[i]);
            //System.out.print(b[i]);
        
        int year,year1,month,month1,day,day1;
        year = a[0];
        year1 = b[0];
        month = a[1];
        month1 = b[1];
        day = a[2];
        day1 = b[2];
        LocalDate date3  = LocalDate.of(year,month,day);
        LocalDate date4  = LocalDate.of(year1,month1,day1);
        if(date3.isBefore(date4) == true)
            System.out.printf("第一个日期比第二个日期更早\\n");
        if(date3.isBefore(date4) == false)
            System.out.printf("第一个日期比第二个日期更晚\\n");

        long date5 = 0,date6 = 0;
        date5 =  date3.until(date4,ChronoUnit.DAYS);
        date6 =  date3.until(date4,ChronoUnit.WEEKS);
        //System.out.print(date5);
        System.out.printf("两个日期间隔%d天\\n",Math.abs(date5));
        System.out.printf("两个日期间隔%d周\\n",Math.abs(date6));



    

这里了解了split用法,可以把数组切开,组成新的大数组,为判断时间做了更好的安排

Integer类中parseInt()的用法,把字符串转化为整形,便于数组判断。

LocalDate类中of()、isAfter()、isBefore()直接使用,直接判断出差值与日期排序,特别方便。

LocalDate类中until()与ChronoUnit类中DAYS、WEEKS直接判断两日期之间相差多少天与多少周。

这道题主要体现自学,只要自学了,这道题非常方便解决。

 

 

 

题目集5的一些正则表达式,太简单了,我直接给出答案。

 1.正则表达式训练-QQ号校验

校验键盘输入的 QQ 号是否合格,判定合格的条件如下:

  • 要求必须是 5-15 位;
  • 0 不能开头;
  • 必须都是数字;
    import java.util.Scanner;
    
    public class Main 
    
        public static void main(String[] args) 
            Scanner in = new Scanner(System.in);
    
            String a = in.next();
            if (a.matches("^[1-9][0-9]4,14")) 
                System.out.print("你输入的QQ号验证成功");
             else 
                System.out.print("你输入的QQ号验证失败");
            
    
        
    
    

      

2.

字符串训练-字符排序

对输入的字符串中的字符进行排序并输出。

输入格式:

在一行内输入一个字符串。

输出格式:

对该字符串内的字符进行排序后(按ASCII码进行升序排序)输出。

import java.util.Scanner;

public class Main 

    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);

        String a = in.next();

        int l = a.length();

        char[] n = new char[l];

        for (int i = 0; i < l; i++) 
            n[i] = a.charAt(i);
        

        for (int i = 0; i < l - 1; i++) 
            for (int j = i + 1; j < l; j++) 
                if (n[i] > n[j]) 
                    char t = n[i];
                    n[i] = n[j];
                    n[j] = t;
                
            
        

        System.out.print(n);
    

  

3.

正则表达式训练-验证码校验
 

接受给定的字符串,判断该字符串是否属于验证码。验证码是由四位数字或者字母(包含大小写)组成的字符串。

import java.util.Scanner;

public class Main 

    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);

        String a = in.next();
        if (a.matches("[0-9a-zA-Z]4")) 
            System.out.print(a +  "属于验证码");
         else 
            System.out.print(a + "不属于验证码");
        

    

  

正则表达式训练-学号校验
 

对软件学院2020级同学学号进行校验,学号共八位,规则如下:

  • 1、2位:入学年份后两位,例如20年
  • 3、4位:学院代码,软件学院代码为20
  • 5位:方向代码,例如1为软件工程,7为物联网
  • 6位:班级序号
  • 7、8位:学号(序号)

要求如下:

  • 只针对2020级
  • 其中软件工程专业班级分别为:202011~17、61,物联网工程专业班级为202071~202073,数据科学与大数据专业班级为202081~82
  • 每个班级学号后两位为01~40
import java.util.Scanner;

public class Main 

    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);

        String a = in.next();
        if (a.matches("^2020(61|1[1-7]|7[1-3]|8[1-2])([1-3][0-9]|40|0[1-9])$")) 
            System.out.print("正确");
         else 
            System.out.print("错误");
        

    

  

接下来我重点叙述2个聚合与2个菜单

日期问题面向对象设计(聚合一)

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

 

import java.util.Scanner;
public class Main 
    public static void main(String[] args) 
        Scanner in=new Scanner(System.in);
        int x=in.nextInt();
        if(x==1) 
            int year=in.nextInt();
            int month=in.nextInt();
            int day=in.nextInt();
            int n=in.nextInt();
            DateUtil date =new DateUtil(day,month,year);
            if(date.checkInputValidity()==false) 
                System.out.println("Wrong Format");
                System.exit(0);
            
            else 
                date.getNextNDays(n);
                date.showDate();
            
        
        if(x==2) 
            int year=in.nextInt();
            int month=in.nextInt();
            int day=in.nextInt();
            int n=in.nextInt();
            DateUtil date=new DateUtil(day,month,year);
            if(date.checkInputValidity()==false) 
                System.out.println("Wrong Format");
                System.exit(0);
            
            else 
                date.getPrviousNDays(n);
                date.showDate();
            
        
        if(x==0)
            System.out.println("Wrong Format");
        
        if(x==3) 
            int year=in.nextInt();
            int month=in.nextInt();
            int day=in.nextInt();
            int year2=in.nextInt();
            int month2=in.nextInt();
            int day2=in.nextInt();
            DateUtil date1=new DateUtil(day,month,year);
            DateUtil date2=new DateUtil(day2,month2,year2);
            if(date1.checkInputValidity()==false||date2.checkInputValidity()==false) 
                System.out.println("Wrong Format");
                System.exit(0);
            
            if(year==year2&&month==month2&day==day2) 
                System.out.println(0);
            
            else 

                System.out.println(date1.getDaysofDates(date2));
            
        
    

 class Year

    private int value;
    Year()
    
    Year(int value)
        
        this.value=value;
    
    public int getValue() 
        return value;
    
    public void setValue(int value) 
        this.value = value;
    
    public boolean isLeapYear() 
        if((value % 4 == 0 && value % 100 !=0 )||(value % 400 == 0)) 
            return true;
        
        else
            return false;
    
    public boolean validate() 
        if(value<1900||value>2050) 
            return false;
        
        else
            return true;
    
    public void yearIncrement() 
        
        value=value+1;
    
    public void yearReduction() 
        
        value=value-1;
    

 class Month

    private int value;
    private Year year;
    Month()
    
    Month(int yearValue,int monthValue)
        this.value=monthValue;
        this.year=new Year(yearValue);
    
    public int getValue() 

        return value;
    
    public void setValue(int value) 

        this.value = value;
    
    public Year getYear() 

        return year;
    
    public void setYear(Year year) 

        this.year = year;
    
    public void resetMin() 

        value=1;
    
    public void resetMax() 

        value=12;
    
    public boolean validate() 
        if(value>12||value<1) 
            return false;
        
        else 
            return true;
        
    
    public int monthget()
        int x;
        if(value==1||value==3||value==5||value==7||value==8||value==10||value==12) 
            x=31;
            return x;
        
        else if(value==4||value==6||value==9||value==11) 
            x=30;
            return x;
        
        else if(value==2) 
            if(year.isLeapYear()==true) 
                x=29;
                return 29;
            
            else 
                x=28;
                return x;
            
        
        return 0;
    
    public void monthIncrement() 
        if(value<12) 
            value++;
        
        else 
            value=1;          //Month 变成 1。
            year.yearIncrement();            //year 加1,
        
    
    public void monthReduction() 
        if(value>1) 
            value--;
        
        else 
            value=12;
            year.yearReduction();
        
    


 class Day 
    private int value;
    private Month month;
    int []monmaxnum= 31,28,31,30,31,30,31,31,30,31,30,31;
    Day()
    
    Day(int yearvalue,int monthvalue,int dayvalue)
        this.value=dayvalue;
        this.month=new Month(yearvalue,monthvalue);
    

    public int getValue() 
        return value;
    
    public void setValue(int value) 
        this.value = value;
    
    public Month getMonth() 
        return month;
    
    public void setMonth(Month month) 
        this.month = month;
    
    public void resetMin() 
        value=1;
    
    public void resetMax() 
        int i;
        if(month.getYear().isLeapYear()==true) 
            monmaxnum[1]=29;
        
        else 
            monmaxnum[1]=28;
        
        value=monmaxnum[month.getValue()-1];
    
    public boolean validate() 
        if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10||month.getValue()==12)
            if(value<1||value>31) 
                return false;
            
            else 
                return true;
            
        
        if(month.getValue()==4||month.getValue()==6||month.getValue()==9||month.getValue()==11) 
            if(value<1||value>30) 
                return false;
            
            else 
                return true;
            
        
        if(month.getYear().isLeapYear()==true) 
            if(value<1||value>29) 
                return false;
            
            else 
                return true;
            
        

        else if(month.getYear().isLeapYear()==false) 
            if(value<1||value>28) 
                return false;
            
        
        else 
            return true;
        

        return true;
    


    public void DayIncrement() 
        int days=month.monthget();
        if(value<days) 
            value++;
        
        else 
            value=1;
            month.monthIncrement();
        
    
    public void DayReduction() 
        int days=month.monthget();
        if(value>=2) 
            value--;
        
        else 
            month.monthReduction();
            value=month.monthget();
        
    


class DateUtil 
    private Day day;
    DateUtil()
    
    DateUtil(int d,int m,int y)
        this.day=new Day(y,m,d);
    
    public Day getDay() 
        return day;
    
    public void setDay(Day day) 
        this.day = day;
    
    public boolean checkInputValidity() 
        if(day.getMonth().getYear().validate()==false||day.getMonth().validate()==false||day.validate()==false) 
            return false;
        
        else 
            return true;
        
    
    public boolean compareDates(DateUtil date) 
        if(date.day.getMonth().getYear().getValue()>day.getMonth().getYear().getValue()) 
            return true;
        
        if(date.day.getMonth().getYear().getValue()<day.getMonth().getYear().getValue()) 
            return false;
        
        if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getMonth().getValue()>day.getMonth().getValue()) 
            return true;
        
        if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getMonth().getValue()<day.getMonth().getValue()) 
            return false;
        
        if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getMonth().getValue()==day.getMonth().getValue()&&date.day.getValue()>day.getValue()) 
            return true;
        
        if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getMonth().getValue()==day.getMonth().getValue()&&date.day.getValue()<day.getValue()) 
            return false;
        

        return false;
    
    public boolean equalTwoDates(DateUtil date) 
        if(date.day.getMonth().getYear().getValue()==day.getMonth().getYear().getValue()&&date.day.getMonth().getValue()==day.getMonth().getValue()&&date.day.getValue()==day.getValue()) 
            return true;
        
        else
            return false;
    
    public void showDate() 
        System.out.println(day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue());
    
    public DateUtil getNextNDays(int n) 
        int i;
        for(i=0;i<n;i++) 
            day.DayIncrement();
        
        return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
    
    public DateUtil getPrviousNDays(int n) 
        int i;
        for(i=0;i<n;i++) 
            day.DayReduction();
        
        return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
    
    public int getDaysofDates(DateUtil date) 
        int a=0;
        if(compareDates(date)==true) 
            while(compareDates(date)==true) 
                day.DayIncrement();
                a++;

            
            return a;
        
        if(compareDates(date)==false) 
            while(compareDates(date)==false) 
                date.day.DayIncrement();
                a++;
                if(equalTwoDates(date)==true) 
                    break;
                
            
            return a;
        
        else
            return 0;
    

  

我的类图

 

我的类图基本满足老师给的类图,从图中我们直接看出它们的耦合性太强,操作性不强

 

 

我的思路与之前的一样,先管下n天与前n天的算法

 

我先写了这两个功能,但是它又是出现了月份越界与天数越界,因为我用的是累加,使得我最后的数值可能会超过int的边界值,起初我都没在意,接着写求2天的差的功能,代码一交,它直接让我所有测试点都过了,搞的我一脸懵,但是还是开心的。

 

 

 

 

 

 

最终这道题还是稳稳拿下,主要还是老师给了类图且注释了该方法的具体作用,我们只需要搭建框架写功能即可。整体难度不高,这道题让我们初步了解聚合的使用。

 

 日期问题面向对象设计(聚合二)
 

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

import java.util.Scanner;
public class Main
    public static void main(String[] args) 
        Scanner in = new Scanner(System.in);
        int x = in.nextInt();
        if(x == 1) 
            Year year = new Year(in.nextInt());
            Month  month = new Month(in.nextInt());
            Day day = new Day(in.nextInt());
            int n = in.nextInt();
            DateUtil date = new DateUtil(year,month,day);
            if(date.checkInputValidity() == false)
                System.out.println("Wrong Format");
            else 
                System.out.printf("%d-%d-%d next %d days is:",year.getValue(),month.getValue(),day.getValue(),n);
                date.getNextNDays(n);

            
        
        if(x == 2)
            Year year = new Year(in.nextInt());
            Month  month = new Month(in.nextInt());
            Day day = new Day(in.nextInt());
            int n = in.nextInt();
            DateUtil date = new DateUtil(year,month,day);
            if(date.checkInputValidity() == false)
                System.out.println("Wrong Format");
            else 
                System.out.printf("%d-%d-%d previous %d days is:",year.getValue(),month.getValue(),day.getValue(),n);
                date.getPreviousNDays(n);
            

        
        if(x == 3)
            Year year=new Year(in.nextInt());
            Month month=new Month(in.nextInt());
            Day day=new Day(in.nextInt());
            Year year2=new Year(in.nextInt());
            Month month2=new Month(in.nextInt());
            Day day2=new Day(in.nextInt());
            DateUtil date1=new DateUtil(year,month,day);
            DateUtil date2=new DateUtil(year2,month2,day2);
            if((date1.checkInputValidity() == false)||(date2.checkInputValidity() == false))
            
                System.out.println("Wrong Format");
                System.exit(0);
            //对两次输入的年月日都做合法性检验
            else
                date1.getDaysofDates(year.getValue(),month.getValue(),day.getValue(),year2.getValue(),month2.getValue(),day2.getValue());

        
        if(x == 0)
            System.out.println("Wrong Format");
            System.exit(0);
        
    

class Month
    private int value;

    public Month() 
    

    public Month(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    public void resetMin()
        value = 1;
    
    public void resetMax()
        value = 12;
    
    public boolean validate()
        if(value>=1&&value<=12)
            return true;
        else return false;
    
    public void monthIncrement()
        value += 1;
    
    public void monthReduction()
        value -= 1;
    

class Year
    private int value;
    public Year() 
    
    public Year(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    public boolean isLeapYear()
        if(value%400==0||(value%4==0&&value%100!=0))
            return true;
        else return false;
    
    public boolean validate()
        if(value>=1820&&value<=2020)
            return true;
        else return false;
    
    public void dayIncrement()
        value += 1;
    
    public void yearReduction()
        value -= 1;
    


class Day
    private int value;

    public Day() 
    

    public Day(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    public void dayIncrement()
        value += 1;
    
    public void dayReduction()
        value -= 1;
    

class DateUtil
    private Year year;
    private Month month;
    private Day day;
    private int []monmaxnum=0,31,28,31,30,31,30,31,31,30,31,30,31;
    public DateUtil() 
    
    public DateUtil(Year year, Month month, Day day) 
        this.year = year;
        this.month = month;
        this.day = day;
    

    public Year getYear() 
        return year;
    

    public void setYear(Year year) 
        this.year = year;
    

    public Month getMonth() 
        return month;
    

    public void setMonth(Month month) 
        this.month = month;
    

    public Day getDay() 
        return day;
    

    public void setDay(Day day) 
        this.day = day;
    
    public void setDayMin()
        day.setValue(1);
    
    public void setDayMax()
        if(year.isLeapYear()==true) 
            if (month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10 || month.getValue() == 12)
                day.setValue(31);
            else if (month.getValue() == 4 || month.getValue() == 6 || month.getValue() == 9 || month.getValue() == 11)
                day.setValue(30);
            else
                day.setValue(29);
        
        else
        
            if (month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10 || month.getValue() == 12)
                day.setValue(31);
            else if (month.getValue() == 4 || month.getValue() == 6 || month.getValue() == 9 || month.getValue() == 11)
                day.setValue(30);
            else
                day.setValue(28);
        
    
    public boolean checkInputValidity() 

        boolean p=false;
        if(year.getValue()<1820||year.getValue()>2020)
        
            return false;
        
        if(month.getValue()<1||month.getValue()>12)
        
            return false;
        
        else if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10||month.getValue()==12) 
            if (day.getValue() <= 31) 
                p = true;
             else 
                p = false;
            
        
        else if(month.getValue()==2) 
            if(year.getValue()%400==0||(year.getValue()%4==0&&year.getValue()%100!=0)) 
                if(day.getValue()<=29) 
                    p=true;
                
                else 
                    p=false;
                
            
            else 
                if(day.getValue()<=28)
                    p=true;
                
                else 
                    p=false;
                
            
        
        else 
            if(day.getValue()<=30)
                p=true;
            
            else 
                p=false;
            
        
        return p;
    
    public void getNextNDays(int n)
        int a[]= 0,31,28,31,30,31,30,31,31,30,31,30,31;
        day.setValue(day.getValue()+n);
        if(isLeapYear(year.getValue()))
            a[2] = 29;
        else
            a[2] = 28;
        while (day.getValue()>a[month.getValue()]) 
            day.setValue(day.getValue()-a[month.getValue()]);
            month.setValue(month.getValue() + 1);
            if (month.getValue() == 13)
            
                month.setValue(month.getValue() - 12);
                year.setValue(year.getValue() + 1);
            
            if(isLeapYear(year.getValue()))
                a[2] = 29;
            else
                a[2] = 28;
        
        System.out.printf("%d-%d-%d",year.getValue(),month.getValue(),day.getValue());
    
    public void getPreviousNDays(int n)
        int a[]= 0,31,28,31,30,31,30,31,31,30,31,30,31;
        day.setValue(day.getValue()-n);
        if(isLeapYear( year.getValue()))
            a[2] = 29;
        else
            a[2] = 28;
        while (day.getValue()<=0)
        
            month.setValue(month.getValue()-1);
            if (month.getValue()==0)
                month.setValue(month.getValue() + 12);
                year.setValue(year.getValue() - 1);
            
            day.setValue(day.getValue()+a[month.getValue()]);
            if(isLeapYear( year.getValue()))
                a[2] = 29;
            else
                a[2] = 28;
        
        System.out.printf("%d-%d-%d", year.getValue(), month.getValue(),day.getValue());
    
    public void getDaysofDates(int year, int month, int day, int year2, int month2, int day2)  //这里我试了一个暴力方法,直接算日期所拥有的时间。
        int startday=0;
        int endday=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) 
                startday += 366;
            
            else
                startday+=365;
        
        if((year % 4 == 0 && year% 100 !=0 )||year% 400 == 0)
            aa[2]=29;

        for(i = 1;i<month;i++)
            startday += aa[
            else
                endday+=365;
        
        if(( year2 % 4 == 0 && year2% 100 !=0 )||year2 % 400 == 0)
            aa[2]=29;

        for(i = 1;i<month2;i++)
            endday += aa[i];
        endday += day2;
        System.out.printf("The days between %d-%d-%d and %d-%d-%d are:%d",year,month,day,year2,month2,day2,Math.abs(startday-endday));//这里用了绝对值,这样我们不需要判断两日期的前后顺序与大小。
    
    public boolean isLeapYeari];
        
        startday = startday + day;
        for(i = 1;i < year2;i++)
            if(i%4 == 0&&i%100 != 0||i%400 == 0) 
                endday+=366;
            (int year) 
        return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) ? true : false;
    

  

 

我的思路与之前的一样,先管下n天与前n天的算法

 

我看到这里我就知道,这道题应该稳了,只是数据越界问题,我以为我写完完整代码,也会直接过

 

 

import java.util.Scanner;
public class Main
    public static void main(String[] args) 
        Scanner in=new Scanner(System.in);
        int x=in.nextInt();
        if(x==1) 
            Year year=new Year(in.nextInt());
            Month  month=new Month(in.nextInt());
            Day day=new Day(in.nextInt());
            int n=in.nextInt();
            DateUtil date=new DateUtil(year,month,day);
            if(date.checkInputValidity()==false)
                System.out.println("Wrong Format");
            else 
                System.out.printf("%d-%d-%d next %d days is:",year.getValue(),month.getValue(),day.getValue(),n);
                date.getNextNDays(n);

            
        
        if(x == 2)
            Year year=new Year(in.nextInt());
            Month  month=new Month(in.nextInt());
            Day day=new Day(in.nextInt());
            int n=in.nextInt();
            DateUtil date=new DateUtil(year,month,day);
            if(date.checkInputValidity()==false)
                System.out.println("Wrong Format");
            else 
                System.out.printf("%d-%d-%d previous %d days is:",year.getValue(),month.getValue(),day.getValue(),n);
                date.getPreviousNDays(n);
            

        
        if(x == 0)
            System.out.println("Wrong Format");
            System.exit(0);
        
    

class Month
    private int value;

    public Month() 
    

    public Month(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    void resetMin()
        value=1;
    
    void resetMax()
        value=12;
    
    boolean validate()
        if(value>=1&&value<=12)
            return true;
        else return false;
    
    void monthIncrement()
        value+=1;
    
    void monthReduction()
        value-=1;
    

class Year
    private int value;
    public Year() 
    
    public Year(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    boolean isLeapYear()
        if(value%400==0||(value%4==0&&value%100!=0))
            return true;
        else return false;
    
    boolean validate()
        if(value>=1820&&value<=2020)
            return true;
        else return false;
    
    void dayIncrement()
        value+=1;
    
    void yearReduction()
        value-=1;
    


class Day
    private int value;

    public Day() 
    

    public Day(int value) 
        this.value = value;
    

    public int getValue() 
        return value;
    

    public void setValue(int value) 
        this.value = value;
    
    void dayIncrement()
        value+=1;
    
    void dayReduction()
        value-=1;
    

class DateUtil
    private Year year;
    private Month month;
    private Day day;
    private int []monmaxnum=0,31,28,31,30,31,30,31,31,30,31,30,31;
    public DateUtil() 
    
    public DateUtil(Year year, Month month, Day day) 
        this.year = year;
        this.month = month;
        this.day = day;
    

    public Year getYear() 
        return year;
    

    public void setYear(Year year) 
        this.year = year;
    

    public Month getMonth() 
        return month;
    

    public void setMonth(Month month) 
        this.month = month;
    

    public Day getDay() 
        return day;
    

    public void setDay(Day day) 
        this.day = day;
    
    void setDayMin()
        day.setValue(1);
    
    void setDayMax()
        if(year.isLeapYear()==true) 
            if (month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10 || month.getValue() == 12)
                day.setValue(31);
            else if (month.getValue() == 4 || month.getValue() == 6 || month.getValue() == 9 || month.getValue() == 11)
                day.setValue(30);
            else
                day.setValue(29);
        
        else
        
            if (month.getValue() == 1 || month.getValue() == 3 || month.getValue() == 5 || month.getValue() == 7 || month.getValue() == 8 || month.getValue() == 10 || month.getValue() == 12)
                day.setValue(31);
            else if (month.getValue() == 4 || month.getValue() == 6 || month.getValue() == 9 || month.getValue() == 11)
                day.setValue(30);
            else
                day.setValue(28);
        
    
    boolean checkInputValidity() 

        boolean p=false;
        if(year.getValue()<1820||year.getValue()>2020)
        
            return false;
        
        if(month.getValue()<1||month.getValue()>12)
        
            return false;
        
        else if(month.getValue()==1||month.getValue()==3||month.getValue()==5||month.getValue()==7||month.getValue()==8||month.getValue()==10||month.getValue()==12) 
            if (day.getValue() <= 31) 
                p = true;
             else 
                p = false;
            
        
        else if(month.getValue()==2) 
            if(year.getValue()%400==0||(year.getValue()%4==0&&year.getValue()%100!=0)) 
                if(day.getValue()<=29) 
                    p=true;
                
                else 
                    p=false;
                
            
            else 
                if(day.getValue()<=28)
                    p=true;
                
                else 
                    p=false;
                
            
        
        else 
            if(day.getValue()<=30)
                p=true;
            
            else 
                p=false;
            
        
        return p;
    
    void getNextNDays(int n)
        int a[]= 0,31,28,31,30,31,30,31,31,30,31,30,31;
        day.setValue(day.getValue()+n);
        if(isLeapYear(year.getValue()))
            a[2]=29;
        else
            a[2]=28;
        while (day.getValue()>a[month.getValue()]) 
            day.setValue(day.getValue()-a[month.getValue()]);
            month.setValue(month.getValue()+1);
            if (month.getValue()==13)
            
                month.setValue(month.getValue()-12);
                year.setValue(year.getValue()+1);
            
            if(isLeapYear(year.getValue()))
                a[2]=29;
            else
                a[2]=28;
        
        System.out.printf("%d-%d-%d",year.getValue(),month.getValue(),day.getValue());
    
    void getPreviousNDays(int n)
        int a[]= 0,31,28,31,30,31,30,31,31,30,31,30,31;
        day.setValue(day.getValue()-n);
        if(isLeapYear( year.getValue()))
            a[2]=29;
        else
            a[2]=28;
        while (day.getValue()<=0)
        
            month.setValue(month.getValue()-1);
            if (month.getValue()==0)
                month.setValue(month.getValue()+12);
                year.setValue(year.getValue()-1);
            
            day.setValue(day.getValue()+a[month.getValue()]);
            if(isLeapYear( year.getValue()))
                a[2]=29;
            else
                a[2]=28;
        
        System.out.printf("%d-%d-%d", year.getValue(), month.getValue(),day.getValue());
    
    public boolean isLeapYear(int year) 
        return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) ? true : false;
    

  这是我一开始的算法,满足了2个功能。

然后我听到我同学,说用暴力算法计算2日期的差值,我试了一下,但我这算法中没有判断2日期的前后,是否相等。

我采用的是直接算日期的所拥有的天数,再二者相减,再取绝对值,再输出这个绝对值即可。结果如下。

 

 

从思路上,感觉是没问题的,还简单好多,但是这时就不会出现我上次的情况,没有满分,因为我没有判断的方法,估计就是我代码问题。因为时间不够,我做到这里就直接结束了,但是我觉得按照上面代码思路应该能做到满分。

 

 

下面是菜单问题

第一次菜单问题,

菜单计价程序-3
分数 30
作者 蔡轲
单位 南昌航空大学

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

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

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu

Dish\\[\\] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

点菜记录类:保存订单上的一道菜品记录

Record

int orderNum;//序号\\\\

Dish d;//菜品\\\\

int portion;//份额(1/2/3代表小/中/大份)\\\\

int getPrice()//计价,计算本条记录的价格\\\\

订单类:保存用户点的所有菜的信息。

Order

Record\\[\\] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\\*\\* does not exist”,\\*\\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\\*\\* does not exist”,\\*\\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

import java.util.Scanner;
import java.util.Calendar;
import java.util.Scanner;
public class Main 
    public static void main(String[] args) 
        Scanner sc = new Scanner(System.in);
        Menu mu = new Menu();
        Table[] tablemes = new Table[10];
        int j = 0;//菜单数
        int l = 0;//订单数
        int k = 0;//代点菜数
        Dish tt;
        //int sum = 0;
        int cntTable = 0;//桌号
        int count;
        String[] temp;
        int a1,a2,a3,a4,a5;

        while (true) 
            String st = sc.nextLine();
            temp = st.split(" ");
            if(st.equals("end"))
                break;
            count = temp.length;
            if (count == 2) //一个空格
                //String[] temp1 = st.split(" ");
                if (temp[1].equals("delete")) //第二个为delete
                    a1 = Integer.parseInt(temp[0]);
                    int c = tablemes[cntTable].odt.delARecordByOrderNum(a1);
                    tablemes[cntTable].sum-=c;
                 else //菜单添加
                    a2 = Integer.parseInt(temp[1]);
                    mu.dishs[j] = mu.addDish(temp[0], a2);
                    j++;
                
                //continue;
            
            else if (count == 4) //三个空格
                //String[] temp2 = st.split(" ");
                if (temp[0].equals("table")) //桌号
                    cntTable++;//跳过0;
                    l = 0;
                    tablemes[cntTable] = new Table();
                    //tablemes[cntTable].tableDtime = st;
                    tablemes[cntTable].AheadProcess(st);
                    System.out.println("table " + cntTable + ": ");
                 else //增加订单的情况;
                    a3 =Integer.parseInt(temp[0]);
                    a4 = Integer.parseInt(temp[2]);
                    a5=Integer.parseInt(temp[3]);
                    tablemes[cntTable].odt.addARecord(a3, temp[1],a4 , a5);
                    tt = mu.searthDish(temp[1]);
                    if (tt != null) 
                        tablemes[cntTable].odt.records[l].d = tt;
                        int a = tablemes[cntTable].odt.records[l].getPrice();
                        System.out.println(tablemes[cntTable].odt.records[l].orderNum + " " + tt.name + " " +a );
                        tablemes[cntTable].sum +=a;
                    
                    l++;
                
                //continue;
            

            else if (count == 5) //代点菜
                //String[] temp3 = st.split(" ");
                a1 = Integer.parseInt(temp[1]);
                a2 = Integer.parseInt(temp[3]);
                a3 = Integer.parseInt(temp[4]);
                tablemes[cntTable].odt.addARecord( a1, temp[2], a2, a3);
                tt = mu.searthDish(temp[2]);
                if (tt != null) 
                    tablemes[cntTable].odt.records[l].d.unit_price = tt.unit_price;
                    int b = tablemes[cntTable].odt.records[l].getPrice();
                    System.out.println(temp[1] + " table " + tablemes[cntTable].tableNum + " pay for table " + temp[0] + " " + b);
                    tablemes[cntTable].sum += b;
                
                l++;
            
            //st = sc.nextLine();

        
        for (int i = 1; i < cntTable + 1; i++) 
            tablemes[i].Gettottalprice();
        
    


 class Dish 
        String name;//菜品名称
        int unit_price;    //单价
        //int num;

        int getPrice(int portion) 
            int peic = 0;
            if (portion == 1) 
                peic = unit_price ;
             else if (portion == 2) 
                peic = Math.round((float) (unit_price * 1.5)) ;
             else if (portion == 3) 
                peic = (unit_price * 2) ;
            
            return peic;//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)
        

class Menu 

        Dish[] dishs = new Dish[10];//菜品数组,保存所有菜品信息
        int count = 0;
        Dish searthDish(String dishName)
            Dish temd = null;
            for(int i=count-1;i>=0;i--)
                if(dishName.equals(dishs[i].name))
                    temd = dishs[i];
                    break;
                
            
            if(temd==null)
                System.out.println(dishName+" does not exist");
            
            return temd;
        //根据菜名在菜谱中查找菜品信息,返回Dish对象。
        Dish addDish(String dishName,int unit_price)
            Dish dh = new Dish();
            dh.name = dishName;
            dh.unit_price = unit_price;
            count++;
            return dh;
        //添加一道菜品信息

 class Order 

    Record[] records = new Record[10];//保存订单上每一道的记录
    int count = 0;//订单数量
    void addARecord(int orderNum,String dishName,int portion,int num)
        records[count] = new Record();
        records[count].d.name = dishName;
        records[count].orderNum = orderNum;
        records[count].portion = portion;
        records[count].num = num;
        count++;
    //添加一条菜品信息到订单中。
    int delARecordByOrderNum(int orderNum)
        if(orderNum>count||orderNum<=0)
            System.out.println("delete error;");
            return 0;
        else 
            return records[orderNum - 1].getPrice();
        
    //根据序号删除一条记录

public class Record 
        int orderNum;//序号\\
        //int AntherOrderNum;
        Dish d = new Dish();//菜品\\
        int num = 0;
        int portion;//份额(1/2/3代表小/中/大份)\\
        //int exist = 1;
        int getPrice()
            return d.getPrice(portion)*num;
        //计价,计算本条记录的价格\\

public  class Table 
    int tableNum;
    String tableDtime;
    int year,month,day,week,hh,mm,ss;
    int sum = 0;//一桌价格 ;
    Order odt = new Order();
    double discnt = -1;
    void Gettottalprice()
        if(discnt>0)
            sum = (int) Math.round(sum*discnt);
            System.out.println("table " + tableNum + ": " + sum);
        else 
            System.out.println("table " + tableNum + " out of opening hours");
        
    
    void AheadProcess(String tableDtime)
        this.tableDtime = tableDtime;
        processTime();
        discount();
    


    void processTime()//处理时间
        String[] temp = tableDtime.split(" ");
        tableNum = Integer.parseInt(temp[1]);
        String[] temp1 = temp[2].split("/");
        String[] temp2 = temp[3].split("/");

        year = Integer.parseInt(temp1[0]);
        month = Integer.parseInt(temp1[1]);
        day = Integer.parseInt(temp1[2]);

        Calendar c = Calendar.getInstance();
        c.set(year, (month-1), day);
        week = c.get(Calendar.DAY_OF_WEEK);
        if(week==1)
            week = 7;
        else
            week--;
        hh = Integer.parseInt(temp2[0]);
        mm = Integer.parseInt(temp2[1]);
        ss = Integer.parseInt(temp2[2]);

    
    
    void discount()
        if(week>=1&&week<=5)
        
            if(hh>=17&&hh<20)
                discnt=0.8;
            else if(hh==20&&mm<30)
                discnt=0.8;
            else if(hh==20&&mm==30&&ss==0)
                discnt=0.8;
            else if(hh>=11&&hh<=13||hh==10&&mm>=30)
                discnt=0.6;
            else if(hh==14&&mm<30)
                discnt=0.6;
            else if(hh==14&&mm==30&&ss==0)
                discnt=0.6;
        
        else
        
            if(hh>=10&&hh<=20)
                discnt= 1.0;
            else if(hh==9&&mm>=30)
                discnt= 1.0;
            else if(hh==21&&mm<30||hh==21&&mm==30&&ss==0)
                discnt= 1.0;
        
    

  这段代码是我在题目集6中写出的代码,题目集4第一次菜单我没写,但在第二次菜单中我先写出正常情况下的点餐,未考虑一些异常情况。但是我写出来的代码发现连第一次的全部情况都没满足,只满足了一些情况。

如图

满足了一些情况,但是我没写出算总价的情况。

第二次题目集太难了,不像聚合一样,老师给了类图,我只需填空即可。这两到题没有一点提示,全靠自己的思路。我思路是先满足正常点餐,在考虑异常点餐。但我发现我花了4天写出的代码连正常点餐都做不到,我就直接放弃写第二次点餐程序了。但是我发现我写的代码满足第一次正常点餐程序的大部分情况,感觉还是有点成就的。

类图如下

 很可惜我这两道题没得一分。但我了解了一些道理,只要你写了,并且有了一定成果,那就不算白干,这2次程序,至少我满足了一些情况,放在第一次点餐题中,我的代码

题目集7-9的总结性Blog

(1)前言:

   这三次题目集主要考察多态,抽象类,接口,如何进行类与类之间的设计等知识点。运用到的算法比较基础,主要考察对面向对象思想的理解。题量适中,虽然题目数量减少但是每个题目集所涉及到的代码量有所增加。题目集难度稍有增加,但是还是在可以接受的范围内,类与类之间的关系更为复杂,但是认真理解题目要求还是会有思路。

(2)设计与分析:

题目7-1:

 (1) 这个题目集主要考察对多态以及抽象类的使用,两个题目是递进关系。首先先要解决多态的问题,创建一个抽象类Card然后通过这个类来实现多态。

 

 

通过阅读题目要求我们可以得出需要三个方法:1.计算面积 2.判断是否合法 3.显示信息 。所以我们要将这些实现相应功能的方法设置为抽象方法。

(2)接下来设计Circle,Rectangle,Trapeze,Triangle这几个类继承与Card类并重写其中的抽象方法,这样就实现了多态。在重写抽象方法时要注意各个类之间的重写内容是不同的要认真考虑每一个类的情况。

例如Circle类重写后是这样的

 

(3)有题目要求可以得出需要解决的相应算法:利用相关数据对每个对象进行排序

利用多态以及实现Comparable接口来实现这一算法是比较简单的

首先先让Card这个抽象类实现Comparable接口并且重写comparato方法(这样做可以简便的使用属性对每一个对象进行排序)

 

 涉及到求面积总和的问题时只需要设计一个方法来解决就可以

 

 (4)这样大体的类与相对应的算法就已经实现,接下来只需要简单的逻辑与循环语句就可以编写完成整个程序。

 

最后编写完成后所生成的类图如下

  从类图中也可以看出使用多态可以使代码整体可读性更高并且使代码思路更加清晰。

圈复杂度如下:

由圈复杂度可以看出使用多态降低了代码的复杂度逻辑思路清晰,这也体现了面向对象中使用多态的好处。

 题目7-2:

(1)这个题目是对7-1的进一步延伸,多了一个需求就是需要分组进行排序这是对算法难度的一个提升。

想要实现这个算法首先要创建多个对应的数组来记录和存储各个对象的信息,然后再进行整体的输出。

具体步骤如下图:

  这样是使用数组进行数据分类的做法,但是设置的类型却是具体的实物类型可以继续改进此代码。运用多态创建数组,这样依旧可以利用多态的优点增加代码的复用性,

所以在学习过程中要不断反思与改进自己所写的代码,这样才能使自己的代码越写越好。

  这个题目所生成的类图与7-1的类图相同,这里就不在给出。

圈复杂度如下:

 

   由此可以看出这个题目的圈复杂度比7-1要大一点,因为这个题目还进行了数组分类逻辑思维量也更大一些。

题目集8:

 

   本题主要目的是设计一个ATM系统,可以实现简单的存款与取款。首先需要设计类与类之间的关系(ATM,银行,账户,用户),然后添加有关的属性与方法。

Bank类:这个类用来管控ATM以及创建银行,总体来说较为简单,下面直接给出源码:

 

  涉及到的方法是要判断所使用的ATM是否属于本行,所使用到的思路也较为简单。

ATM:这个类主要是要实现对账户的操作,然后实现存款与取款。下面给出这个类的主要方法:

Account:这个类主要记录密码与账户号,设计理念比较简单这里就不在给出。

Consumer:这个类主要记录用户的基本信息,这里也不在给出。

下面介绍本题需要用到的算法:1.存款取款只需要使用加减法就可以 2.核对卡号,密码用户信息,存款取款是否合法等

第二个算法我使用法的是String类中的方法,截取卡号然后利用equals方法来进行校验,给出部分代码如下:

 

在储存用户信息时需要用到集合,利用集合去添加用户信息更加简便,并且在使用的时候也很方便。具体代码如下:

 

最后再根据题意利用String的一些方法增加一些逻辑关系的判断就可以完成整个程序:

 

这道题的代码对面向对象的使用并不是很多,所以代码的可读性与复用性比较差还需要继续进行改进。代码中大量的使用了if-else语句这也使代码的圈复杂度有所增加。

下面给出这道题的圈复杂度:

 

从圈复杂度可以看出本题代码编写时运用到的逻辑比较复杂,但这并不是最优的选择,在以后的编写时应该注意对面向对象思想的使用,先构思再写代码。

题目集9:

题目集9是对题目集8的进一步改进与优化,但是同时它也增加了许多新的功能(可透支,可跨行交易)同时这次是在老师所给的代码上进行修改,所以难度也会有所增加。

1.首先要明确思路,借记卡与贷记卡是针对于账户的,所以多态就要运用于此。创建一个借记账户,创建一个贷记账户让它们都继承于Account类,同时重写Account中的方法这样就实现了多态。

两个子类重写的方法如下:

 

 

2.通过总结老师所给的代码我得出了各个类之间的关系:银联---->银行------>账户------->卡号 用户------>账号

得出各个类之间的关系对后面方法的调用就有很大的帮助。

3.Withdraw类用于各项条件的判断,因为有两类账户所以对数据的判断要进行分类讨论

特别需要注意的是要添加跨行操作的逻辑判断:

 

4.最后完善所写代码,所生成的类图为:

 圈复杂度如下:

由上图可以看出即使题目集9比题目集8增加了6到7个类但是正确运用多态还是可以使圈复杂度比较稳定不至于提高太多。所以正确的类与类之间的关系设置和正确使用面向对象三大基础特性就显得尤为重要了。

(3)踩坑心得

  1.写代码时没有先进行构思就开始编写,这就使某些算法思路还停留在面向过程当中。

 

设置数组时并没用运用多态,这就增加了不必的重复性,代码复用性也变差了许多,这也是以后需要注意的地方。

  1.大量使用if-else语句,增加了代码的圈复杂度,这是一个很不好的习惯以后需要注意改正。

 

大量的if-else语句不仅逻辑复杂而且可读性差,可以用switch语句代替并且在以后写代码时也要避免不必要的逻辑判断。

3.增强对陌生代码的阅读能力,这次题目集9是在老师所给的代码的基础上进行改进的,所以要想完成题目就必须要读懂老师所写的代码。

首先明确类与类之间的关系,然后针对每一类中的方法进行研究搞懂每一个方法的作用,这样阅读陌生代码会更快的搞懂它的逻辑结构。

4.在使用多态时调用方法时出现了问题

 

在获取余额时没有运用正确的逻辑思路,首先要搞清楚余额是存储在账户里面的。所以调用余额时要getAccount()这样才能获取到正确的余额。

(4)改进建议

   自己写的代码还不够有面向对象的味道,所以之后还得多加练习,在写代码之前先进行构思这样会很有效率。

在卡片题目中虽然使用了多态但是没用将多态贯彻到底这就使代码还是出现了一些美中不足,在ATM机的题目中没有正确的运用多态,虽然想到使用多态但是却不能正确的运用。

这样就要加强对多态的练习,不仅要有使用多态的意识还要学会怎样正确使用多态。

(5)总结

  这几次题目集是对面向对象使用的进一步加强,可以说是如果不使用面向对象就不可能做出来相关的题目。在做题中也深刻体会到了面向对象带来的便利,尤其是使用多态时只需要重写方法就可以反复使用。

而且这几次的题目都偏向于生活中的实例这就让学生在做题时更加具有生活情境希望以后这样具有丰富生活情境的题目可以多出一点。本次题目集还有一个创新的地方就是在老师原有的代码上进行改动实现题目要求,

这也是一个值得保持的地方,因为看懂别人所写的代码也是一种能力,在看别人写的优秀的代码时也可以发现不同的思路同时对自己写代码也有很好的帮助。这几次题目集难度虽然有所提升在做题时也出现了许多问题,

在不断debug和改错的过程中也体会到了坚持的力量,在最后得出正确答案时感受到了成功的喜悦,这也是java课让我学到的东西,希望这样的感觉可以继续保持。反转课堂的效果也很好可以继续采取这样的教学方式。

  

 

以上是关于题目集4~6的总结性Blog的主要内容,如果未能解决你的问题,请参考以下文章

PTA题目集4~6的总结

OO题目集4-6总结

PTA题目集4~6总结

OOP 4-6次题目集总结

题目集4~6总结心得

题目集4-6次总结