NCHU-pta题目集4-6总结
前言:
题目集4中,第一题难度最大,第二题难度中等,第三题难度中等,
题目集5中,前三道题目难度较小,第四题难度中等,第五题稍难
题目集6中,前四道题目难度小,第四题,第五题难度稍大(唯一一次全部做出来了,哈哈哈哈哈哈)。
涉及到知识点有:正则表达式、Java中的字符串处理类、for语句等的使用,Java类的属性、定义,类的封装、继承,简单语句的使用,对象、继承,相关简单语句的使用。
设计与分析:
本次重点对题目集4的第二,三题讨论,题目集5的第四道,以及题目集6的五,六题。
先上题目
4-2:
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format - 当第一个数字为1且输入均有效,输出格式如下:
year-month-day - 当第一个数字为2且输入均有效,输出格式如下:
year-month-day - 当第一个数字为3且输入均有效,输出格式如下:
天数值
输入样例1:
在这里给出一组输入。例如:
3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:
2312
输入样例2:
在这里给出一组输入。例如:
2 1935 2 17 125340
输出样例2:
在这里给出相应的输出。例如:
1591-12-17
输入样例3:
在这里给出一组输入。例如:
1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:
2017-2-24
输入样例4:
在这里给出一组输入。例如:
0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:
Wrong Format
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
- 1 year month day n //测试输入日期的下n天
- 2 year month day n //测试输入日期的前n天
- 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
- 当输入有误时,输出格式如下:
Wrong Format - 当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2 - 当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2 - 当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:值
输入样例1:
在这里给出一组输入。例如:
3 2014 2 14 2020 6 14
输出样例1:
在这里给出相应的输出。例如:
The days between 2014-2-14 and 2020-6-14 are:2312
输入样例2:
在这里给出一组输入。例如:
2 1834 2 17 7821
输出样例2:
在这里给出相应的输出。例如:
1834-2-17 previous 7821 days is:1812-9-19
输入样例3:
在这里给出一组输入。例如:
1 1999 3 28 6543
输出样例3:
在这里给出相应的输出。例如:
1999-3-28 next 6543 days is:2017-2-24
输入样例4:
在这里给出一组输入。例如:
0 2000 5 12 30
输出样例4:
在这里给出相应的输出。例如:
Wrong Format
为方便起见,我将4-2称为前者,5-5称为后者
前者中,DateUtil中,并没有后者中的这三个方法
//getyear() (Year)
//getmonth() (Month)
//getday() (Day)
此三个方法,后者能够在Dateutil类中,更方便的调用从建盘输入的数据,减少了代码量,而且更方便阅读,而且,后者的Dateutil类将大部分的功能集中起来,方便后期对某个函数进行修改。
但前者代码结构更加清晰,类与类之间的联系没有过多繁杂之处。
第一个代码复杂度:

第二个代复杂度:

