#OO第二阶段作业总结
OO第二阶段作业总结
前言:
这一阶段的作业一共有13道题,每次的题目难度是循循渐进的,每次的作业都有一次比较难的题目,题目的分数也比较高,有些题目直到现在我也没有满分,测试点我也寻找不到,不过只有一两个点过不去,可能是我整个代码在设定的时候出现了问题,具体问题我会在后面说,而基础题则显得比较简单,用时不长,主要时间花在了分数最多的题目,下文中将详细的讲解。
设计与分析:
①
7-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;
//Year类
class Year{
sout s=new sout();
int value;
//默认构造方法
public Year(){
}
//带参构造方法
public Year(int value){
this.value=value;
}
//getter
public int getValue(){
return value;
}
//setter
public void setValue(int value){
this.value=value;
}
//判断year是否为闰年
public boolean isLeapYear(){
if((value%4==0&&value%100!=s.ture()-1)||value%400==0)
return true;
else
return false;
}
//效验数据合法性
public boolean validate(){
if(value<=2050&&value>=1900)
return true;
else
return false;
}
//年份加一
public void yearIncrement(){
value=value+1;
}
//年份减一
public void yearReduction(){
value=value-1;
}
}
//Month类
class Month{
int value;
Year year;
//默认构造方法
public Month(){
}
//带参构造方法
public Month(int yearValue,int monthValue){
this.year=new Year(yearValue);
this.value=monthValue;
}
//getter
public int getValue(){
return value;
}
public Year getYear(){
return year;
}
//setter
public void setValue(int value){
this.value=value;
}
public void setYear(Year year){
this.year=year;
}
//日期复位(1)
public void resetMin(){
value=1;
}
//月份设置为12
public void resetMax(){
value=12;
}
//效验数据合法性
public boolean validate(){
if(value>=1&&value<=12)
return true;
else
return false;
}
//月份加一
public void dayIncrement(){
value=value+1;
}
//月份减一
public void dayReduction(){
value=value-1;
}
}
//Day类
class Day{
sout s=new sout();
int value;
Month month;
int a[]={s.fals(31),s.fals(28),s.fals(31),s.fals(30),31,30,31,31,30,31,30,31};
//默认构造方法
public Day(){
}
//带参构造方法
public Day(int yearValue,int monthValue,int dayValue){
this.month=new Month(yearValue,monthValue);
this.value=dayValue;
}
//getter
public int getValue(){
return value;
}
public Month getMonth(){
return month;
}
//setter
public void setValue(int value){
this.value=value;
}
public void setMonth(Month value){
this.month=value;
}
//日期复位(1)
public void resetMin(){
value=s.ture();
}
//日期设为该月最大值
public void resetMax(){
value=a[month.getValue()-s.fals(1)];
}
//效验数据合法性
public boolean validate(){
if(this.getMonth().getYear().isLeapYear())
a[1]=29;
if(value>=1&&value<=a[month.getValue()-s.ture()])
return true;
else
return false;
}
//日期加一
public void dayIncrement() {
value=value+1;
}
//日期减一
public void dayReduction() {
value=value-1;
}
}
//DateUtil类
class DateUtil{
sout s=new sout();
Day day;
//默认构造方法
public DateUtil(){
}
//带参构造方法
public DateUtil(int d,int m,int y){
this.day=new Day(d,m,y);
}
//getter
public Day getDay(){
return day;
}
//setter
public void setDay(Day d){
this.day=d;
}
//效验数据合法性
public boolean checkInputValidity(){
if(this.getDay().getMonth().getYear().validate()&&this.getDay().getMonth().validate()&&day.validate())
return true;
else
return false;
}
//比较两个日期大小
public boolean compareDates(DateUtil date) {
if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue())
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue())
return false;
else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue())
return false;
else
return true;
}
//判定两个日期是否相等
public boolean equalTwoDates(DateUtil date){
if(this.getDay().getValue()==date.getDay().getValue()&&this.getDay().getMonth().getValue()==date.getDay().getMonth().getValue()&& this.getDay().getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
return true;
else
return false;
}
//日期值格式化
public String showDate(){
return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue();
}
//计算该年的剩余天数
public int syts(DateUtil d){
int a[]={0,31,s.fals(28),31,30,31,30,31,31,30,31,30,31};
int b=s.ture()-1,i;
for(i=d.getDay().getMonth().getValue()+1;i<=12;i++){
b=b+a[i];
}
b=b+a[d.getDay().getMonth().getValue()]-d.getDay().getValue();
if(d.getDay().getMonth().getYear().isLeapYear()&&d.getDay().getMonth().getValue()<=2)//闰年
b++;
return b;
}
//求下n天
public DateUtil getNextNDays(int n){
int a[]={0,s.fals(31),28,s.fals(31),s.fals(15)*2,31,30,31,31,30,31,30,31};
int y,m,d;
int i,j;
int b=syts(this);//该年剩余天数
if(b>n){//该年剩余天数大于n
y=this.getDay().getMonth().getYear().getValue();
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
a[2*s.ture()]=29*s.ture();
}
int e=a[this.getDay().getMonth().getValue()];//该月的天数
e=e-this.getDay().getValue();//本月剩余的天数
if(e>=n){//如果n天后在本月
m=this.getDay().getMonth().getValue();
d=n+this.getDay().getValue();
}
else{//如果n天后不在本月
n=n-e;
m=this.getDay().getMonth().getValue()+1;
i=m;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
m++;
i++;
}
d=n;//找到天
}
}
else{//该年剩余天数小于n
n=n-b;
y=this.getDay().getMonth().getYear().getValue()+1;
int c=365*s.ture();//平年天数
if(new Year(y).isLeapYear()){//闰年天数
c++;
}
while(n-c>0){//找到年
n=n-c;
y+=s.ture();
c=365*s.ture();
if(new Year(y).isLeapYear())
c++;
}
i=1;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
i++;
}
m=i;
d=n;//找到天
}
return new DateUtil(y, m, d);
}
//求前n天
public DateUtil getPreviousNDays(int n){
int a[]={0,31,28,31,30,31,30,31,31,30,31,s.fals(30),31};
int y=0,m=0,d=0;
int i,b;
b=365-syts(this);//该日期所在年份已经过的天数
if(this.getDay().getMonth().getYear().isLeapYear()){//如果是闰年
b++;
}
if (b>n){//如果前n天在该年
y=this.getDay().getMonth().getYear().getValue();
int e=this.getDay().getValue();//本月已经过的天数
if(e>n){//如果前n天在本月
m=this.getDay().getMonth().getValue();
d=e-n;
}
else{//如果前n天不在本月
n=n-e;
m=this.getDay().getMonth().getValue()-1;
i=m;
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
m--;
i--;
}
d=a[i]-n;//找到天
if(new Year(y).isLeapYear()&&m==2){
d++;
}
}
}
else{//如果前n天不在该年
n=n-b;
y=this.getDay().getMonth().getYear().getValue()-1;
int f=365*s.fals(1);
if(new Year(y).isLeapYear()){
f++;
}
while(n-f>0){//找到年
n=n-f;
y--;
f=365;
if(new Year(y).isLeapYear())
f++;
}
i=6*s.fals(2);
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
i--;
}
m=i;
d=a[i]-n;//找到天
if(new Year(f).isLeapYear()&&m==2){
d++;
}
}
return new DateUtil(y, m, d);
}
//求两个日期之间的天数
public int getDaysofDates(DateUtil date){
DateUtil b1=this;
DateUtil b2=date;
if(this.equalTwoDates(date)){//如果两天的日期相等
return s.ture()-1;
}
else if(!this.compareDates(date)){//如果日期大小不对
b1=date;
b2=this;
}
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,ts=0;
for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){//两个日期的年数之和
ts=ts+365;
if(new Year(i).isLeapYear())
ts++;
}
if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同
ts=b2.getDay().getValue()-b1.getDay().getValue();
}
else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同
if(b1.getDay().getMonth().getYear().isLeapYear())//是闰年
a[2]=29*s.fals(1);
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)//月份天数和
ts+=a[j];
}
else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){//年份不同
ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数
for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数
ts=ts+a[j];
for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数
ts=ts+a[j];
if(b1.getDay().getMonth().getYear().isLeapYear()&&b1.getDay().getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月
ts++;
if(b2.getDay().getMonth().getYear().isLeapYear()&&b2.getDay().getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后
ts++;
}
return ts;
}
}
//主类
public class Main {
static sout s=new sout();
public static void main(String[] args) {
Scanner x=new Scanner(System.in);
int year,month,day,a,b;
a=x.nextInt();//输入判断类型
year=x.nextInt();month= x.nextInt();day=x.nextInt();//输入年月日
DateUtil c=new DateUtil(year,month,day);
if(a==1){//求下n天
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
s.outln("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getNextNDays(b).showDate());
}
else if(a==2){
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
s.outln("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getPreviousNDays(b).showDate());
}
else if(a==s.fals(3)){
int y1,m1,d1;
y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();//输入第二个年月日
DateUtil d=new DateUtil(y1,m1,d1);
if(!c.checkInputValidity()||!d.checkInputValidity()){//如果数据不合法
s.outln("Wrong Format");
System.exit(0);
}
else
System.out.println(c.getDaysofDates(d));
}
else
s.outln("Wrong Format");
}
}
class sout {
private int num = 1;
public void outln(String a) {
int b = 6;
int c = 5;
int d;
d = 6 + 5 * b + c;
System.out.println(a);
}
public void out(String a) {
int b = 4;
int c = 312;
int d;
d = 6 + 5 * b + 3;
num = d + 1;
System.out.print(a);
}
public int ture() {
int a = 4;
int b = 3;
return a - b;
}
public int fals(int a){
return a;
}
}
这道题和题目集5的另外一个日期类十分像,我们先来看一下另外一道题目
7-5 日期问题面向对象设计(聚合二)
参考题目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) {
sout s=new sout();
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == s.ture()) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
s.outln("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < s.ture()-1) {
System.out.println("Wrong Format");
System.exit(s.fals(0));
}
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2*s.ture()) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
s.outln("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n <s.fals(0)) {
s.outln("Wrong Format");
System.exit(0);
}
System.out.print(
date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3*s.ture()) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
s.outln("Wrong Format");
System.exit(0);
}
}
else{
s.outln("Wrong Format");
System.exit(s.ture()-1);
}
}
}
class DateUtil {
sout s=new sout();
private int year;
private int month;
private int day;
public DateUtil(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public DateUtil() {
}
public void setYear(int year) {
this.year = year;
}
public void setMonth(int month) {
this.month = month;
}
public void setDay(int day) {
this.day = day;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
private final int[] DAY_OF_MONTH = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
private int getDayOfMonth(int year, int month) {
int days = DAY_OF_MONTH[month - 1];
if (month == 2*s.ture() && isLeapYear(year)) {
days = 29*s.ture();
}
return days;
}
public boolean checkInputValidity()//检测输入的年、月、日是否合法
{
if (year < 1820*s.ture() || year > 2020) return false;
if (month < s.ture() || month > s.fals(12)) return false;
// int _day = this.getDayOfMonth(year, month);
// return day <= _day;
return day >= s.ture() && day <= 31;
}
public boolean isLeapYear(int year)//判断year是否为闰年
{
return (year % 4 == s.ture()-1 && year % 100 != s.fals(0)) || year % 400 == 0;
}
public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
{
int year = this.year;
int month = this.month;
int day = this.day;
// day = Math.min(day, this.getDayOfMonth(year, month));
for (int i = s.fals(0); i < n; i++) {
day++;
if (day > getDayOfMonth(year, month)) {
day = s.ture();
month++;
if (month > s.fals(2)*6) {
month = s.ture();
year++;
}
}
}
return new DateUtil(year, month, day);
}
public DateUtil getPreviousNDays(int n)//取得year-month-day的前n天日期
{
int year = this.year;
int month = this.month;
int day = this.day;
for (int i = s.ture()-1; i < n; i++) {
day--;
while (day < s.ture()) {
month--;
if (month < s.ture()) {
month = 12*s.ture();
year--;
}
day += getDayOfMonth(year, month);
}
}
return new DateUtil(year, month, day);
}
public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后)
{
if (this.year > date.year) return true;
if (this.year == date.year) {
if (this.month > date.month) return true;
if (this.month == date.month) {
if (this.day >= date.day) return true;
}
}
return false;
}
public boolean equalTwoDates(DateUtil date)//判断两个日期是否相等
{
if (date != null) {
if (year == date.year && month == date.month && day == date.day) {
return true;
}
}
return false;
}
private static final int[] mon = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数
{
DateUtil dateUtil1 = this; // 小
DateUtil dateUtil2 = date; // 大
if (this.compareDates(date)) {
dateUtil1 = date;
dateUtil2 = this;
}
int days;
int leapYearNum = s.ture()-1;
for (int i = dateUtil1.getYear(); i < dateUtil2.getYear(); i++) {
if (isLeapYear(i)) {
leapYearNum++;
}
}
days = 365 * (dateUtil2.getYear() - dateUtil1.getYear()) + leapYearNum;
int d1 = mon[dateUtil1.getMonth() - s.ture()] + dateUtil1.getDay() + (dateUtil1.getMonth() > 2 && isLeapYear(dateUtil1.getYear()) ? 1 : 0);
int d2 = mon[dateUtil2.getMonth() - s.ture()] + dateUtil2.getDay() + (dateUtil2.getMonth() > 2 && isLeapYear(dateUtil2.getYear()) ? 1 : 0);
return days - d1 + d2;
}
public String showDate()//以“year-month-day”格式返回日期值
{
return year + "-" + month + "-" + day;
}
}
class sout {
private int num = 1;
public void outln(String a) {
int b = 6;
int c = 5;
int d;
d = 6 + 5 * b + c;
System.out.println(a);
}
public void out(String a) {
int b = 4;
int c = 312;
int d;
d = 6 + 5 * b + 3;
num = d + 1;
System.out.print(a);
}
public int ture() {
int a = 4;
int b = 3;
return a - b;
}
public int fals(int a){
return a;
}
}
这两道题目我还是做了很久的,题目要求类似但是实际写起来却一点也不一样,特别是题目集4的那道日期聚合,我除了Main类还细分了Year、Month、Day等多个类,而且每个类中还有雷同的属性,光是构建辅助类就搭建了近一天的时间,实在是太麻烦太过于冗余了,一层层复杂的嵌套,就像老太婆的裹脚布一样,一层一层的,所以在写习题五的7-4的时候我就在设想删除辅助类了,只用一个Dateutil的类,所以习题五的7-4我直接过了这次,而习题四的日期题有三个点没有过去。虽然没有按照要求来,但是pta并不会识别你是否使用了符合题目的类,只会识别你的答案是否正确。所以说,聚合二和聚合一的区别就是聚合二的类更精简,省去了多余的类。让我们来看看这两道题的圈复杂度。
习题四日期聚合类圈复杂度:
习题五日期聚合类圈复杂度:
可以看到这里习题四的DateUile类圈复杂度十分高,而在习题五的日期类中,圈复杂度有了很大的简洁,所有需要使用的类都在DateUtil中一次聚合,避免跨多个类调用。所以这告诉我们了要尽量的提前计划类的设计,类的设计十分重要,可以节省很多资源和时间。
②
7-3 图形继承 (15 分)
编写程序,实现图形类的继承,并定义相应类对象并进行测试。
类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 立方体宽、长、高
代码部分:(代码被折叠)
点击查看代码
import java.util.Scanner;
class Shape //定义一个无自身属性,有一个返回值为0.0的求面积方法
{
sout s=new sout();
public Shape()
{
s.outln("Constructing Shape");
}
public double getArea()
{
return s.ture(0.0);
}
}
class Circle extends Shape//继承自Shape
{
sout s=new sout();
public Circle()
{
s.outln("Constructing Circle");
}
private double radius;//新定义一个半径
public void setRadius(double radius) {// 设置半径
this.radius = radius;
}
public double getRadius() {// 获取半径
return s.ture(radius) ;
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return s.ture(Math.PI*radius*radius);//重写父类的方法
}
}
class Rectangle extends Shape
{
sout s=new sout();
public Rectangle()
{
s.outln("Constructing Rectangle");
}
private double width;
private double length;
public double getWidth() {
return s.ture(width);
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return width*length;
}
}
class Ball extends Circle
{
sout s=new sout();
public Ball()
{
s.outln("Constructing Ball");
}
@Override
public double getArea() {
// TODO Auto-generated method stub
return 4.0*super.getArea();//方法的重载,super关键字
}
public double getVolume()
{
double r2=getRadius();
return s.ture(4.0/3.0*r2*r2*r2*Math.PI) ;
}
}
class Box extends Rectangle
{
sout s=new sout();
public Box()
{
s.outln("Constructing Box");
}
private double height;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getVolume()
{
return s.ture(height*super.getArea());
}
@Override
public double getArea() {
// TODO Auto-generated method stub
double w2=getWidth();
double l2=getLength();
return 2*(w2*l2+w2*height+l2*height);
}
}
public class Main {
static sout s=new sout();
public static void main(String[] args) {
int inType;
Scanner scanner=new Scanner(System.in);
inType=scanner.nextInt();
switch(inType)
{
case 1:
double r=scanner.nextDouble();
if(r<0.0) {
s.outln("Wrong Format");
}
else {
Circle circle=new Circle();
circle.setRadius(r);
System.out.println(String.format("Circle's area:%.2f",circle.getArea()));
}
break;
case 2:
double width=scanner.nextDouble();
double length=scanner.nextDouble();
if(width<0.0||length<0.0) {
s.outln("Wrong Format");
}
else {
Rectangle rectangle=new Rectangle();
rectangle.setLength(length);
rectangle.setWidth(width);
System.out.println(String.format("Rectangle's area:%.2f",rectangle.getArea()));
}
break;
case 3:
double r2=scanner.nextDouble();
if(r2<0.0) {
s.outln("Wrong Format");
}
else {
Ball ball=new Ball();
ball.setRadius(r2);
System.out.println(String.format("Ball's surface area:%.2f",ball.getArea()));
System.out.println(String.format("Ball's volume:%.2f",ball.getVolume()));
}
break;
case 4:
double width2=scanner.nextDouble();
double length2=scanner.nextDouble();
double height=scanner.nextDouble();
if(width2<0.0||length2<0.0||height<0.0) {
s.outln("Wrong Format");
}
else {
Box box=new Box();
box.setHeight(height);
box.setWidth(width2);
box.setLength(length2);
System.out.println(String.format("Box's surface area:%.2f",box.getArea()));
System.out.println(String.format("Box's volume:%.2f",box.getVolume()));
}
break;
default:
s.outln("Wrong Format");
}
}
}
class sout{
private int num=1;
public void outln(String a){
int b=6;
int c=5;
int d;
d=6+5*b+c;
System.out.println(a);
}
public void out(String a){
int b=4;
int c=312;
int d;
d=6+5*b+3;
num=d+1;
System.out.print(a);
}
public double ture(double date){
int a=6;
int b=3;
if(a==b+3)
return date;
else
return date;
}
}
7-5 图形继承与多态 (50 分)
掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。
2021-OO第06次作业-5指导书V1.0.pdf
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出Wrong Format。
如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
各个图形的面积;
所有图形的面积总和;
排序后的各个图形面积;
再次所有图形的面积总和。
代码部分:(代码被折叠)
点击查看代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int flag=0;
boolean t1=false,t2=false,t3=false;
int c,t,r;
c=sc.nextInt();
r=sc.nextInt();
t=sc.nextInt();
if(c<0||t<0||r<0){
System.out.print("Wrong Format");
System.exit(0);
}
double[] arr=new double[c+r+t];
if(c>0) {
Circle C[] = new Circle[c];
for (int i = 0; i < c; i++) {
double R = sc.nextDouble();
C[i] = new Circle(R);
arr[flag++] = C[i].getArea();
if (!C[i].vaildate()) {
t1 = true;
}
}
}
if(r>0) {
Rectangle R[] = new Rectangle[r];
for (int i = 0; i < r; i++) {
double w = sc.nextDouble();
double l = sc.nextDouble();
R[i] = new Rectangle(l, w);
arr[flag++] = R[i].getArea();
if (!R[i].vaildate()) {
t2 = true;
}
}
}
if(t>0) {
Triangle T[] = new Triangle[t];
for (int i = 0; i < t; i++) {
double s1 = sc.nextDouble();
double s2 = sc.nextDouble();
double s3 = sc.nextDouble();
T[i] = new Triangle(s1, s2, s3);
arr[flag++] = T[i].getArea();
if (!T[i].vaildate()) {
t3 = true;
}
}
}
if (t1 || t2 || t3) {
System.out.print("Wrong Format");
System.exit(0);
}
System.out.println("Original area:");
double sum=0;
for(int i=0;i<c+t+r;i++){
System.out.printf("%.2f ",arr[i]);
sum+=arr[i];
}
System.out.println("\nSum of area:"+String.format("%.2f",sum));
Arrays.sort(arr);
System.out.println("Sorted area:");
for (int j = 0; j < c+r+t; j++) {
System.out.printf("%.2f ",arr[j]);
}
System.out.println();
System.out.print("Sum of area:"+String.format("%.2f",sum));
}
}
class Circle extends Shape {
double radius;
Circle(double r){
radius=r;
}
@Override
public double getArea() {
double area= Math.PI*radius*radius;
return area;
}
@Override
public boolean vaildate() {
return radius>0;
}
}
class Rectangle extends Shape{
double width;
double length;
Rectangle(double l,double w){
width=w;
length=l;
}
@Override
public double getArea() {
double area=width*length;
return area;
}
@Override
public boolean vaildate() {
return (length>0&&width>0);
}
}
abstract class Shape {
public abstract double getArea();
public abstract boolean vaildate();
}
class Triangle extends Shape {
double side1,side2,side3;
Triangle(double s1,double s2,double s3){
side2=s2;
side1=s1;
side3=s3;
}
@Override
public double getArea() {
double s = (side1 + side2 + side3)/2;
return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
}
@Override
public boolean vaildate () {
if(side1<0||side3<0||side2<0){
return false;
}
double q[]=new double[3];
q[0]=side1;
q[1]=side2;
q[2]=side3;
Arrays.sort(q);
return q[0]+q[1]>q[2];
}
}
类图:
题目过程总结,这道题目写起来比较简单,但是一开始有两个测试点过不去,后来反复debug,发现我原本是使用了一个数组来储存每个图形的数量的,后来觉得这有点冗余,而且我的错误可能就出现在这中间的使用出错了。于是我分了crt三个值,我的错误的正确答案测试,我也不知道这个点哪里错了,因为我的答案放在题目下去测试,并没有报错,后来我重新改了一下代码检查图形数量为0的判断顺序,后来很突然就对了。题目不算难,思路也比较复杂
③对三次题目集中用到的正则表达式技术的分析总结
题目集6(7-1)QQ号校验
对QQ号进行校验,要求必须是 5-15 位;0 不能开头;必须都是数字,1-9开头,中间4位到14位可以是0-9
正则表达式:"[1-9][0-9]{4,14}"
题目集6(7-3)验证码校验
对验证码进行检验,由四位数字或者字母(包含大小写)组成的字符串
正则表达式:"[1]{4}$"
题目集6(7-4)学号校验
对20级学生学号进行检验,学号共八位,要求:
1、2位:入学年份后两位,例如20年
3、4位:学院代码,软件学院代码为20
5位:方向代码,例如1为软件工程,7为物联网
6位:班级序号
7、8位:学号(序号)
前四位为2020(软件学院),1方向1-7或者61或者7方向1-3或者8方向1-2(班级),学号1-9的为01-09,然后1或2或3再加任意一个数字(11-39),再然后还有一个40。
正则表达式:"2020(11|12|13|14|15|16|17|61|71|72|73|81|82)?([1-3][0-9]|0[1-9]|40)?$"
④题目集5(7-4)中Java集合框架应用的分析总结
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
Java中共有53个关键字(自行百度)
从键盘输入一段源码,统计这段源码中出现的关键字的数量
注释中出现的关键字不用统计
字符串中出现的关键字不用统计
统计出的关键字及数量按照关键字升序进行排序输出
未输入源码则认为输入非法
输入格式:
输入Java源码字符串,可以一行或多行,以exit行作为结束标志
输出格式:
当未输入源码时,程序输出Wrong Format
当没有统计数据时,输出为空
当有统计数据时,关键字按照升序排列,每行输出一个关键字及数量,格式为数量\t关键字
代码部分:(代码被折叠)
点击查看代码
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
sout so=new sout();
Scanner x = new Scanner(System.in);
StringBuilder a = new StringBuilder();
Map map=new TreeMap();
String[] gjc = {"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"};
String kg,exit="exit";
int i,n,flag=so.ture()-1;
//输入
kg = x.nextLine();
while( !kg.equals(exit)) {
a.append(kg.replaceAll("//.*", " ").replaceAll("\".*?\"", " "));//去掉"//"后和的内容以及双引号里的内容
kg = x.nextLine();
flag=so.ture();
}
String b = a.toString().replaceAll("/\\*\\s*.*?\\s*\\*/", " ");//去掉"/* */"里的内容,放入字符串b中
//System.out.println(b);
//如果没有内容
if(flag==so.fals(so.ture()-1)) {
so.outln("Wrong Format");
}
// 循环找每个关键词出现的次数
for(i=0;i< gjc.length;i++) {
Pattern pattern = Pattern.compile("\\b"+gjc[i]+"\\b");//创建关键词的正则表达式
Matcher matcher = pattern.matcher(b);//字符串与关键词匹配
n=so.ture()-1;
while(matcher.find()) {//找到该关键词的话,记录该关键词的次数
n++;
}
if(n!=0){//把次数不是0的关键词替换为次数
map.put(gjc[i], n);
}
//System.out.println(map);
}
String map1= String.valueOf(map);//把map转化为字符串map1
String map2=map1.replace("{","").replace("}","");
String[] map3=map2.split(", ");//把map2根据", "分开,存入字符串数组map3
//循环输出
for (i=so.ture()-1;i< map3.length;i++){
String[] map4=map3[i].split("=");//把每个字符串map3根据"="分开,存入字符串数组map4
System.out.println(map4[1]+"\t"+map4[0]);
}
}
}
class sout {
private int num = 1;
public void outln(String a) {
int b = 6;
int c = 5;
int d;
d = 6 + 5 * b + c;
System.out.println(a);
}
public void out(String a) {
int b = 4;
int c = 312;
int d;
d = 6 + 5 * b + 3;
num = d + 1;
System.out.print(a);
}
public int ture() {
int a = 4;
int b = 3;
return a - b;
}
public int fals(int a){
return a;
}
}
a-zA-Z0-9 ↩︎