blog作业1
目 录
一、前言
二、设计与分析
三、踩坑心得
四、改进建议
五、总结
一、前言
题目集一主要考察对基本的Java语法的使用以及简单的计算,题量较大,但难度较小;题目集二主要考察对字符串,数组,函数的基本使用能力,题量适中,难度也在中等偏下的水平;题目集三主要考察对类与对象的理解与使用,题量小,前两题难度适中,第三题偏难。
二、设计与分析
(1)题目集1-7-8:
7-8 判断三角形类型 (20 分)
输入三角形三条边,判断该三角形为什么类型的三角形。
输入格式:
在一行中输入三角形的三条边的值(实型数),可以用一个或多个空格或回车分隔,其中三条边的取值范围均为[1,200]。
输出格式:
(1)如果输入数据非法,则输出“Wrong Format”; (2)如果输入数据合法,但三条边不能构成三角形,则输出“Not a triangle”; (3)如果输入数据合法且能够成等边三角形,则输出“Equilateral triangle”; (3)如果输入数据合法且能够成等腰直角三角形,则输出“Isosceles right-angled triangle”; (5)如果输入数据合法且能够成等腰三角形,则输出“Isosceles triangle”; (6)如果输入数据合法且能够成直角三角形,则输出“Right-angled triangle”; (7)如果输入数据合法且能够成一般三角形,则输出“General triangle”。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
int i;
double a,b,c;
Scanner input = new Scanner(System.in);
double[] s=new double[3];
for(i=0;i<3;i++){
double num=input.nextDouble();
s[i]=num;
}
a=s[0];
b=s[1];
c=s[2];
if(a<1||a>200||b<1||b>200||c<1||c>200){ //非法
System.out.println("Wrong Format");
}
else{ //合法
if(a+b>c&&a+c>b&&b+c>a){ //能
if(a==b||a==c||b==c){ //等腰
if(a==b&&b==c&&a==c){ //等边
System.out.println("Equilateral triangle");
}
else{
if((a*a+b*b==c*c)||(a*a+c*c==b*b)||(b*b+c*c==a*a)){ //等腰直角
System.out.println("Isosceles right-angled triangle");
}
else{
System.out.println("Isosceles triangle"); //等腰
}
}
}
else{ //不等腰
if((a*a+b*b==c*c)||(a*a+c*c==b*b)||(b*b+c*c==a*a)){ //普通直角
System.out.println("Right-angled triangle");
}
else{ //一般
System.out.println("General triangle");
}
}
}
else{ //不能
System.out.println("Not a triangle");
}
}
}
}
使用多层嵌套if-else语句,使整段代码结构紧凑,条理清晰。具体设计分析为:输入可分为合法与非法,合法可分为能构建三角形与不能构建三角形,而三角形又可分为等腰三角形与普通三角形,等腰三角形包括等边三角形与等腰三角形,等腰三角形再分为等腰三角形和等腰直角三角形,普通三角形分为直角三角形和普通三角形,如此,使用多层嵌套if-else语句进行分情况输出就能将该题所包含的七种情况就毫无遗漏地执行完成了。这道题目虽然简单,但也能够有许多种不同的解答方式,不同的方法解题的复杂度不同,该题可培养答题者的严密逻辑,比如我这种方法我自我感觉就非常好。
(2)题目集2-7-4
7-4 求下一天 (30 分)
输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
要求:Main类中必须含有如下方法,签名如下:
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Wrong Format”;
- 当输入日期合法,输出下一天,格式如下:Next date is:年-月-日
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year=input.nextInt();
int month=input.nextInt();
int day=input.nextInt();
if(year<1820||year>2020||month<1||month>12||day<1||day>31){
System.out.println("Wrong Format");
}
else{
if((year%4==0&&year%100!=0)||(year%400==0)){ //闰年
if((month==2&&day>29)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)){
System.out.println("Wrong Format");
}
else{
if((month==2&&day<29)||(month==4&&day<30)||(month==6&&day<30)||(month==9&&day<30)||(month==11&&day<30)||(month==1&&day<31)||(month==3&&day<31)||(month==5&&day<31)||(month==7&&day<31)||(month==8&&day<31)||(month==10&&day<31)||(month==12&&day<31)){
System.out.printf("Next date is:%d-%d-%d",year,month,day+1);
}
if(month==12&&day==31){
System.out.printf("Next date is:%d-1-1",year+1);
}
if((month==2&&day==29)||(month==4&&day==30)||(month==6&&day==30)||(month==9&&day==30)||(month==11&&day==30)||(month==1&&day==31)||(month==3&&day==31)||(month==5&&day==31)||(month==8&&day==31)||(month==10&&day==31)){
System.out.printf("Next date is:%d-%d-1",year,month+1);
}
if(month==7&&day==31){
System.out.printf("Next date is:%d-%d-1",year,month+1);
}
}
}
else{ //平年
if((month==2&&day>28)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)){
System.out.println("Wrong Format");
}
else{
if(month==2&&day==28){
System.out.printf("Next date is:%d-%d-1",year,month+1);
}
if(month==7&&day==31){
System.out.printf("Next date is:%d-%d-1",year,month+1);
}
}
}
}
}
}
这道题需要考虑多方面的因素,如闰年二月二十九天,平年二月只有二十八天,一月、三月、五月、七月、八月、十月、十二月有三十一天,二月、四月、六月、九月、十一月只有三十天,在每月的最后一天的下一天是第二个月的第一天,另外,还需考虑跨年等因素。这道题的解答方法有很多,我首先想的方法是使用if-else语句,虽然这道题使用if-else语句也能够做出来,但在很多方面有缺陷,然而当我意识到的时候我已经快做完了,所以就用这个方法写到底了。
这道题最好的方法应该就是使用创建方法和调用方法,使整个源代码的每一部分的内容都可清晰的知晓,这不仅有利于答题者在编写的过程中思路清晰,防止写着写着不知道自己在干什么,也有利于他人的分析;而我使用的方法就是直接使用if-else语句硬写,这使我在做题过程中思路混乱,答案错误需要修改时很难找到错误所在地,这是一个反面教材供大家参考。
(3)题目集2-7-5
7-5 求前N天 (30 分)
输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
输入格式:
在一行中输入年月日的值以及n的值,可以用一个或多个空格或回车分隔。
输出格式:
- 当输入的年、月、日以及n的值非法时,输出“Wrong Format”;
- 当输入数据合法时,输出“n days ago is:年-月-日”
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year=input.nextInt();
int month=input.nextInt();
int day=input.nextInt();
int n=input.nextInt();
if(year<1820||year>2020||month<1||month>12||day<1||day>31||n<-10||n>10){
System.out.println("Wrong Format");
}
else if(n==0){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day);
}
else{
if((year%4==0&&year%100!=0)||(year%400==0)){ //闰年
switch(month){
case 1:
if(n>0&&n>day){
System.out.printf("%d days ago is:%d-12-%d",n,year-1,31-n+day);
}
case 12:
if(n<0){
System.out.printf("%d days ago is:%d-1-%d",n,year+1,day-31-n);
}
case 8:
case 9:
if(n<=0&&day-n>31){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month+1,day-31-n);
}
if(n<=0){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(n>0&&n<day){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(n>0&&n>day){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month-1,31-n+day);
}
case 3:
if(day-n>0&&day<=31){ //前几天
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(day-n<=0){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month-1,29+day-n);
}
}
}
else{ //平年
if(month==2&&day==29){
System.out.println("Wrong Format");
}
switch(month){
case 1:
if(n>0&&n>day){
System.out.printf("%d days ago is:%d-12-%d",n,year-1,31-n+day);
}
case 12:
if(n<0){
System.out.printf("%d days ago is:%d-1-%d",n,year+1,day-31-n);
}
case 8:
case 9:
if(n<=0&&day-n>31){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month+1,day-31-n);
}
if(n<=0&&day-n<=31){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(n>0&&n<day){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(n>0&&n>day){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month-1,31-n+day);
}
case 3:
if(day-n>0&&day<=31){ //前几天
System.out.printf("%d days ago is:%d-%d-%d",n,year,month,day-n);
}
else if(day-n<=0){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month-1,28+day-n);
}
case 2:
if(n<0&&day-n<=28){
System.out.printf("%d days ago is:%d-%d-%d",n,year,month-1,28+day-n); //gai
}
}
}
}
}
}
这道题理论上和上道题十分的类似,都是需要考虑闰年二月二十九天,平年二月只有二十八天,一月、三月、五月、七月、八月、十月、十二月有三十一天,二月、四月、六月、九月、十一月只有三十天,在每月的最后一天的下一天是第二个月的第一天,跨年等因素。但这道题多了个变量 n,前n天(当n > 0时)、后n天(当n<0时)。运用函数(方法)可以轻松完成。
(4)题目集3-7-2
7-2 定义日期类 (28 分)
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
要求:Date类结构如下图所示:
输入格式:
在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。
输出格式:
- 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
- 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int year=input.nextInt();
int month=input.nextInt();
int day=input.nextInt();
if(year<1900||year>2000||month<1||month>12||day<1||day>31){
System.out.println("Date Format is Wrong");
}
else{
if((year%4==0&&year%100!=0)||(year%400==0)){ //闰年
if((month==2&&day>29)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)){
System.out.println("Date Format is Wrong");
}
else{
if((month==2&&day<29)||(month==4&&day<30)||(month==6&&day<30)||(month==9&&day<30)||(month==11&&day<30)||(month==1&&day<31)||(month==3&&day<31)||(month==5&&day<31)||(month==7&&day<31)||(month==8&&day<31)||(month==10&&day<31)||(month==12&&day<31)){
System.out.printf("Next day is:%d-%d-%d",year,month,day+1);
}
if(month==12&&day==31){
System.out.printf("Next day is:%d-1-1",year+1);
}
if((month==2&&day==29)||(month==4&&day==30)||(month==6&&day==30)||(month==9&&day==30)||(month==11&&day==30)||(month==1&&day==31)||(month==3&&day==31)||(month==5&&day==31)||(month==8&&day==31)||(month==10&&day==31)){
System.out.printf("Next day is:%d-%d-1",year,month+1);
}
if(month==7&&day==31){
System.out.printf("Next day is:%d-%d-1",year,month+1);
}
if(month==12&&day==31){
System.out.printf("Next day is:%d-1-1",year+1);
}
}
}
else{ //平年
if((month==2&&day>28)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)){
System.out.println("Date Format is Wrong");
}
else{
if(month==2&&day==28){
System.out.printf("Next day is:%d-%d-1",year,month+1);
}
if(month==7&&day==31){
System.out.printf("Next day is:%d-%d-1",year,month+1);
}
if(month==12&&day==31){
System.out.printf("Next day is:%d-1-1",year+1);
}
if(month==12&&day!=31){
System.out.printf("Next day is:%d-%d-&d",year,month,day+1);
}
}
}
}
}
}
这道题与题目集二中的题相似,只不过这道题需要用到类,但大体上还是可以参考题目集2-7-4的,这里就不作详细说明了 。
(5)题目集3-7-3
7-3 一元多项式求导(类设计) (50 分)
编写程序性,实现对简单多项式的导函数进行求解。详见作业指导书。 OO作业3-3题目说明.pdf
输入格式:
在一行内输入一个待计算导函数的表达式,以回车符结束。
输出格式:
- 如果输入表达式不符合上述表达式基本规则,则输出“Wrong Format”。
- 如果输入合法,则在一行内正常输出该表达式的导函数,注意以下几点: 结果不需要排序,也不需要化简;
- 当某一项为“0”时,则该项不需要显示,但如果整个导函数结果为“0”时,则显示为“0”;
- 当输出结果第一项系数符号为“+”时,不输出“+”;
- 当指数符号为“+”时,不输出“+”;
- 当指数值为“0”时,则不需要输出“x^0”,只需要输出其系数即可
这道题我个人认为难度还是有点大的,需要自学正则表达式,然后用类与方法的设计解答。
三 、踩坑心得
在源码的提交过程中最常出现的就是语法问题导致的编译错误了,比如写着写着漏了一个大括号,当一个程序代码中大括号比较多且密集时,遗漏了大括号就比较麻烦了,因此在编写过程中一定要仔细,且在格式方面要做适当的缩进处理,这样可使整段代码看上去舒适整洁,便于修改。其次,在写代码前千万要确定一种正确的方法,避免写到一半发现方法错误,继续写又比较困难,又不想重新开始,就像做题目集2-7-5那样。
四、改进建议
(1)建议题目集2的7-5题中的变量n可以改成两个变量,一个变量用于计算前几天,另一个变量用于计算后几天,这样可以避免答题过程中晕头转向,分不清正负号;
(2)关于可持续性,我觉得应该尽量用类与方法做题,如此,之后的题目就可以是之前的题目的升级,在之前的题目上加一些要求,使题目更加多功能化,使用类与方法的方法进行代码编写,在下次做题时就能在之前代码的基础上添加方法进行作答,方便快捷,在题目升级的同时,代码功能也随之越来越丰富。
五、总结
在本阶段三个题目集的学习过程中,我学到了使用Java编程语言的基本语法以及算法操作,还有运用类与对象进行的较复杂的算法操作;对类与对象的使用还很不熟悉,存在很多不足,需要进一步的学习及研究。建议老师在布置作业前先大概讲解一下相关知识点,这样在做作业的过程中不会太吃力。
浙公网安备 33010602011771号