JAVA大作业的第二次总结
写在最前:
题量、难度分析:
题目集四:考查了字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算,面向对象的类的封装性,以及简单的图形类的继承。第一题对个人来讲题目相对较难,并在最后查看全班答题得分的情况来讲,这道题属于比较难的,再加上自己本身并不能熟练地掌握情况运用正则表达式。
题目集五:考查了字符串的分割、替换,数组合并,插入排序、选择排序及冒泡排序三种算法,正则表达式,面向对象的类的封装性。第二题“统计Java程序中关键词的出现次数”难度在该题目集里难度最大。
题目集六:考查了字符串,正则表达式,面向对象的封装性、继承性及多态性。第一、二、三、四题均考查的是正则表达式,第五、六题便上升到了面向对象的继承问题,但是老师给予了类图,使我们是比较好处理的。
一、4-7-2、5-7-4两种日期类聚合设计的优劣比较
4-7-2
import java.util.*;
public class Main{
public static void main(String[] args) {
int i=0,year1=0,month1=0,day1=0,n1=0,year2=0,month2=0,day2=0,n2=0;//会不会输小数去测试
Scanner sc=new Scanner(System.in);
i=sc.nextInt();
PrinRule prin=new PrinRule();
CheckInputValidity check=new CheckInputValidity(year1,month1,day1);
switch (i)
{
case 1: year1=sc.nextInt();month1=sc.nextInt();day1=sc.nextInt();n1=sc.nextInt();
if(n1<0){
System.out.println("Wrong Format");
System.exit(0);
}
check.setInput(year1,month1,day1);
prin.isRight(check);
DateUtil x=new DateUtil(year1,month1,day1);
System.out.print((x.getNextDays(n1)).showDate());
break;
case 2:
year2=Integer.parseInt(sc.next());
month2=Integer.parseInt(sc.next());
day2 = Integer.parseInt(sc.next());
n2=sc.nextInt();
if(n2<0){
System.out.println("Wrong Format");
System.exit(0);
}
check.setInput(year2,month2,day2);
prin.isRight(check);
DateUtil y=new DateUtil(year2,month2,day2);
System.out.print((y.getPreviousNDays(n2)).showDate());
break;
case 3: year1=sc.nextInt();month1=sc.nextInt();day1=sc.nextInt();year2=sc.nextInt();month2=sc.nextInt();day2=sc.nextInt();
check.setInput(year1,month1,day1);
prin.isRight(check);
check.setInput(year2,month2,day2);
prin.isRight(check);
DateUtil a=new DateUtil(year1,month1,day1);
DateUtil b=new DateUtil(year2,month2,day2);
int k= a.getDaysOfDates(b);
System.out.print(k);break;
default:
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class PrinRule{
public void isRight(CheckInputValidity check)
{
if(!check.checkValidity())
{
System.out.println("Wrong Format");
System.exit(1);
}
}
}
class Day
{
private int value;
private Month month;
private int [] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
Day()
{}
Day(int yearValue,int monthValue,int dayValue)
{
value=dayValue;
month=new Month(yearValue,monthValue);
}
int getValue()
{
return value;
}
void setValue(int value)
{
this.value=value;
}
Month getMonth(){
return month;
}
void setMonth(Month value)
{
this.month=value;
}
void resetMin()
{
value=1;
}
void resetMax()
{
value=mon_maxnum[this.getMonth().getValue()-1];
if(this.getMonth().getValue() == 2 && this.getMonth().getYear().isLeapYear())
{
value++;
}
}
boolean validate()
{
if(value>=1||value<=31)
return true;
else
return false;
}
public void dayIncrement() {
value++;
if (value > 27) {
if (this.getMonth().getValue() == 2 && this.getMonth().getYear().isLeapYear()) {
if (value > mon_maxnum[this.getMonth().getValue() - 1] + 1) {
this.resetMin();
this.month.monthIncrement();
}
} else {
if (value > mon_maxnum[this.getMonth().getValue() - 1]) {
this.resetMin();
this.month.monthIncrement();
}
}
}
}
public void dayReduction() {
value--;
if (value <= 0) {
this.month.monthReduction();
if (this.month.getValue() <= 0) {
this.month.resetMax();
this.month.getYear().yearReduction();
}
this.resetMax();
}
}
}
class Month{
int value;
Year year;
Month ()
{}
Month (int yearValue,int monthValue )
{
value=monthValue;
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 true;
else
return false;
}
public void monthIncrement() {
value++;
if (value > 12) {
value = 1;
year.yearIncrement();
}
}
public void monthReduction() {
value--;
if (value <= 0) {
value = 12;
year.yearReduction();
}
}
}
class DateUtil{
private static int n=0,nday=0,nmonth=0,nyear=0;
private Day day;
DateUtil()
{
}
DateUtil(int y,int m,int d)
{
day=new Day(y,m,d);
}
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public boolean checkInputValidity()
{
CheckInputValidity input=new CheckInputValidity(day.getMonth().getYear().getValue(),day.getMonth().getValue(),day.getValue());
if(input.checkValidity())
return true;
else
return false;
}
public boolean comparaDates(DateUtil date)//com1 da yes
{
int day1=day.getValue(),day2=date.day.getValue();
int mon1=day.getMonth().getValue(),mon2=date.day.getMonth().getValue();
int year1=day.getMonth().getYear().getValue(),year2=date.day.getMonth().getYear().getValue();
int com1=day1+mon1*15+year1*35;
int com2=day2+mon2*15+year2*35;
if(com1>com2)
return true;
else
return false;
}
public boolean equalTwoDates(DateUtil date)
{
if(day.getValue()==date.day.getValue()&&day.getMonth().getValue()==date.day.getMonth().getValue()&&day.getMonth().getYear().getValue()==date.day.getMonth().getYear().getValue())
return true;
else
return false;
}
public String showDate()
{
return this.day.getMonth().getYear().getValue() + "-" + this.day.getMonth().getValue() + "-"
+ this.day.getValue();
}
public DateUtil getNextDays(int n)
{
for (int i = 0; i < n; i++) {
this.day.dayIncrement();
}
return this;
}
public DateUtil getPreviousNDays(int n)
{
for (int i = 0; i < n; i++) {
this.day.dayReduction();
}
return this;
}
public int getDaysOfDates(DateUtil date)
{
int days = 0;
if (this.comparaDates(date)) {
while (!equalTwoDates(date)) {
date = date.getNextDays(1);
days++;
}
} else {
while (!equalTwoDates(date)) {
date = date.getPreviousNDays(1);
days++;
}
}
return days;
}
public static int numOfDays(int year,int month ,int day)//求出year-month-day到0001-1-1的距离天数,返回整型数;
{
int sum=0;
int i=0;
int begin=1;
int end=year;
int []run=new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
int []nrun=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
int begin4=(begin-1)/4;
int begin100=(begin-1)/100;
int begin400=(begin-1)/400;
int left=begin4-begin100+begin400;
int end4=end/4;
int end100=end/100;
int end400=end/400;
int right=end4-end100+end400;
int result=right-left;
sum=(year-1)*365+result;
if((year%4==0&&year%100!=0)||year%400==0)
{
while (i<month-1)
{
sum += run[i++];
}
sum += day;
sum=sum-1;
}
else {
while (i<month-1)
{
sum += nrun[i++];
}
sum += day;
}
return sum;
}
}
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()//run yes
{
if((value%4==0&&value%100!=0)||value%400==0)
return true;
else
return false;
}
public boolean validate()
{
if(value>=1900&&value<=2050)
return true;
else
return false;
}
public void yearIncrement()
{
value++;
}
public void yearReduction()
{
value--;
}
}
class CheckInputValidity
{
int year;int month;int day;
CheckInputValidity(int year,int month,int day)
{
this.day=day;
this.month=month;
this.year=year;
}
public void setInput(int year,int month,int day)
{
this.year=year;
this.month=month;
this.day=day;
}
boolean checkValidity()
{
int [] big=new int[]{1, 3, 5, 7, 8, 10, 12};
int index=Arrays.binarySearch(big,month);
if(range(year,1900,2050)&&range(month,1,12)&&range(day,1,31)) {
if (!((year%4==0&&year%100!=0)||year%400==0))//run
{
if (month == 2) {
if (range(day, 1, 29))//right
{
return true;
} else
return false;
} else if (index<0 )
{
if (range(day, 1, 30))//right
{
return true;
} else
return false;
} else//big
{
if (range(day, 1, 31))//right
{
return true;
} else
return false;
}
} else//not run
{
if (month == 2) {
if (range(day, 1, 28))//right
{
return true;
} else
return false;
} else if (index <0)//"-1".equals(index)? 小月
{
if (range(day, 1, 30))//right
{
return true;
} else
return false;
} else//big
{
if (range(day, 1, 31))//right
{
return true;
} else
return false;
}
}
}
else
return false;
}
private static boolean range(int v, int min, int max) {
return Math.max(min, v) == Math.min(v, max);
}
}
- SourceMonitor生成报表
- 类图
5-7-5
import java.util.*;
public class Main{
public static void main(String[] args) {
int i=0,year1=0,month1=0,day1=0,n1=0,year2=0,month2=0,day2=0,n2=0;//会不会输小数去测试
Scanner sc=new Scanner(System.in);
i=sc.nextInt();
PrinRule prin=new PrinRule();
CheckInputValidity check=new CheckInputValidity(year1,month1,day1);
switch (i)
{
case 1: year1=sc.nextInt();month1=sc.nextInt();day1=sc.nextInt();n1=sc.nextInt();
if(n1<0){
System.out.println("Wrong Format");
System.exit(0);
}
check.setInput(year1,month1,day1);
prin.isRight(check);
DateUtil x=new DateUtil(year1,month1,day1);
System.out.print(year1+"-"+month1+"-"+day1+" next "+n1+" days is:"+(x.getNextDays(n1)).showDate());
break;
case 2:
year2=Integer.parseInt(sc.next());
month2=Integer.parseInt(sc.next());
day2 = Integer.parseInt(sc.next());
n2=sc.nextInt();
if(n2<0){
System.out.println("Wrong Format");
System.exit(0);
}
check.setInput(year2,month2,day2);
prin.isRight(check);
DateUtil y=new DateUtil(year2,month2,day2);
System.out.print(year2+"-"+month2+"-"+day2+" previous "+n2+" days is:"+(y.getPreviousNDays(n2)).showDate());
break;
case 3: year1=sc.nextInt();month1=sc.nextInt();day1=sc.nextInt();year2=sc.nextInt();month2=sc.nextInt();day2=sc.nextInt();
check.setInput(year1,month1,day1);
prin.isRight(check);
check.setInput(year2,month2,day2);
prin.isRight(check);
DateUtil a=new DateUtil(year1,month1,day1);
DateUtil b=new DateUtil(year2,month2,day2);
int k= a.getDaysOfDates(b);
System.out.print("The days between "+year1+"-"+month1+"-"+day1+" and "+year2+"-"+month2+"-"+day2+" are:"+k);break;
default:
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class PrinRule{
public void isRight(CheckInputValidity check)
{
if(!check.checkValidity())
{
System.out.println("Wrong Format");
System.exit(1);
}
}
}
class Day
{
private int value;
private Month month;
private int [] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
Day()
{}
Day(int yearValue,int monthValue,int dayValue)
{
value=dayValue;
month=new Month(yearValue,monthValue);
}
int getValue()
{
return value;
}
void setValue(int value)
{
this.value=value;
}
Month getMonth(){
return month;
}
void setMonth(Month value)
{
this.month=value;
}
void resetMin()
{
value=1;
}
void resetMax()
{
value=mon_maxnum[this.getMonth().getValue()-1];
if(this.getMonth().getValue() == 2 && this.getMonth().getYear().isLeapYear())
{
value++;
}
}
boolean validate()
{
if(value>=1||value<=31)
return true;
else
return false;
}
public void dayIncrement() {
value++;
if (value > 27) {
if (this.getMonth().getValue() == 2 && this.getMonth().getYear().isLeapYear()) {
if (value > mon_maxnum[this.getMonth().getValue() - 1] + 1) {
this.resetMin();
this.month.monthIncrement();
}
} else {
if (value > mon_maxnum[this.getMonth().getValue() - 1]) {
this.resetMin();
this.month.monthIncrement();
}
}
}
}
public void dayReduction() {
value--;
if (value <= 0) {
this.month.monthReduction();
if (this.month.getValue() <= 0) {
this.month.resetMax();
this.month.getYear().yearReduction();
}
this.resetMax();
}
}
}
class Month{
int value;
Year year;
Month ()
{}
Month (int yearValue,int monthValue )
{
value=monthValue;
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 true;
else
return false;
}
public void monthIncrement() {
value++;
if (value > 12) {
value = 1;
year.yearIncrement();
}
}
public void monthReduction() {
value--;
if (value <= 0) {
value = 12;
year.yearReduction();
}
}
}
class DateUtil{
private static int n=0,nday=0,nmonth=0,nyear=0;
private Day day;
DateUtil()
{
}
DateUtil(int y,int m,int d)
{
day=new Day(y,m,d);
}
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public boolean checkInputValidity()
{
CheckInputValidity input=new CheckInputValidity(day.getMonth().getYear().getValue(),day.getMonth().getValue(),day.getValue());
if(input.checkValidity())
return true;
else
return false;
}
public boolean comparaDates(DateUtil date)//com1 da yes
{
int day1=day.getValue(),day2=date.day.getValue();
int mon1=day.getMonth().getValue(),mon2=date.day.getMonth().getValue();
int year1=day.getMonth().getYear().getValue(),year2=date.day.getMonth().getYear().getValue();
int com1=day1+mon1*15+year1*35;
int com2=day2+mon2*15+year2*35;
if(com1>com2)
return true;
else
return false;
}
public boolean equalTwoDates(DateUtil date)
{
if(day.getValue()==date.day.getValue()&&day.getMonth().getValue()==date.day.getMonth().getValue()&&day.getMonth().getYear().getValue()==date.day.getMonth().getYear().getValue())
return true;
else
return false;
}
public String showDate()
{
return this.day.getMonth().getYear().getValue() + "-" + this.day.getMonth().getValue() + "-"
+ this.day.getValue();
}
public DateUtil getNextDays(int n)
{
for (int i = 0; i < n; i++) {
this.day.dayIncrement();
}
return this;
}
public DateUtil getPreviousNDays(int n)
{
for (int i = 0; i < n; i++) {
this.day.dayReduction();
}
return this;
}
public int getDaysOfDates(DateUtil date)
{
int days = 0;
if (this.comparaDates(date)) {
while (!equalTwoDates(date)) {
date = date.getNextDays(1);
days++;
}
} else {
while (!equalTwoDates(date)) {
date = date.getPreviousNDays(1);
days++;
}
}
return days;
}
public static int numOfDays(int year,int month ,int day)//求出year-month-day到0001-1-1的距离天数,返回整型数;
{
int sum=0;
int i=0;
int begin=1;
int end=year;
int []run=new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
int []nrun=new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
int begin4=(begin-1)/4;
int begin100=(begin-1)/100;
int begin400=(begin-1)/400;
int left=begin4-begin100+begin400;
int end4=end/4;
int end100=end/100;
int end400=end/400;
int right=end4-end100+end400;
int result=right-left;
sum=(year-1)*365+result;
if((year%4==0&&year%100!=0)||year%400==0)
{
while (i<month-1)
{
sum += run[i++];
}
sum += day;
sum=sum-1;
}
else {
while (i<month-1)
{
sum += nrun[i++];
}
sum += day;
}
return sum;
}
}
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()//run yes
{
if((value%4==0&&value%100!=0)||value%400==0)
return true;
else
return false;
}
public boolean validate()
{
if(value>=1820&&value<=2020)
return true;
else
return false;
}
public void yearIncrement()
{
value++;
}
public void yearReduction()
{
value--;
}
}
class CheckInputValidity
{
int year;int month;int day;
CheckInputValidity(int year,int month,int day)
{
this.day=day;
this.month=month;
this.year=year;
}
public void setInput(int year,int month,int day)
{
this.year=year;
this.month=month;
this.day=day;
}
boolean checkValidity()
{
int [] big=new int[]{1, 3, 5, 7, 8, 10, 12};
int index=Arrays.binarySearch(big,month);
if(range(year,1820,2020)&&range(month,1,12)&&range(day,1,31)) {
if (!((year%4==0&&year%100!=0)||year%400==0))//run
{
if (month == 2) {
if (range(day, 1, 29))//right
{
return true;
} else
return false;
} else if (index<0 )
{
if (range(day, 1, 30))//right
{
return true;
} else
return false;
} else//big
{
if (range(day, 1, 31))//right
{
return true;
} else
return false;
}
} else//not run
{
if (month == 2) {
if (range(day, 1, 28))//right
{
return true;
} else
return false;
} else if (index <0)//"-1".equals(index)? 小月
{
if (range(day, 1, 30))//right
{
return true;
} else
return false;
} else//big
{
if (range(day, 1, 31))//right
{
return true;
} else
return false;
}
}
}
else
return false;
}
private static boolean range(int v, int min, int max) {
return Math.max(min, v) == Math.min(v, max);
}
}
- SourceMonitor生成报表
2.类图
两次日期类的比较
1.通过类图可以看到,这种日期类的设计主要是层层递进的关系。DateUtil为总的日期类,其中包含了Day类(存储天数相关信息及方法),而Day类中又包含了Month类(存储月份相关信息及方法),Month类中则包含了Year类(存储年份相关信息及方法)。这种层层包含的设计显而易见有个不合理之处,Day、Month、Year三个类之间的关系不应该是这种一个包含一个的关系,这三个类应该是平等的。因此,在调用相关方法的时候,总是会很麻烦。例如我要调用Year类中的方法,就还要通过Month类进行调用,增加了很多不必要的麻烦。而第二种设计让Day、Month、Year三类全部包含于DateUtil类,在需要调用相关类的方法时,只要通过DateUtil这个类进行调用,方便了不少。
2.通过两者的报表可以看出,两次的Max Comlexity太长,同时我比较了两次的运行时间:
4-7-2
5-7-5
可以看出聚合一花费时间长于聚合二。
二、4-7-3、6-7-5、6-7-6三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)
4-7-3
- SourceMonitor生成报表
- 2.类图
- 从类图中可以看到父类为Shape类,其中只有构造方法和一个求图形面积的方法。其有两个子类Circle类和Rectangle类并在这两个类中根据对应类的实际情况重写了求面积方法。再由这两个子类去拓展子类Box,Ball。
6-7-5
import java.util.*;
public class Main{
public static void main(String[] args) {//会不会少输数据
Scanner sc = new Scanner(System.in);
int a=0,b=0,c=0,i=0;
double input1=0,input2=0,input3=0,input4=0;
Circle circle=new Circle();
Rectangle rectangle=new Rectangle();
Triangle triangle=new Triangle();
a=sc.nextInt();
b=sc.nextInt();
c=sc.nextInt();
if(a<0||b<0||c<0)
{
System.out.print("Wrong Format");
System.exit(0);
}
double []area=new double[a+b+c];
for(i=0;i<a+b+c;i++)
area[i]=0;
for(i=0;i<a;i++)
{
input1=sc.nextDouble();
circle.setRadius(input1);
if(!circle.vaildate())
{
System.out.print("Wrong Format");
System.exit(0);
}
area[i]=circle.getArea();
}
for (i=0;i<b;i++)
{
input1=sc.nextDouble();
input2=sc.nextDouble();
rectangle.setLength(input1);
rectangle.setWidth(input2);
if(!rectangle.vaildate())
{
System.out.print("Wrong Format");
System.exit(0);
}
area[i+a]= rectangle.getArea();
}
for(i=0;i<c;i++)
{
input1=sc.nextDouble();
input2=sc.nextDouble();
input3=sc.nextDouble();
triangle.setSide1(input1);
triangle.setSide2(input2);
triangle.setSide3(input3);
if(!triangle.vaildate())
{
System.out.print("Wrong Format");
System.exit(0);
}
area[i+a+b]=triangle.getArea();
}
Out out=new Out();
out.out(area);
}
}
abstract class Shape{//图形
Shape() {
}
public abstract double getArea();
public abstract boolean vaildate();
public String toString ()
{
return toString();
}
}
class Circle extends Shape{//圆
private double radius=1;
Circle()
{
}
Circle(double radius) {
this.radius=radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return radius*radius*Math.PI;
}
@Override
public boolean vaildate() {
if(radius<=0)
return false;
else
return true;
}
}
class Rectangle extends Shape{//矩形
private double width=0,length=0;
Rectangle()
{
}
public double getLength() {
return length;
}
Rectangle(double width,double length)
{
this.length=length;
this.width=width;
}
public void setLength(double length) {
this.length = length;
}//矩形
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double getArea() {
return width*length;
}
@Override
public boolean vaildate() {
if(length<0||width<0)
return false;
else
return true;
}
}
class Triangle extends Shape{//三角
private double side1=0,side2=0,side3=0;
Triangle()
{
}
Triangle(double side1,double side2,double side3)
{
this.side1=side1;
this.side2=side2;
this.side3=side3;
}
public double getSide1() {
return side1;
}
public void setSide1(double side1) {
this.side1 = side1;
}
public double getSide2() {
return side2;
}
public void setSide2(double side2) {
this.side2 = side2;
}
public double getSide3() {
return side3;
}
public void setSide3(double side3) {
this.side3 = side3;
}
@Override
public double getArea() {
double s=(side1+side2+side3)/2;
double area=Math.sqrt(s*(s-side1)*(s-side2)*(s-side3));
return area;
}
@Override
public boolean vaildate() {
double[] arr= {side1,side2,side3};
Arrays.sort(arr);
if(arr[0]+arr[1]>arr[2]&&arr[1]-arr[0]<arr[2]) {
return true;
}else {
return false;
}
}
}
class Out{
public void out(double [] area)
{
int i=0;
double all=0;
System.out.println("Original area:");
for(i=0;i<area.length;i++)//总和是约前约后
{
System.out.printf("%.2f ",area[i]);
all=all+area[i];
}
System.out.print("\n");
System.out.print("Sum of area:");
System.out.printf("%.2f\n",all);
System.out.println("Sorted area:");
Arrays.sort(area);
for (i=0;i<area.length;i++)
{
System.out.printf("%.2f ",area[i]);
}
System.out.print("\n");
System.out.print("Sum of area:");
System.out.printf("%.2f",all);
}
}
class PrinRule{
int i;
}
- SourceMonitor生成报表
2.类图
从类图中可以看出,此次将Shape修改为抽象类,使设计更加合理。通过重写父类的方法,可以增加多态性,并且增加了可扩充性及灵活性等。也让我实际看到了多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
6-7-6
import java.util.Scanner;
public class Main {
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
double radius,width,length;
radius=sc.nextDouble();
width=sc.nextDouble();
length=sc.nextDouble();
if(radius<=0||width<=0||length<=0)
{
System.out.print("Wrong Format");
System.exit(1);
}
Circle circle=new Circle(radius);
System.out.printf("%.2f\n",circle.getArea());
Rectangle rectangle=new Rectangle(width,length);
System.out.printf("%.2f",rectangle.getArea());
}
}
class Circle implements GetArea{
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
Circle(double radius) {
this.radius=radius;
}
Circle()
{
}
@Override
public double getArea() {
return radius*radius*Math.PI;
}
/*public double getArea() {
return radius*radius*Math.PI;
}*/
}
class Rectangle implements GetArea{
private double width,length;
public double getLength() {
return length;
}
Rectangle(double width,double length)
{
this.length=length;
this.width=width;
}
Rectangle()
{
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double getArea() {
return width*length;
}
/* public double getArea() {
return width*length;
}*/
}
interface GetArea{
public double getArea();
}
- SourceMonitor生成报表
2.类图
从类图中可以看出,此次新增了接口的要求,而不再创建父类。从中也可以看出接口与抽象类既有相同之处,也有不同之处。
一个接口可以和类一样有多个方法,但接口没有构造方法,也不能实例化对象,而且接口中的方法必须都是抽象的方法,方法必须继承接口的所有方法,同时接口支持多继承。这样是我们的程序可以更加灵活,简单。
下面我将继续从封装,继承,多态,接口来阐述这三个题目:
封装:三个题目都对程序进行了功能的单一化;
继承多态:第一个题目都是用实体类继承,第二个是用抽象类进行继承,这样更有利于运用多态解决问题,第三题是用接口继承,这可以实现代码的多继承。
三、正则表达式技术的分析总结
这三次作业中都有与正则表达式相关的题目要求。正则表达式常常用来匹配一些文本字符,可以说是极其重要的。在学习正则表达式的过程中也遇到了许多的问题,例如起初 '' 字符总是和平常一样,只打一个代表转义,但后来查阅了相关资料才知道两个 \ 代表其他其他语言中的一个 \ ,而表示一个普通的反斜杠字符则是 \\ 。正则表达式我主要用Pattern,Matcher两个类匹配。
具体操作方法:
1、获取Pattern:设计好需要匹配字符的正则表达式,用Pattern p=Pattern.compile("正则表达式")获取Pattern对象,这一是为了创建之后的Matcher,二是你的正则表达式需要一个东西包裹才能使用;
2、获取Matcher:通过Matcher m=p.matcher(要匹配的字符串),你可以获取你的匹配器,之后就可以匹配了。
3.匹配:我们可以通过调用Matcher的方法来匹配,比如,用m.find 判断是否有符合要求的字符串,有则返回true,无返回false。用Matcher.group 获取当前匹配值,同时,下一次匹配它将自动从刚刚结束的位置查找。
附上我的小栗子:
点击查看小栗子
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
String input=sc.nextLine();
if(input.length()!=8)
{
System.out.print("错误");
System.exit(1);
}
Pattern p=Pattern.compile("^^2020[1-8]{1}[1-7]{1}[01-40]{1}{1}$$");
Matcher m=p.matcher(input);
if(m.find())
{
System.out.print("正确");
}
else
{
System.out.print("错误");
}
}
}
此外:Matcher还提供如下方法:
https://www.runoob.com/java/java-regular-expressions.html
四、题目 5-7-4 中Java集合框架应用的分析总结
5-7-4
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Input input=new Input();
String str=input.input();
StrDeal strDeal=new StrDeal();
Map<String,Integer> map = new HashMap<String,Integer>();
map=strDeal.deal(str);
Prin prin=new Prin();
prin.prin(map);
}
}
class StrDeal{
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"};
Map deal(String str)
{
int num=0,i=0,j=0;
String regex;
Map<String,Integer> map = new HashMap<String,Integer>();
for( i=0;i<53;i++)
{
map.put(key[i], 0);
Pattern p=Pattern.compile("\\b"+key[i]+"\\b");
Matcher m=p.matcher(str);
while (m.find())
{
num++;
map.replace(key[i],num);
}
num=0;
}
return map;
}
}
class Input{
Scanner sc=new Scanner(System.in);
String input()
{
StringBuilder stringBuilder = new StringBuilder();
String get_in = new String();
String res1 = "//.*$";//整行注释
String res2 = "\"(.*)\"";//字符串
String res3 = "/\\**(.*)\\*/";//{/* */}型注释
String res4 = "\\s+";//多空格
int i;
for(i=0;true;i++) {
get_in=sc.nextLine();
if(i==0&&get_in.equals("exit"))
{
System.out.println("Wrong Format");
System.exit(0);
}
if(get_in.equals("exit"))
break;
get_in=get_in.replaceAll(res1, " ");
get_in=get_in.replaceAll(res2, " ");
get_in=get_in.replaceAll(res3, " ");
stringBuilder.append(get_in+' ');
}
String input = stringBuilder.toString();
return input;
}
}
class Prin{
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"};
void prin(Map map)
{
int num=0,k=0,j=0;
String []n=new String[53];
for (int i=0;i<53;i++)
{ num=(int)map.get(key[i]);
if(num!=0)
{
//n[k]=key[i];
//k++;
System.out.println(num+" "+key[i]);
}
}
/*for (int i=0;i<k-1;i++)
{
System.out.println((int)map.get(n[i])+" "+n[i]);
}
System.out.print((int)map.get(n[k-1])+" "+n[k-1]);*/
}
}
1. SourceMonitor生成报表
框架应用的分析总结:
这个题就是统计Java程序中关键词的出现次数,关键词一共有53个,需要自己到网上查阅,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"};就是要把程序通过键盘输入进去,输入exit是停止。
首先,需要初始化一个Map用于存储输出信息。此题用input类控制输入,同时,input还负责将注释、输出字符串剔除。为了避免多行输入造成的麻烦,我使用了stringBuilder将接收的字符串加工成一整个字符串,之后送入StrDeal进行匹配处理,匹配处理是用for循环一个一个与关键字匹配,最后送入Prin类进行输出。
五、采坑心得
1.在判断三角形三边是否合法时一定要将三边从小到大排列,再用a+b<=c两边之和大于第三边来判断,如果不进行排列判断就会有误;
2.抽象类可以有构造方法,接口中不能有构造方法。抽象类中可以有普通成员变量,接口中没有普通成员变量。抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法;
3.正则表达式在JAVA中还要加一个/;
4.圈复杂度降低的方法有很多,在DateUtil,这个类的设计时里面的方法,求下n天,求前n天,求两个日期的天数差,在这里就体现出了,圈复杂度的方法,第一次设计的时候圈复杂度较大,第二次我将if-else 改换掉成switch,使得代码的圈复杂度降了许多,所以还是有方法来降低圈复杂的。
六、改进建议
1.如果说要改进的话应该是需要改进,题目集4、题目集6直接运用多态和接口处理可以省去很多的代码量;
2.在运算前n后n天时,可以判断n的大小,从年,月,日三个层面进行自加或自减,比日期自加或自减n次并判断要大大节约计算资源,提升效率;
3.在设计类的时候,圈复杂度还是较大,怎样减少圈复杂度也是我今后要学习的一个地方;
4.类与类之关系,以及怎样更好的减少类与类之间的关系,在设计代码时,我设计的两个类总是有很多的关联,子类继承父类的功能,这些关系我在解题时依然不清楚;
5.老师有的题目会提供类图,我也得提高自己设计代码,设计类图的能力。
七、作业总结
本次题目集让我加深了对正则表达式的理解,有些程序在自己的努力下自己写出来是一件很值得骄傲的事情,前提是这个题目不是难到没有思路,就是有难度,但是通过自己努力分析和查阅资料,能顺利地解决这个问题,在这个过程中提高了就自己地思维能力,也锻炼了自己地编程能力,我希望能另外开一个永久的题目集,让我们在截止提交后还能写这道题,这之后写的不算入平时分,就只是单纯地让我们琢磨,思考完善还没过的测试点。
此外,这次的作业主要集中锻炼了继承与多态和正则表达式的运用。继承与多态都是提高代码质量,提高代码复用的手段,也同为面向对象语言的支柱。而正则表达式则是为字符串的识别处理提供了更丰富的手段。
Java是一种面向对象的语言,相比于编程来说,在编写代码前的思考更为重要,考虑如何将代码完善,将Java学习的思维方式更好地运用,才能越走越远。