20201728-第一次博客作业
学习编程如此长时间,从上学期的C语言到现在的Java。也算是写了不少的代码,单从这学期的程序设计来看,发现自己的编程能力几乎属于未入门。
对于这段时间在pta上写过的作业,发现了我学习Java的一些问题,同时也找到了其中的部分方法。首先是每次布置的题量,并不是很多,正常情况下是可以在一定时间范围内完成的。但是对于其难度来说,一开始还是比较简单的,但是从第二次开始难度就突然加大,做起来相当吃力,第三次的作业基本上就可以说是不会了,只能从网上或者书上先学习然后才能开始自己逐步摸索。相较于C语言,所用到的知识点几乎没有听过,必须提前看书网上找学习资料才能学习,课堂上讲的东西完全不够用。
第一次的作业的第一题:计算两个数的和。内容很好写,非常简单,但是刚开始学习Java,编译器都是找别人装的,语法格式什么的完全没有概念,还好教官刚好查寝,对于学习Java一年多的学长来说毫无难度,给我讲了大概的操作方法后,成功的完成了第一个Java程序。
从这开始就正式的开启了我学习Java的道路,第二题,第三题,第四题……简直不要太顺利,虽然有一个题有两分没有拿到,最主要的原因是不知道错在哪,难以发现错误并且改正。甚至第一次作业的第七题:“先从键盘输入一个整数n,n代表需要排序的整数数量,然后再从键盘输入n个整数,对这些数从小到大排序并输出。”就这?首先来一个
Scanner Scanner = new Scanner(System.in);
int n=Scanner.nextInt();
int a[]=new int[n];
定义一个变量和数组,然后输入这个变量,再来一个for循环输入数组,再来一个排序的经典方法:冒泡排序。
for(int i=0;i<n;i++) {
a[i]=Scanner.nextInt();
}
for(int i=0;i<n-1;i++){
for(int j=0;j<n-1-i;j++) {
if(a[j]>a[j+1]) {
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
最后一个for循环“System.out.print(a[i]+" ");”输出数组,收工。看来Java也是很轻松的嘛,何来掉头发一说?好了,下一题。“输入三角形三条边,判断该三角形为什么类型的三角形。”这是什么?这玩意也能用Java写出来?这作业超前了吧?完全没思路啊!冷静一下,看看学习视频。整理好思路,这个题总结来说也就是比较两边和或差与第三边之间的关系。分析下来也并不是很难。先定义三个变量代表三边,然后用选择结构分别表示三边之间的关系。说白了也就是对if的使用。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner Scanner = new Scanner(System.in);
double a=Scanner.nextDouble();
double b=Scanner.nextDouble();
double c=Scanner.nextDouble();
if(a>=1&&a<=200&&b>=1&&b<=200&&c>=1&&c<=200) {
if(a+b<=c||a+c<=b||b+c<=a) {
System.out.print("Not a triangle");
}
else if(a==b&&a==c) {
System.out.print("Equilateral triangle");
}
else if((a==b||a==c||b==c)&&(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)) {
System.out.print("Isosceles right-angled triangle");
}
else if(a==b||a==c||b==c) {
System.out.print("Isosceles triangle");
}
else if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a) {
System.out.print("Right-angled triangle");
}
else
{
System.out.print("General triangle");
}
}
else {
System.out.print("Wrong Format");
}
}
}
挺别致的作业,不错,还是被我想出来了吧!哼哼,提交!!! ???
这是什么?有bug我再康康。思索良久看不出来哪有问题,试着改一改再提交,错的更多了,这也没个提示,不知道哪有问题,真是让人头大。日常看代码改代码,最终也没有找到错哪了,难道这题目就有bug?不对啊,别人都能全对,肯定是我的代码有问题。好了,下次再看,到交作业那天也没有发现哪有问题,简直焦灼,不让人舒心。
一周过去了,新得作业来了,再让我看看这次作业又是什么东西。“请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。”这是啥?首先我知道没学过,所以先看看视频吧,半小时后,我懂了,开始写,提交。又是全错?哪有问题,好再来。新代码提交…只过了一个测试点?啊这,问问别人吧。一顿讲解后,懂了!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String a = input.nextLine();
int[] b = new int[4];
int[] c = new int[4];
int length = a.length();
if(length != 32) {
System.out.print("Wrong Format");
System.exit(0);
}
else
for(int i =0;i<4;i++){
c[i] = Integer.parseInt(a.substring(i * 8, (i + 1) * 8));
}
int n,k=0;
for(int i=0; i<4; i++) {
for(int j=0; j<8; j++) {
n=c[i]%10;
c[i]=c[i]/10;
if(n!=0&&n!=1) {
k=1;
break;
}
}
if(k==1)
break;
}
for(int i =0;i<4;i++){
c[i] = Integer.parseInt(a.substring(i * 8, (i + 1) * 8));
}
if(k==1) {
System.out.print("Wrong Format");
System.exit(0);
}
else
for(int i = 0; i<4; i++)
{
for(int j = 0; j<8; j++)
{
b[i]+=(int)Math.pow(2, j)*(c[i]%10);
c[i] /= 10;
}
if(i!=3)
System.out.print(b[i]+".");
else System.out.print(b[i]);
}
}
}
这还是有点难度的,我就说嘛,怎么会那么简单!这才是正常的。革命尚未成功,同志仍需努力。开始往后面做…“输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。”这东西似乎挺简单的,开始写。首先输入变量代表年月日,然后判断是否合法,再判断这一年是不是闰年,新建一个类吧,不然有点乱。然后计算下一天,不过如此,日期加一就行。提交过后,怎么错这么多?仔细分析一下,是把题想得太简单了,不同的月份,有的是28天,有的30天,有的31天,闰年的二月又不一样,然后每个月的最后一天就是不同的算法,而每年的最后一天还要特殊。所以重新整理思路,这挺复杂的啊,经历很长时间后终于做出来了。
import java.util.Scanner;
public class Main {
public static boolean isLeapYear(int year) {
if(year%400==0||(year%100!=0&&year%4==0))
return true;
else
return false;
}
public static boolean checkInputValidity(int year,int month,int day) {
if((year>2020||year<1820||month>12||month<1||day>31||day<1)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)||((isLeapYear(year)==true)&&month==2&&day>29)||((isLeapYear(year)==false)&&month==2&&day>28))
return false;
else
return true;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
if(checkInputValidity(year,month,day)==false)
System.out.print("Wrong Format");
else {
if(day==31&&month==12) {
month=1;
day=1;
year=year+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(day==31&&(month==1||month==3||month==5||month==7||month==8||month==10)) {
day=1;
month=month+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(day==30&&(month==4||month==6||month==9||month==11)) {
day=1;
month=month+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(isLeapYear(year)==true&&month==2&&day==29) {
month=month+1;
day=1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(isLeapYear(year)==false&&month==2&&day==28) {
month=month+1;
day=1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else {
day=day+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
}
}
}
这个确实不容易啊!同时我明白了,Java要的不只是一腔孤勇,更重要的是细心,仔细才能写出好代码。从这开始对Java的心态又发生了一些微妙的变化。带着新的态度看向下一题:“输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。”首先思考这个用什么方法写,经过分析后得到思路,和上一个题其实一样,只是把下一天换成了,下n天,n由控制台输入,同时多了前n天。也就是将上一题的代码升级。仔细推敲,拿出最优的方法写出来新代码:
import java.util.Scanner;
public class Main {
public static boolean isLeapYear(int year) {
if(year%400==0||(year%100!=0&&year%4==0))
return true;
else
return false;
}
public static boolean checkInputValidity(int year,int month,int day) {
if((year>2020||year<1820||month>12||month<1||day>31||day<1)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)||((isLeapYear(year)==true)&&month==2&&day>29)||((isLeapYear(year)==false)&&month==2&&day>28))
return false;
else
return true;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
int n = in.nextInt();
if(checkInputValidity(year,month,day)==false) {
System.out.print("Wrong Format");
System.exit(0);
}
else {
if(n>0) {
if(month==1&&day<n) {
year--;
month=12;
day=31+day-n;
}
else if((month==2||month==4||month==6||month==8||month==9||month==11)&&day<n) {
month--;
day=31+day-n;
}
else if((month==5||month==7||month==10||month==11)&&day<n) {
month--;
day=30+day-n;
}
else if((month==3&&day<n&&isLeapYear(year)==true)) {
month--;
day=29+day-n;
}
else if((month==3&&day<n&&isLeapYear(year)==false)){
month--;
day=28+day-n;
}
else
day=day-n;
}
else if(n<0) {
if(month==12&&day-n>31) {
year++;
month=1;
day=day-n-31;
}
else if((month==1||month==3||month==5||month==7||month==8||month==10)&&day-n>31) {
month++;
day=day-n-31;
}
else if((month==4||month==6||month==9||month==11)&&day-n>30) {
month++;
day=day-n-30;
}
else if((month==2&&day-n>29&&isLeapYear(year)==true)){
month++;
day=day-n-29;
}
else if((month==2&&day-n>28&&isLeapYear(year)==false)){
month++;
day=day-n-28;
}
}
else {
day=day-n;
}
}
System.out.print(n+" days ago is:"+year+"-"+month+"-"+day);
}
}
这才是写代码最舒服的感觉,也是最应该出现的东西。这次的作业主要考研细心,题并不是很难,重点要考虑难以被察觉的东西,把所有可能出现的东西全部想到。这样才能写出来一个优质的,最简单的,最让人容易理解的代码。
带着这种想法开始了带三周的作业,这次作业的前两题方法很简单,甚至第二题和上次的作业基本一样,唯一多出来的就是“私有属性”这个概念。经过查阅资料发现经过private定义的变量不能直接调用,需要用到getter及setter的方法。经过对之前代码的升级得到新代码:
import java.util.Scanner;
public class Main {
public static boolean isLeapYear(int year) {
if(year%400==0||(year%100!=0&&year%4==0))
return true;
else
return false;
}
public static boolean checkInputValidity(int year,int month,int day) {
if((year>2020||year<1820||month>12||month<1||day>31||day<1)||(month==4&&day>30)||(month==6&&day>30)||(month==9&&day>30)||(month==11&&day>30)||((isLeapYear(year)==true)&&month==2&&day>29)||((isLeapYear(year)==false)&&month==2&&day>28))
return false;
else
return true;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner in = new Scanner(System.in);
int year = in.nextInt();
int month = in.nextInt();
int day = in.nextInt();
if(checkInputValidity(year,month,day)==false)
System.out.print("Wrong Format");
else {
if(day==31&&month==12) {
month=1;
day=1;
year=year+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(day==31&&(month==1||month==3||month==5||month==7||month==8||month==10)) {
day=1;
month=month+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(day==30&&(month==4||month==6||month==9||month==11)) {
day=1;
month=month+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(isLeapYear(year)==true&&month==2&&day==29) {
month=month+1;
day=1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else if(isLeapYear(year)==false&&month==2&&day==28) {
month=month+1;
day=1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
else {
day=day+1;
System.out.print("Next date is:"+year +"-" +month +"-"+day);
}
}
}
}
可以正常的输出下一天,难度相对于之前来说,提升了不止一个档次。暗暗深吸一口气,然后开始第三题:简单来说就是对一个式子进行求导。这个东西我知道做题的思路,首先要把式子中的每一部分提取出来,然后另外用一个类对其计算然后重新结合在一起并且输出。但是对于这个多项式怎么截取呢,这必然要用到正则表达式。但是多项式从什么地方截取合适呢,如果看加减号,幂上面也有减号,肯定不行,那就用再用选择判断^的存在,来决定要不要提取,然后再写计算部分。但是从开始提取就遇到问题,总是报错,正则表达式部分写了很久始终有问题,最后还没写完就截止了。
加上随堂测试和实验的作业,对Java的课程理解更加深刻。可以做到一次编译,到处运行。因为Java为解释型语言,编译器将Class文件编译成与平台无关的字节码,然后在虚拟机上解释执行,所以有很好的移植性。安装编译器的时候就发现了Java提供了丰富的内置的类库。这些类库简化了开发人员的程序设计工作,缩短了项目周期。Java语言具有良好的安全性。同时又严谨整洁,Java语言去掉了C++中难以理解的,容易混淆的特性,例如头文件、指针、结构、单元、运算符重载、虚拟基础类、多重继承等。
这三次作业让我明白了学习Java编程不只是一句空话,更多的是多动手练习,勤使用,才能更加深刻的了解Java编程。