题目集的总结性blog
历时三个星期,我学习了java的部分基础,也在三次练习中收获了很多知识,为了能更好的学习java,我觉得有必要对这次的作业进行一次总结。
在题目集7-8中,题目要求对三角形的类型进行判断,例如等边三角形,等腰三角形,直角三角形等。首先,在初学java的前提下,我们应该了解java中使用Scanner类从控制台获取输入,并利用基本数据类型、变量、常量、操作符、表达式以及输入输出来进行基本的程序设计。import java.util.Scanner与Scanner input=new Scanner(System.in)是同时存在的,也可以把它们合并为java.util.Scanner input=new java.util.Scanner(System.in),两种写法都是正确的,但个人更喜欢用前者。从控制台读取输入可以分为三步走:导入—创建—使用。例如在该题中就充分的体现了这三部曲,导入import java.util.Scanner,Scanner类在包java.util里。有两种类型的import语句:明确导入和通配导入。在该题中我的写法就是明确导入。通配导入是通过星号作为通配符,导入一个包中所有的类,例如import java.util.*。关于创建:Scanner input=new Scanner(System.in)。这步是必不可少的。导入:
double x=input.nextDouble();
double y=input.nextDouble();
double z=input.nextDouble();
在初写java代码时,我没有明确不同类型的变量应用不同的输入语句,例如int型变量的输入语句input.nextInt();String型变量的输入input.nextLine()和input.next()。在写该题时也会犯一些小错误,比如没有区分好标识符的大小写导致的编译错误,这让我认识到java是区分大小写的,且area、Area、AREA是不同的标识符。在本题中还涉及到一维数组的使用
double []list=new double[3];
list[0]=x;
list[1]=y;
list[2]=z;
一旦数组被创建,它的大小是固定的,使用一个数组引用变量和下标来访问数组中的元素,且数组的下标是基于0的。在该题中我还使用了数组的排序,在java.util.Arrays类中包含一些实用的方法用于常见的数组操作,比如排序和查找。例如 java.util.Arrays.sort(list);就是对list数组元素的排序。
if((x>=1&&x<=200)&&(y>=1&&y<=200)&&(z>=1&&z<=200))
{ if(x+y>z){
if(x==y&&y==z)
System.out.println("Equilateral triangle");
else if((x==y||y==z||z==x)&&x*x+y*y-z*z>=0.0001)
System.out.println("Isosceles triangle");
else if(x==y&&x*x+y*y-z*z<0.0001)
System.out.println("Isosceles right-angled triangle");
else if(x*x+y*y-z*z<0.0001&&x!=y)
System.out.println("Right-angled triangle");
else
System.out.println("General triangle");
}
if(x+y<=z)
System.out.println("Not a triangle");
}
else
System.out.println("Wrong Format");
}
在这部分代码中包含了对逻辑操作符&&、||、!、^的应用,在该题中我认识到逻辑操作符!、&&、||、^可以用于产生复合布尔表达式以及java提供的if-else选择语句。在本题中要考虑到三角形边的多种情况,在写出正确的代码之前,因为我没有考虑完全关于三角形三边的数值与三角形类型之间的关系,所以导致答案部分正确。为了更好地将各种情况一一类举出来,可以讲三条边的值放入一个数组list中,再将数组里的元素进行排序,将元素进行从小到大排列,便的到边z最大,再接下来进行分情况讨论就方便很多,且不会出现忽略莫种情况的现象。在该题中没有特别难的地方,对于初学者来说比较容易忽略部分情况导致该题部分正确,但通过编译,大部分没有考虑到的地方都可以再进行修改和补充。此外在一条语句结束时不能漏写了符号“;”,这也很需要注意。
在题目集2的7-4题中要求输入年月日并求下一天,这题的难度比题目集1的要更难一点,但通过学习课本的第6章方法一节再运用一些前面所学习过基础知识写出该题的正确代码还是可以的。在该题中的部分提示能给我们比较多的思路,例如
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) ; //求输入日期的下一天
步骤清晰,思路也一目了然。除此之外还需了解到方法名和参数列表一起构成方法签名,参数是可选的,方法可以不包含参数。在写这种包含多个方法的main函数,我深刻的体会到了这种自顶向下或自底向上的设计,而不是一次性的编写整个程序。方法抽象可以将程序模块化为整齐、
层次分明
的形式。将程序写成由简洁的方法构成的集合会比其他的方法更容易编写、调试、维护和修改。这种编写风格也会提高方法的可重用性。在写该题时,我学习到了三目运算符的应用:?前面的结果为真,返回?后面的值,否则返回:后面的值。在main函数里面包
含了多个方法的程序里可以采用逐步求精方法将大问题分解成小的易于处理的子问题。每个子问题可以使用一个方法来实现。在写代码的过程中也让我认识到了使用这种方法可以使得问题更加易于编写、重用、调试、修改和维护。在写该题的过程中,充分体现了方法之间的相关性,
即方法可以返回
一个值。我学到了方法签名是由方法名和参数列表一起构成,并且一个方法可以不包含参数,传递给方法的实际参数应该与方法签名中的形式参数具有相同的数目、类型和顺序。从该题的各个方法的书写规律及输出结果可以发现:当程序调用一个方法时,程序控制就转移到被调用的方法上,
当被调用函数执行到return或到达方法结束的右括号时,将程序还给调用者。在该程序中我们可以看到多种抽象,方法抽象是通过将方法的使用和它的实现分离来实现的,方法的实现细节封装在方法里,对于使用该方法的用户来说是隐藏的。在该题中要求求输入天数的下一天:同时输入一个
取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] ,这就要求我们要考虑到有关月份,年份,天数的各种情况。因此,产生以下代码:
public static boolean checked(int year,int month,int day,int n){
if(year<1820||year>2020||month>12||day>31||month<1||day<1)
return false;
else if(!isLeapYear(year)&&(day==29)&&month==2)
return false;
else if((month==4||month==6||month==9||month==11)&&day==31)
return false;
else if(month==2&&day>=30)
return false;
else if(n<-10&&n>10)
return false;
else
return true;
}
在写判断输入的年份、月份、日期是否正确时,经常会忽略月份小于1和日期小于1的情况,这就需要我们仔细,将每种情况都有条理的罗列出来。其中还要清楚闰年的判定方法:
public static boolean isLeapYear(int year){
return (year%400==0||(year%4==0&&year%100!=0));
}
这里返回的是boolean值:true或false.除此之外,void 方法不返回任何值,对void方法的调用必须是一条语句,因此,在main方法中 nextorlastday(year,month,day,n);作为一条语句直接显示 nextorlastday中的输出语句。
主要的决定下一天的年月日的方法是public static void nextorlastday(int year,int month,int day,int n),该方法需要对各种情况加一分析并一一罗列出来
public static void nextDate(int year,int month,int day){
if(month==2&&!isLeapYear(year)&&day==28){
month=month+1;
day=1;
}
else if(month==2&&isLeapYear(year)&&day==29){
month=month+1;
day=1;
}
else if(month==12&&day==31){
year=year+1;
month=1;
day=1;
}
else if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==31){
month=month+1;
day=1;
}
else if((month==4||month==6||month==9||month==11)&&day==30){
month=month+1;
day=1;
}
else{
if( checkInputValidity(year,month,day) )
day=day+1;
else
{System.out.println("Wrong Format");
System.exit(0);
}
}
System.out.println("Next date is:"+year +"-"+ month+"-"+day);
}
写该代码的时候特别要注意某些容易改变月份或者年份的data.
题目集7-5中要求求第n天,这题比上一题7-4的难度要大一点,要求输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时),则需要对n进行判断,并将不同n的取值分为两类来写,在日期输入合法的情况下,分
if(n>0){
if(month==5||month==7||month==10||month==12){
if(day-n>0) {day=day-n;}
else {day=day+30; day=day-n;month=month-1;}
}
else if( month==3&&isLeapYear(year) ){
if(day-n>0){day=day-n;}
else {day=day+29;day=day-n;month--;}
}
else if(month==3&&!isLeapYear(year) ){
if(day-n>0) {day=day-n;}
else {day=day+28;day=day-n;month--;}
}
else if(month==1){
if (day-n>0) {day=day-n;}
else {day=day+31; day=day-n;month=12;year--;}
}
else if(month==8){
if(day-n>0) {day=day-n;}
else {day=day+31;day=day-n;month--;}
}
else{
if(day-n>0) {day=day-n;}
else {day=day+31;day=day-n;month--;}
}
}与
if(n<0){
if(month==4||month==6||month==9||month==11){
if(Math.abs(n)+day>30) {day=day+Math.abs(n); day=day%30; month++;}
else {day=day+Math.abs(n);}
}
else if( month==2&&isLeapYear(year) ){
if(Math.abs(n)+day>29) {day=day+Math.abs(n);day=day%29;month++;}
else {day=day+Math.abs(n);}
}
else if( month==2&&!isLeapYear(year) ){
if(Math.abs(n)+day>28) {day=day+Math.abs(n);day=day%28;month++;}
else {day=day+Math.abs(n);}
}
else if(month==12){
if(Math.abs(n)+day>31) {day=day+Math.abs(n);day=day%31;month=1;year++;}
else {day=day+Math.abs(n);}
}
else{
if(Math.abs(n)+day>31) {day=day+Math.abs(n);day=day%31;month++;year++;}
else {day=day+Math.abs(n);}
}
}
System.out.println(n+" days ago is:" +year+"-"+month+"-"+day);
}最后说明一下当输入的日期不合法时系统的输出。在该题中需要用到数学函数Math.abs(),在写该题时要有一定的思路,找到各种情况(各种日期)在求第n天的相同规律,一开始我在草稿纸上一一罗列各种情况,每个月份分段考虑,这样不仅加大了工作量,还会有漏解的情况,这会使源代码变得冗长,最后,在一位同学的提示下发现每个月的求第n天都有相似的求法,掌握了一定的数学规律后,求解每个月的第n天就容易多了。例如在求4.6.9.11月的后n 天中有如下数学规律
if(month==4||month==6||month==9||month==11){
if(Math.abs(n)+day>30) {day=day+Math.abs(n); day=day%30; month++;}
else {day=day+Math.abs(n);}
}
其中30表示这些月份总共有30天,求其他月份的后n天的方法也如上规律。类似的,求4.6.9.11月的前n天也有一定的数学规律
if(month==4||month==6||month==9||month==11){
if(Math.abs(n)+day>30) {day=day+Math.abs(n); day=day%30; month++;}
else {day=day+Math.abs(n);}
}其他月份的前n天类似。
在题目集3中7-2题定义一个日期类,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31],该题与上一个题目集的倒数第二题的部分代码类试,结果都是需要再输入日期合法的情况下输出下一天,与上一题不同的是该题需要定义一个日期类,类就是使用对象进行程序设计,java类使用变量定义数据域,使用方法定义动作。在该题中在类的数据域前使用了private修饰符表面它只能在它自己的类中被访问,getyear()方法返回year值,getmonth()方法返回month值,getday方法返回day值,这些方法是读取数据的唯一途径,
public void setmonth(int month){
this.month=month;
}
public int getday(){
return day;
}
public void setday(int day){
this.day=day;
}而这些方法是改变这些数据域的唯一途径,如果要改变这些方法的实现,是不需要改变使用它们的客户程序,因此,这种类更易于维护。除此之外,对象是类的实例。可以使用new操作符创建对象,使用点操作符(.)通过对象的引用变量来访问该对象的成员。
在题目集3的最后一题中要求对输入的数学表达式就是求导,根据题目要求需要识别用户从命令行输入对的多项式,并且要提取出其中对的系数、指数以便于后续计算,正则表达式是解决这个问题的最好方式。用字符串存下一整行对的输入信息,然后从中删去所有的空格和制表符。运用正则表达式时,一定要记得#include<regex>。
最后,在练习了部分的题目后,可以帮我们充分掌握编程的逻辑、语意和语法,通过 实践性编程练习以及及时的反馈,可以很好的提高我们的编程能力。

浙公网安备 33010602011771号