差别不大,但还是有些区别的。
通过代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int key=Integer.parseInt(input.next()); //int key=2; if(key==1){//求下N天 1 1999 3 28 6543 int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int year=Integer.parseInt(input.next()); //int year =1999; int month=Integer.parseInt(input.next()); //int month = 3; int day=Integer.parseInt(input.next()); //int day = 28; int N=Integer.parseInt(input.next()); //int N=6543; DateUtil A = new DateUtil(year,month,day); Year A1=new Year(); if((year>=1900&&year<=2050)&&(month>=1&&month<=12)&&(day>=1&&day<=a[month])){ DateUtil B=new DateUtil(year,month,day); B=A.xiaNtian(N); //System.out.println(N); System.out.println(B.getDay().getMonth().getYear().getValue()+"-"+B.getDay().getMonth().getValue()+"-"+B.getDay().getValue()); } else if((year<1900||year>2050)||(month<1||month>12)||(day<1||day>a[month])) System.out.println("Wrong Format"); //A.jiannian(); //System.out.println(A.getValue()); } else if(key==2){//求前N天 2 1935 2 17 125340 int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int year=Integer.parseInt(input.next()); //int year =1935; int month=Integer.parseInt(input.next()); //int month = 2; int day=Integer.parseInt(input.next()); //int day = 17; int N=Integer.parseInt(input.next()); //int N=125340; DateUtil A = new DateUtil(year,month,day); if((year>=1900&&year<=2050)&&(month>=1&&month<=12)&&(day>=1&&day<=a[month])){ DateUtil B=new DateUtil(year,month,day); B=A.qianNtian(N); //System.out.println(N); System.out.println(B.getDay().getMonth().getYear().getValue()+"-"+B.getDay().getMonth().getValue()+"-"+B.getDay().getValue()); } else if((year<1900||year>2050)||(month<1||month>12)||(day<1||day>a[month])) System.out.println("Wrong Format"); //A.jiannian(); //System.out.println(A.getValue()); } else if(key==3){//求相差天数 3 2014 2 14 2020 6 14 int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; Year b=new Year(); //if(b.isLeapYear(this.getDay().getMonth().getYear().getValue())){ //a[2]=29; //} int year=Integer.parseInt(input.next()); //int year =2014; int month=Integer.parseInt(input.next()); //int month = 2; int day=Integer.parseInt(input.next()); //int day = 14; int year1=Integer.parseInt(input.next()); //int year1 =2020; int month1=Integer.parseInt(input.next()); //int month1 = 6; int day1=Integer.parseInt(input.next()); //int day1 = 14; DateUtil A=new DateUtil(year,month,day); DateUtil B=new DateUtil(year1,month1,day1); if(b.isLeapYear(A.getDay().getMonth().getYear().getValue())){ a[2]=29; } //System.out.print(A.getDay().getMonth().getYear().getValue()+" ");//输出年份 //System.out.print(A.getDay().getMonth().getValue()+" ");//输出月份 //System.out.println(A.getDay().getValue());//输出日 //System.out.print(B.getDay().getMonth().getYear().getValue()+" ");//输出年份 //System.out.print(B.getDay().getMonth().getValue()+" ");//输出月份 //System.out.println(B.getDay().getValue());//输出日 if((year>=1900&&year<=2050)&&(month>=1&&month<=12)&&(day>=1&&day<=a[month])&&(year1>=1900&&year1<=2050)&&(month1>=1&&month1<=12)&&(day1>=1&&day1<=a[month1])){ //System.out.println("第一个等于第二个"); System.out.println(A.qts(B)); } //System.out.println("第一个不等于于第二个"); //System.out.println(A.qts(B)); else System.out.println("Wrong Format"); } else System.out.println("Wrong Format"); } } class Year { private int value; // 定义私有变量 Year() { // 定义无参的构造方法 value = 0; } Year(int value) { // 定义有参的构造方法 this.value = value; } public void setValue(int value) { this.value = value; } public int getValue() { return value; } public static boolean isLeapYear(int year) { if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) return true; else return false; } public boolean panduan(){//判断年份是否正确 getValue(); if(value>=1900&&value<=2050) return true; else return false; } public void jianian(){//年份加一 getValue(); value+=1; } public void jiannian(){//年份减一 getValue(); value-=1; } } class Month{ int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int value; Year year; Month() { // 定义无参的构造方法 value = 0; } Month(int yearValue,int monthValue ) { // 定义有参的构造方法 this.year=new Year(yearValue); this.value=monthValue; } public void setValue(int value) { this.value = value; } public int getValue() { return value; } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public boolean panduan(){//判断月份是否正确 getValue(); if(value>=1&&value<=12) return true; else return false; } public void hui1(){//月份回到一月 getValue(); value=1; } public void hui12(){//月份回到12月 getValue(); value=12; } public void jiamonth(int value){//月份加一 getValue(); value+=1; } public void jianmonth(int value){//月份减一 getValue(); value-=1; } } class Day { int value; Month month; Day() {// 定义无参的构造方法 value = 0; } Day(int yearvalu, int monthvalue, int dayvalue) {// 定义有参的构造方法 this.value = dayvalue; this.month = new Month(yearvalu, monthvalue); } int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void setMonth(Month month) { this.month = month; } public Month getMonth() { return month; } public void hui1() {//天数回到1 getValue(); value = 1; } public void huida() {//天数回到最大 getValue(); Month A = new Month(); value = a[A.getValue()]; } public boolean panduan() {//判断天数是否正确 getValue(); Month A = new Month(); month.getValue(); //System.out.println(value);//value为天数; //System.out.println(month.getValue());//month.getValue()为月份 if (value >= 1 && value <= a[month.getValue()]) { return true; } else return false; } } class DateUtil { Day day; public DateUtil(){ } public DateUtil(int y,int m,int d){ this.day=new Day(y,m,d); } public Day getDay() { return day; } public void setDay(Day day) { this.day = day; } public boolean panduan(DateUtil date) {//判断合法 if (this.getDay().getMonth().getYear().panduan()) { if (this.getDay().getMonth().panduan()) { if (this.getDay().panduan()) { if (date.getDay().getMonth().getYear().panduan()) { if (date.getDay().getMonth().panduan()) { if (date.getDay().panduan()) { return true; } else return false; } else return false; } else return false; } else return false; } else return false; } else return false; } public boolean panduan2() {//判断合法 if (this.getDay().getMonth().getYear().panduan()) return true; else return false; } public boolean bjdx(DateUtil date){//比较大小 if(this.getDay().getMonth().getYear().getValue() > date.getDay().getMonth().getYear().getValue()) return true; else if(this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&&this.getDay().getMonth().getValue() > date.getDay().getMonth().getValue()) return true; else if(this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&&this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue()&&this.getDay().getValue()>date.getDay().getValue()) return true; else return false; } public boolean pdxd(DateUtil date){//判断是否相等 if(this.getDay().getMonth().getYear().getValue() == date.getDay().getMonth().getYear().getValue()&&this.getDay().getMonth().getValue() == date.getDay().getMonth().getValue()&&this.getDay().getValue()==date.getDay().getValue()) return true; else return false; } public String showDate()//以“year-month-day”格式返回日期值 { return this.getDay().getMonth().getYear().getValue() + "-" + this.getDay().getMonth().getValue() + "-" + this.getDay().getValue(); } public DateUtil xiaNtian(int n)//取得year-month-day的下n天日期 { Year b=new Year(); int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(b.isLeapYear(this.getDay().getMonth().getYear().getValue())){ a[2]=29; } int day = this.getDay().getValue(); //System.out.println(this.getDay().getValue()); int month = this.getDay().getMonth().getValue(); int year=this.getDay().getMonth().getYear().getValue(); for (int i = 0; i < n; i++) { day++; if (day > a[month]) { day = 1; month++; if (month > 12) { month = 1; year++; if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) day--; //System.out.println(year); } } } //System.out.println(year); return new DateUtil(year, month, day); } public DateUtil qianNtian(int n)//取得year-month-day的前n天日期 { Year b=new Year(); int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(b.isLeapYear(this.getDay().getMonth().getYear().getValue())){ a[2]=29; } int day = this.getDay().getValue(); int month = this.getDay().getMonth().getValue(); //System.out.println(month); int year =this.getDay().getMonth().getYear().getValue(); for (int i = 0; i < n; i++) { day--; while (day < 1) { month--; if (month < 1) { month = 12; year--; //if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) //day--; } day += a[month]; } } return new DateUtil(year, month, day); } public int pdrn(int date){ if (this.getDay().getMonth().getYear().getValue() % 4 == 0 && this.getDay().getMonth().getYear().getValue() % 100 != 0 || this.getDay().getMonth().getYear().getValue() % 400 == 0) return 1; else return 0; } public int qts(DateUtil date){//求天数 Year b=new Year(); int[] a = new int[]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if(b.isLeapYear(this.getDay().getMonth().getYear().getValue())||b.isLeapYear(date.getDay().getMonth().getYear().getValue() )){ a[2]=29; } DateUtil dateUtil1 = this; DateUtil dateUtil2 = date; if (this.bjdx(date)) {//大的给小的// 小的给大的 dateUtil1 = date; dateUtil2 = this; } int[]a1=new int[]{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; int sum; int rnsm = 0; for (int i = dateUtil1.getDay().getMonth().getYear().getValue(); i < dateUtil2.getDay().getMonth().getYear().getValue(); i++) { if (b.isLeapYear(i)) { rnsm++; } } sum = 365 * (dateUtil2.getDay().getMonth().getYear().getValue() - dateUtil1.getDay().getMonth().getYear().getValue()) + rnsm; //System.out.println(a[dateUtil1.getDay().getMonth().getValue()]); int qian = a1[dateUtil1.getDay().getMonth().getValue()-1] + dateUtil1.getDay().getValue()+ (dateUtil1.getDay().getMonth().getValue() > 1 && b.isLeapYear(dateUtil1.getDay().getMonth(). getYear().getValue()) ? 1 : 0); int huo = a1[dateUtil2.getDay().getMonth().getValue()-1] + dateUtil2.getDay().getValue()+(dateUtil2.getDay().getMonth().getValue() > 1 && b.isLeapYear(dateUtil2.getDay().getMonth(). getYear().getValue()) ? 1 : 0); return sum - qian + huo; } }
编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法
public double getArea();//求图形面积 - 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
- 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
- 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法
public double getVolume();//求球体积 - 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法
public double getVolume();//求立方体体积 - 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:
Constructing 类名 - 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
- 输出的数值均保留两位小数
主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format
输入格式:
共四种合法输入
- 1 圆半径
- 2 矩形宽、长
- 3 球半径
- 4 立方体宽、长、高
输出格式:
按照以上需求提示依次输出
输入样例1:
在这里给出一组输入。例如:
1 1.0
输出样例1:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Circle
Circle's area:3.14
输入样例2:
在这里给出一组输入。例如:
4 3.6 2.1 0.01211
输出样例2:
在这里给出相应的输出。例如:
Constructing Shape
Constructing Rectangle
Constructing Box
Box's surface area:15.26
Box's volume:0.09
输入样例3:
在这里给出一组输入。例如:
2 -2.3 5.110
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
题目集4的第三题,采用顺序的结构,编写若干个函数功能,在主函数中,可以用if else语句来选择相对应的功能。并建立了sheap类,里面有获得图形面积这一方法,在后面具体的类中,重写了这个方法。
复杂度:
![]()
代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int Key=input.nextInt(); if(Key==1){ double R=input.nextDouble(); if(R>0) { Circle W = new Circle(); W.setR(R); System.out.printf("Circle's area:%.2f",W.getArea()); } else System.out.println("Wrong Format"); } else if(Key==2){ double chang=input.nextDouble(); double kuan=input.nextDoauble(); if(chang>0&&kuan>0) { Rectangle W = new Rectangle(); W.setChang(chang); W.setKuan(kuan); System.out.printf("Rectangle's area:%.2f",W.getArea()); } else System.out.println("Wrong Format"); } else if(Key==3){ double R=input.nextDouble(); if(R>0) { Ball W = new Ball(); W.setR(R); System.out.printf("Ball's surface area:%.2f",W.getArea()); System.out.println(); System.out.printf("Ball's volume:%.2f",W.getVolume()); } else System.out.println("Wrong Format"); } else if(Key==4){ double chang=input.nextDouble(); double kuan=input.nextDouble(); double gao=input.nextDouble(); if(chang>0&&kuan>0&&gao>0) { Box W = new Box(); W.setGao(gao); W.setChang(chang); W.setKuan(kuan); System.out.printf("Box's surface area:%.2f",W.getArea()); System.out.println(); System.out.printf("Box's volume:%.2f",W.getVolume()); } else System.out.println("Wrong Format"); } else { System.out.println("Wrong Format"); } } } class Shape { public double getArea() {//求图形面积 System.out.println("Constructing Shape"); return 0.0; } } class Circle extends Shape { double D = 3.14; private double R;//半径 public double getR(){ return R; } public void setR(double R){ this.R=R; } public double getArea() { System.out.println("Constructing Shape"); System.out.println("Constructing Circle"); //getR(); double area=Math.PI * R * R; return area; } } class Rectangle extends Shape { private double chang;//矩形的长 private double kuan;//矩形的宽 public double getchang() { return chang; } public void setChang(double chang) { this.chang = chang; } public double getKuan() { return kuan; } public void setKuan(double kuan) { this.kuan = kuan; } public double getArea() { System.out.println("Constructing Shape"); System.out.println("Constructing Rectangle"); getchang(); getKuan(); return chang * kuan; } } class Ball extends Circle { public double getArea() {//求球表面积 Circle A=new Circle(); double R1=getR(); System.out.println("Constructing Shape"); System.out.println("Constructing Circle"); System.out.println("Constructing Ball"); return 4.0 * Math.PI * R1 * R1; } public double getVolume() {//求球体积 Ball A=new Ball(); double R1=getR(); //System.out.println("Constructing Shape"); //System.out.println("Constructing Circle"); //System.out.println("Constructing Ball"); return Math.PI * Math.pow(R1,3) * 4.0 / 3.0; } } class Box extends Rectangle { private double gao;//矩形的高 public double getGao() { return gao; } public void setGao(double gao){ this.gao=gao; } public double getArea() {//求矩形表面积 Rectangle A = new Rectangle(); double gao1=getGao(); double chang1=getchang(); double kuan1=getKuan(); System.out.println("Constructing Shape"); System.out.println("Constructing Rectangle"); System.out.println("Constructing Box"); return (chang1 * kuan1 + chang1 * gao1 + kuan1 * gao1) * 2.0; } public double getVolume() {//求立方体体积 Box A = new Box(); double gao1=getGao(); double chang1=getchang(); double kuan1=getKuan(); //System.out.println("Constructing Shape"); //System.out.println("Constructing Rectangle"); //System.out.println("Constructing Box"); return chang1 * kuan1 * gao1; } }
(7—5):
掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
输入样例1:
在这里给出一组输入。例如:
1 1 1 2.3 3.2 3.2 6.5 3.2 4.2
输出样例1:
在这里给出相应的输出。例如:
Original area:
16.62 10.24 5.68
Sum of area:32.54
Sorted area:
5.68 10.24 16.62
Sum of area:32.54
输入样例2:
在这里给出一组输入。例如:
0 2 2 2.3 2.5 56.4 86.5 64.3 85.6 74.6544 3.2 6.1 4.5
输出样例2:
在这里给出相应的输出。例如:
Original area:
5.75 4878.60 2325.19 7.00
Sum of area:7216.54
Sorted area:
5.75 7.00 2325.19 4878.60
Sum of area:7216.54
输入样例3:
在这里给出一组输入。例如:
0 0 1 3 3 6
输出样例3:
在这里给出相应的输出。例如:
Wrong Format
复杂度如下:
![]()
而题目集(7-5)中则是直接输入三个数据,分别代表三种图形的面积。之后我们可以用三个特殊数组:
Circle[] A1 = new Circle[A ];//A为圆储存面积继承Circle Rectangle[] B1 = new Rectangle[B ];//B为圆储存面积继承Rectangle Triangle[] C1 = new Triangle[C ];//C为圆储存面积继承Triangle
用这三个数组来存储三个图形的数目,接下来用for循环来依次计算图形的面积,在存储在一个数组中。
编写抽象类:
abstract class Shape {//抽象类 public abstract double getArea(); public abstract boolean validate(); }
注意:在编写抽象类后,须在后面每一个继承自它的类中,实现这个Shape类中的两个方法,不然就会报错。
代码如下:
import javax.lang.model.type.NullType; import java.util.Scanner; import java.util.regex.*; import java.text.DecimalFormat; import java.util.Arrays; import static java.lang.System.exit; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int A=in.nextInt();//A表示为圆的个数 if(A<0){ System.out.println("Wrong Format"); exit(0); } int B = in.nextInt();//B表示为矩形个数 if(B<0){ System.out.println("Wrong Format"); exit(0); } int C = in.nextInt();//C表示为三角形个数 if(C<0){ System.out.println("Wrong Format"); exit(0); } Circle[] A1 = new Circle[A ];//A为圆储存面积继承来自Circle Rectangle[] B1 = new Rectangle[B ];//B为圆储存面积继承来自Rectangle Triangle[] C1 = new Triangle[C ];//C为圆储存面积继承来自Triangle int flag = 0;//标记圆与矩形到的位置 double sum = 0;//求面积和 double[] allarea = new double[A+B+C];//计算储存面积 if (A < 0 || B < 0 || C < 0) { } else { for (int i = 0; i < A; i++) { double R = in.nextDouble();//R为圆的半径 A1[i]=new Circle(R); if (A1[i].validate()) {//判断圆是否合法 A1[i].getArea();//应用圆的计算面积的函数 sum+=A1[i].getArea(); allarea[flag++]=A1[i].getArea();//面积全部存储到allarea中 } else { System.out.println("Wrong Format"); exit(0); } } for (int j = 0; j < B; j++) {//计算并存储矩形的面积 double chang = in.nextDouble();//长 double kuan = in.nextDouble();//宽 B1[j]=new Rectangle(kuan,chang); if (B1[j].validate()) {//判断矩形是否合法 B1[j].getArea();//计算矩形面积 sum+=B1[j].getArea(); allarea[flag++]=B1[j].getArea();//将计算出来的面积存储到allarea中 } else{ System.out.println("Wrong Format"); exit(0); } } for (int k = 0; k < C; k++) {//计算并存储三角形的面积 double a = in.nextDouble();//定义a,b,c代表三边 double b = in.nextDouble(); double c = in.nextDouble(); C1[k]=new Triangle(a,b,c); if (C1[k].validate()) {//判断三角是否合法 C1[k].getArea();//计算三角面积 sum+=C1[k].getArea(); allarea[flag++]=C1[k].getArea();//将计算出来的面积存储到allarea中 } else { System.out.println("Wrong Format"); exit(0); } } System.out.println("Original area:"); for (int i = 0; i < A+B+C ; i++) { System.out.printf("%.2f ", allarea[i]); } System.out.println(); System.out.printf("Sum of area:" + "%.2f", sum); System.out.println(); System.out.println("Sorted area:"); Arrays.sort(allarea); for (int i = 0; i < A+B+C ; i++) { System.out.printf("%.2f ",allarea[i]); } System.out.println(); System.out.printf("Sum of area:" + "%.2f", sum); } } } abstract class Shape { public abstract double getArea(); public abstract boolean validate(); } class Circle extends Shape{ double radius; public Circle(double radius) { super(); this.radius = radius; } public double getArea() { return Math.PI * radius * radius; } public boolean validate(){ boolean flag=false; if(radius>0){ flag=true; } return flag; } } class Rectangle extends Shape { double width; double length; public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } @Override public double getArea() { return width*length; } @Override public boolean validate() { boolean flag=false; if(width>0&&length>0){ flag=true; } return flag; } } class Triangle extends Shape{ double c = 0; double s = 0; double y = 0; public Triangle(double a, double b, double c) { this.c = a; this.s = b; this.y = c; } @Override public double getArea() { double w = (c + s + y) / 2; return Math.sqrt(w * (w - c) * (w-s) * (w - y)); } @Override public boolean validate() { if (c < 0 || s < 0 || y < 0) { return false; } else if(c+s<=y||c+y<=s||s+y<=c){ return false; } else return true; } }
(7-6):
编写程序,使用接口及类实现多态性,类图结构如下所示:

其中:
- GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
- Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
- 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
输入格式:
从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。
输出格式:
- 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出
Wrong Format - 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。
输入样例1:
在这里给出一组输入。例如:
2 3.6 2.45
输出样例1:
在这里给出相应的输出。例如:
12.57
8.82
输入样例2:
在这里给出一组输入。例如:
9 0.5 -7.03
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
本题相对于前面的两题简单,在创建一个接口后,在创建两个类,实现这个接口内的方法:
interface GetArea{ public double getArea(); }
在之后的两个类中,一定要实现接口中的方法,不然会报错。
复杂度:

代码:
import java.util.Scanner; import java.time.LocalDateTime; import java.util.regex.*; import java.text.DecimalFormat; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double R = input.nextDouble(); double kuan = input.nextDouble(); double chang = input.nextDouble(); Yuan Y = new Yuan(); Y.setR(R); Juxing J = new Juxing(); J.setKuan(kuan); J.setChang(chang); if (Y.isyuan()&&J.isjuxing()) { System.out.printf("%.2f\n", Y.getArea()); System.out.printf("%.2f\n", J.getArea()); } else { System.out.println("Wrong Format"); System.exit(0); } } } class Yuan implements GetArea { double R; public double getR() { return R; } public void setR(double r) { R = r; } public Yuan(){ } public Yuan(double R){ } public double getArea(){ double r=this.R; return Math.PI*r*r; } public boolean isyuan(){ boolean bj=false; if(R>0){ return true; } else return false; } } class Juxing implements GetArea{ double kuan; double chang; public double getChang() { return chang; } public void setChang(double chang) { this.chang = chang; } public double getKuan() { return kuan; } public void setKuan(double kuan) { this.kuan = kuan; } Juxing (){ } Juxing(double kuan,double chang){ } public double getArea(){ double k=this.kuan; double c=this.chang; return k*c; } public boolean isjuxing(){ boolean bj=false; if(kuan>0&&chang>0){ return true; } else return false; } } interface GetArea{ public double getArea(); }
好,接下来分析(7-4)
题目如下:
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
- 当未输入源码时,程序输出
Wrong Format - 当没有统计数据时,输出为空
- 当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为
数量\t关键字
输入样例:
在这里给出一组输入。例如:
//Test public method
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
exit
输出样例:
在这里给出相应的输出。例如:
1 float 3 if 2 int 2 new 2 public 3 this 2 throw
本题对于我来说可能是这三次作业相对比较难的。
首先说说集合与数组的区别
数组的长度是固定的,如果想增加长度,只能创建新的数组。
集合的长度是可变的,数据理论可以无限添加,自动扩容。
数组元素的类型必须是同一种类型,比如 String[] arr = ["aaa","bbb"];
集合元素可以是不同的类型 ArrayList<Object> arr = new ArrayList<Object>();
本题可以选择创建集合,用正则表达式将//后,或者/**/以及字符串中间的字符删除。然后根据
行来划分,行与行之间for循环查找关键词。
通过代码(别人的)
:
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { /* abstract、assert、boolean、break、byte、case、catch、 char、class、const、continue、default、do、double、else、 enum、extends、false、final、finally、float、 for、goto、if、implements、import、instanceof、 int、interface、long、native、new、null、package、 private、protected、public、return、short、static、 strictfp、super、switch、synchronized、this、throw、 throws、transient、true、try、void、volatile、while */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner input=new Scanner(System.in); String a; StringBuilder ss=new StringBuilder(); Map<String, Integer> map=new HashMap<String, Integer>(); String []key= { "abstract","assert","boolean","break","byte","case","catch", "char","class","const","continue","default","do","double","else", "enum","extends","false","final","finally","float", "for","goto","if","implements","import","instanceof", "int","interface","long","native","new","null","package", "private","protected","public","return","short","static", "strictfp","super","switch","synchronized","this","throw", "throws","transient","true","try","void","volatile","while" }; int j=0; for(int i=0;;i++) { a=input.nextLine(); if(a.equals("exit")) break; if(a.matches("(.*)//(.*)")) {String b[]=a.split("//"); ss.append(b[0]+" "); //ss.append('\n'); } else {ss.append(a+" "); //ss.append('\n'); } } int count=0; String s=ss.toString(); // System.out.println(s); Pattern p=Pattern.compile("\"(.*?)\""); Matcher m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); p=Pattern.compile("\"(.*?)\""); m=p.matcher(s); } p=Pattern.compile("/\\**(.*?)/"); m=p.matcher(s); while(m.find()){ s=s.replace(m.group()," "); // p=Pattern.compile("/\\*(.*?)\\*/"); m=p.matcher(s); } // System.out.println(s); if(s.isEmpty()) {System.out.println("Wrong Format"); System.exit(0); } s=s.replace("["," "); s=s.replace("]"," "); s=s.replace("-","a"); s=s.replace("*","a"); s=s.replace("/","a"); s=s.replace("+","a"); s=s.replace(">","a"); s=s.replace("=","a"); s=s.replace("!","a"); s=s.replace(":","a"); s=s.replace("\\","a"); s= s.replaceAll("[^a-zA-Z]", " "); String []s1=s.split("[ ' ']"); for(int i=0;i<s1.length;i++) {//System.out.println(s1[i]); for( j=0;j<key.length;j++) if(s1[i].equals(key[j])) { map.put(key[j], 0); } } for( int i = 0;i<s1.length;i++) { for( j=0;j<key.length;j++) if(s1[i].equals(key[j])) { count=map.get(key[j]); map.put(key[j], count+1); } } Set set=map.keySet(); Object[] arr=set.toArray(); Arrays.sort(arr); for(Object k:arr){ System.out.println(map.get(k)+"\t"+k); } } }
复杂度:

(3):
踩坑心得:从题目集5的7-4说起,7-4真的是太难了,我程序写了半天,发现根本不会

测试点也只是过了一个空的。发现老是正则出现问题,不知道如何消除字符串内的关键字。
对于题目集4的第二题,我一开始在判断上一天和前N天的函数方法中老是出问题,导致总是
比正确答案少了个四五天,后来发现,原来是因为,在这个函数中判断闰年的方法里少了一句
if(b.isLeapYear(this.getDay().getMonth().getYear().getValue())){ a[2]=29; }
else
a[2]=28;
就因为这么一个小问题,我硬是碰壁了一两天。
对于题目集4的第三题,我踩的坑主要是,一开始并不知道,Π不能用3.14来代替,导致我圆
的测试点过不去,只要把3.14改为Math.PI就能过圆的测试点。
至于题目集的第五题,我认为和前面的聚合一相差并不多,猜的坑也和它差不多
对于题目集6的第五第六道题,我们一定注意,在有抽象类的时候,继承于它的类是一定要实
现他里面的方法的。接口也类似。
改进:
我认为我在类与类之间的联系有点过于复杂,并没有做到清晰明白。
还有就是类里面的方法,没有一点头绪,一团乱,导致有时候需要这个方法的时候,总是找
不到。鉴于此,我认为,在代码简化方面,还有待于加强,要做到让代码,一看便知道是干
嘛的。还有就是注释方面,一定要多写注释,好的代码是注释比代码还多的。
总结:
这是我的第二次博客了,对于这第二次作业,我还是很清楚的认识到:
我在代码相关编程方面仍有很大的漏洞,经常不知道如何在个类中调用另一个类中的数据。
类的定义出现一点问题,类与类之间的联系不够明确,类图太过复杂。类中的方法杂乱无章
经常忘记getXXX,setXXX;要加强代码的编写,优化自己的代码风格。对于那些基础的知
识点,多去网上寻找相关的资料,大学一定要培养出自己的自学能力,网络发达,正是方便
我们去自己寻找相关资料。多多注意注释等基本素养,要让注释比代码更多。这次的题目,让
我清楚的认识到接口,抽象类的实用性,以及它的强大之处。
课程布置的作业,老师可以适当的给一些提示,方便我们能更好的查寻相关的资料,作业可以
适当的降低一些难题的难度,增加一些基础题,普通题的难度。这样既保证了题目质量,也不
会让我们对于难题束手无措,不知想如何下手。上课老师可以多讲一些例题,让我们能更好地
理解相关的知识。



浙公网安备 33010602011771号