OOP训练集1-3总结
一,前言
题目集1-3总体难度不大,但有个别题目比较难。题目集1题目量较大,共有12题,作业时间很紧张。所以到题目集2发布时我提前做好准备,有充足的时间完成作业。
题目集1考察的是基本编程技能,例如java函数的基本结构,一些简单的输出,if语句的使用,和字符串的使用。其中字符串的使用比较难需要自己去书上学习,其他知识相比之下就很容易掌握。
题目集2在1的基础上,多了switch语句的使用,以及float类型的数据。
题目集3开始考察类的使用,circle类,account类和date类,难度增大了很多。
二,设计与分析
题目集1:7-3
打印九九乘法表,乘法表格式如图
接收用户从键盘输入的一个1到9(含边界)的整数,假设该整数是n,则打印乘法表的前n行。
说明:
(1)用户输入的整数不在1到9这个范围内,则固定输出下面信息:
INPUT ERROR.
(2)两个整数之间的乘号,是使用的大写字母X。同一行的多个乘法结果之间,用制表符\t分开,一行末尾没有多余的制表符
源代码:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
if(1<=n&&n<=9){
int i=1;
int j=1;
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
if(i==j) System.out.print(i+"X"+j+"="+i*j);
else
System.out.print(i+"X"+j+"="+i*j+"\t");
}
System.out.println();
}
}
else{
System.out.print("INPUT ERROR.");
}
}
}
运行结果:
分析:这个题目主要考察双重循环输出,最后要呈阶梯形输出九九乘法表,其中第一个for循环为for(i=1;i<=n;i++),第二个为for(j=1;j<=i;j++),最初做这个题目的时候第二个循环我写成了for(j=1;j<=n;j++),导致输出时全部结果都是9行的乘法表而不是用户输入的数字n所代表的行数,在找同学帮我看过之后我重新改正,最终输出了正确结果。
题目集2:7-4游戏角色选择
一款网游中包括4个种族:人类、精灵、兽人、暗精灵,每个种族包含三种角色:战士、法师、射手。玩家新建人物时需要选择种族和角色。请编写角色选择程序。
输入格式:
两个整数:游戏种族、角色的选项,以空格分隔。例如:1 2。
种族选项设定为:1、人类 2、精灵 3、兽人 4、暗精灵
角色选项设定为:1、战士 2、法师 3、射手
输出格式:
所选择的种族、角色的名称,以空格分隔。例如:人类 法师
若输入数值超出选项范围,输出“Wrong Format”
输出格式:
所选择的种族、角色的名称,以空格分隔。例如:人类 法师
若输入数值超出选项范围,输出“Wrong Format”
输入样例1:
在这里给出一组输入。例如:
1 2
输出样例1:
在这里给出相应的输出。例如:
人类 法师
输入样例2:
在这里给出一组输入。例如:
1 6
输出样例2:
在这里给出相应的输出。例如:
Wrong Format
源代码:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
if(1<=n&&n<=9){
int i=1;
int j=1;
for(i=1;i<=n;i++){
for(j=1;j<=i;j++){
if(i==j) System.out.print(i+"X"+j+"="+i*j);
else
System.out.print(i+"X"+j+"="+i*j+"\t");
}
System.out.println();
}
}
else{
System.out.print("INPUT ERROR.");
}
}
}
运行结果
分析:这个题目做的时候感觉很有意思,四个种族和三个职业相组合,共有12种组合,每一个case最后都要用break跳出,初做的时候不仔细,没注意少了一个break就编译不出来,从头到尾检查过来才发现,所以编程的时候必须细心一点,避免不必要的错误。
7-5
题目集3:7-3
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
源代码:
import java.util.*;
public class Main{
public static boolean isLeapYear(int year) {
boolean isLeapYear=(year%4==0&&year%100!=0);
return isLeapYear;}
public static boolean checkInputValidity(int year,int month,int day) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2] = 29;
boolean checkInputValidity=(year>=1900&&year<=2000&&month>0&&month<=12&&day<=aa[month]&&day>0);
return checkInputValidity;}
public static void nextDate(int year,int month,int day) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2]=29;
int a=0,b=0,c=0;
if(checkInputValidity(year,month,day)){
if(month==12){
if(day==aa[month]){
a=year+1;
b=1;
c=1;}
if(day>0&&day<aa[month]){
a=year;
b=month;
c=day+1;}
}
if(month<12){
if(day==aa[month]){
a=year;
b=month + 1;
c=1;}
if(day>0&&day<aa[month]){
a=year;
b=month;
c=day+1;}
}
System.out.println("Next day is:"+a+"-"+b+"-"+c);}
else System.out.println("Date Format is Wrong");}public static void main(String[] args){
Scanner xy=new Scanner(System.in);
Main XY=new Main();
int year = xy.nextInt();
int month = xy.nextInt();
int day = xy.nextInt();
XY.nextDate(year,month,day);
}
}
输出结果:
分析:这个时间类,主函数中用户输入日期,程序判断并输出下一天,其中闰年函数判断是否为闰年,另外一个函数用于判断输入的时间是否符合要求;需要特别注意的是当年份为闰年时,数组保存的每个月的最大天数中,2月需要从28改为29天,当天数到达当月最大天数时,月份+1,天数变为1;还有一种情况则是当日期为12月31日时,年份+1,月份天数变为1月1日。
题目集3:7-4
参考题目3和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值
应用程序共测试三个功能:
求下n天
求前n天
求两个日期相差的天数
程序主方法:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // 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()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(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) { // 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()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("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) { //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 {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
源代码:
import java.util.Scanner;
public class Main {
public static boolean isLeapYear(int year) {
boolean isLeapYear = (year % 4 == 0 && year % 100 !=0 )||year % 400 == 0;
return isLeapYear;
}
public static boolean checkInputValidity(int year,int month,int day,int n) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2] = 29;
boolean checkInputValidity = (year>=1820&&year<=2020&&month>0&&month<=12&&day<=aa[month]&&day>0&&Math.abs(n)<=10&&Math.abs(n)>=0);
return checkInputValidity;
}
public static void nextDate(int year,int month,int day,int n) {
int[] aa=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeapYear(year))
aa[2] = 29;
int a = 0,b = 0,c = 0;
if(checkInputValidity(year,month,day,n)) {
if (n==0) {
a = year;
b = month;
c = day;
}
if(month==12&&n>0) {
if(day-n<=aa[month]&&day-n>0) {
a = year;
b = month;
c = day-n;}
if(day-n<=aa[month]&&day-n<0) {
a = year;
b = month-1;
c = aa[b]-n+day;
}
if(day-n<=aa[month]&&day-n==0) {
a = year;
b = month-1;
c = aa[b]-n+day;
}
}
if(month==12&&n<0) {
if(day-n>aa[month]) {
a = year +1;
b = 1;
c =day - n -aa[month];
}
if(day-n<=aa[month]) {
a = year;
b = month;
c =day - n;
}
}
if(month>1&&month<12&&n>0) {
if(day-n<=aa[month]&&day-n>0) {
a = year;
b = month;
c = day-n;}
if(day-n<=aa[month]&&day-n<0) {
a = year;
b = month-1;
c = aa[b]-n+day;
}
if(day-n<=aa[month]&&day-n==0) {
a = year;
b = month-1;
c = aa[b]-n+day;
}
}
if(month<12&&month>1&&n<0) {
if(day-n>aa[month]) {
a = year;
b = month+1;
c =day - n -aa[month];
}
if(day-n<=aa[month]) {
a = year;
b = month;
c =day - n;
}
}
if(month == 1&&n>0) {
if(day-n<=aa[month]&&day-n>0) {
a = year;
b = month;
c = day-n;
}
if(day-n<=aa[month]&&day-n<0) {
a = year-1;
b = 12;
c = aa[b]-n+day;
}
if(day-n<=aa[month]&&day-n==0) {
a = year-1;
b = 12;
c = aa[b]-n+day;
}
}
if(month==1&&n<0) {
if(day-n>aa[month]) {
a = year;
b = month+1;
c =day - n -aa[month];
}
if(day-n<=aa[month]) {
a = year;
b = month;
c =day - n;
}
}
System.out.println(n+" days ago is:"+a+"-"+b+"-"+c);
}
else System.out.println("Wrong Format");
}
public static void main(String[] args) {
Scanner XY= new Scanner(System.in);
Main xy = new Main();
int year = XY.nextInt();
int month = XY.nextInt();
int day = XY.nextInt();
int n = XY.nextInt();
xy.nextDate(year,month,day,n);
}
}
分析:此题在7-3的基础上增加了功能,求下n天,前n天以及两个日期相差的天数,难度增大了许多.
三,踩坑心得
在打代码的要注意中英文的切换,因为不同输入法的字符不同,例如代码中有一个分号为中文形式,程序编译就会报错,而且这种错误不仔细看真的很难发现;
此外题目集2中7-6求平方根近似值,double类型的数据是过不了pta的测试点,只有float型才能过测试点。
四,总结
通过三次作业,我对面向对象的编程有了一个大概的印象,学会了基本函数的输入与输出,字符串的使用,对象的赋值,作用域,修饰符的使用,java中数组的使用,以及不同的类的使用,
一个对象赋值给另一个队象在默认下是引用传递,赋的是地址;
全局变量:作用域在整个类中,可以被其他类使用;默认赋值,可不赋值直接使用;可以加访问修饰符。
局部变量:作用域在定义它的代码块中;必须赋值后才能使用;不能使用访问控制符。
java提供四种访问控制修饰符号:
公开级别:用public修饰,对外公开;
受保护级别:用protected修饰,对子类和同一个包中的类公开;
默认级别:没有修饰符号,向同一个包的类公开;
私有级别:用private修饰,只有类本身可以访问,不对外公开;
类中需要但没有声明和定义的构造函数编译器在需要时都会自动生成。
其中类的使用对我来说有些难度,需要日后进一步学习来补充我在这方面的短板;
我还需要学习很多,例如用sourcemonitor生成报表内容,用powerdesigner画类图,这都是我目前还不会的东西,需要一点时间尝试掌握。