前言:
今年才学的Java,准确来说是这个学期才学的,之前上学期学过一点点c语言,在编程这条路上开了个头。前三次的题目集对我来说难度是偏高的,很多题目我自己没做完全,是不敢放在pta平台上测试的,即使测试了几遍也不敢提交。我先学习了配置JDK,后面又将JRE配置到Eclipse这个集成开发软件中去。
前三章的知识点都是入门级的,至少前两章是。主要知识点有:Java语言规范,创建、编译和执行Java程序,学习了正确的注释、缩进和空白,块的风格,选择、循环语句的使用,数组的使用,对象与类的概念等等。题量不多,难度不大,但对于萌新来说复杂了点,是对我很头疼的事,我必须先去找网课研读,再自己写些代码调试再来做这些题目,而且目前很多题目没拿到满分,这些题目后面我又重做重新测试了,但无法提交到pta上了。
设计与分析:
这是7-1:
import java.util.Scanner;
public class Main { public static void main(String[] args) { Scanner input = new Scanner (System.in); int i = input.nextInt(); double a=7.70; if(i>5) System.out.println("实际利率="+a*1.1+"%"); else if(i==5||i==4) System.out.println("实际利率="+"7.70"+"%"); else if(i==3||i==2) System.out.println("实际利率="+a*0.7+"%"); else if(i==1) System.out.println("实际利率="+a*0.5+"%"); else System.out.println("error"); } }
这第一题思路很简单,就一个main函数,输入和输出,还有一个if判断语句,这语句是在c语言中学过的,语法都差不多的。重点是学会了从控制台读取数据,得知Java用System.out来标准输出设备,用System.in来标准输入设备。println方法在控制台显示基本数据类型值或字符串。使用Scanner类创建一个对象,读取来自System.in的输入。
Scanner s = new Scanner (System.in);
这句是创建了一个Scanner类型的对象,并且把引用赋给input.Scanner类在java.util包里。刚开始的时候我习惯写的是:
java.util.Scanner s = new java.util.Scanner (System.in);
7-2和7-1相比没有新内容,这里就不贴上来分析了。
这是7-3:
public class Main { public static void main(String[] args) { java.util.Scanner s = new java.util.Scanner (System.in); int i = s.nextInt();int a,b; if(i<1 ||i>=10) {
System.out.println("INPUT ERROR.");
} else { for(a=1;a<=i;a++) { for(b=1;b<=a;b++) { System.out.print(a+"X"+b+"="+a*b); if(b!=a) System.out.print("\t"); } System.out.println(); } } } }
这题是打印一个九九乘法表,之前在学习C语言的时候制作过各式各样的九九乘法表,所以知道要用一个嵌套的for循环,这里了解到Java里的条件与、条件或、条件非跟C语言中是一样的还有赋值操作符等等操作符都是一样的。
Java中命名变量和方法采用驼峰命名法,类名每个单词首字母大写,常量所有字母大写。
print是打印字符串后不换行,printf是打印字符串后换行。
public class Main{}
这行代码是定义类,类名为Main,public是修饰符,声明类是公有的,class是关键词,{}里面是类体。
public static void main(String[] args)
这行代码是定义静态main方法,类中必须包含静态main方法,args是参数名,可自由定义,args参数是程序运行时,传递字符串,其他的基本不能改动,String[] args是声明String数组。
这是7-9:
public static boolean isPrime(long x) { long m= (int) Math.sqrt(x); boolean flag=true; if (x==1) return false; if (x==2) return true; if (x%2==0) return false; for(long i=3;i<=m;i+=2){ if(x%i==0)
{ flag=false; break; } } return flag; }
定义了一个方法,通过定义和调用函数,组织简化代码,避免重复,避免使主函数繁琐。
public static是修饰符,boolean是返回值类型,若方法无返回值,则关键字为void。这两种方法分别称为空方法和有返回值的方法。isPrime(long x)这个是形式参数,调用方法时会给参数传递一个值,为实际参数。在方法头中必须每个参数都声明数据类型。定义了一个布尔类型的flag方便返回主方法。
if (isPrime(i))
{ sum+=i; }
在主方法中这样调用isPrime方法,省略了==true。
这是7-11:
for (int j = 1; j <= t; j++) { double x = a + j * (b - a) / t ; sum = sum + 2*x*x+x; }
这道求定积分的题目我前前后后试了多种算式,答案最接近的一次也差了3位小数。百思不得其解。
这是7-12:
System.out.print("1/"+i+",");
Java和c语言的输出格式不一样,这里是要直接的输出的加上“”,赋值了的不用加,中间用+连接。
这是第二次作业7-1:
double m,n; m = i / 0.45359237; n = l / 0.0254; float a,b; a = (float) m; b = (float) n;
这里使用了double强转float。
当字节范围小的数据类型转换为大数据的时候,可实现直接转换;但当大数据转换为小数据时,必须加上括号写上转换的类型,否则系统报错说精度损失。
这是7-2:
int a[] = {0,0,0,0,0,0,0,0,0,0};
学会了这样定义数组。这个数组共有10个int类型元素,分别为a[0]—a[9]。
后面会这样定义数组了:
int[] myList = new int[10];
这样声明了一个数组变量myList,创建一个数组,将引用赋值给myList,后面可以直接赋值。
创建数组后元素会被赋予默认值,数值类型的数据会被赋值为0,char类型的默认值为\u0000,布尔类型的默认值为false。
这是7-3:
switch(a){ case 1: if(d<=90) s=c*10000*0.01; else if(d>90&&d<=144) s=c*10000*0.015; else if(d>144) s=c*10000*0.03; }
switch语句用于处理多条件语句,防止if嵌套次数过多。
每次case后面都要用break;否则会一直执行不退出。
default是上面case都不符合时执行的语句。
这是7-6:
while(Math.abs(nextGuess-lastGuess)>=0.00001) { lastGuess = nextGuess; nextGuess = (lastGuess+n/lastGuess)/2; }
用了一个while循环语句,当符合条件的时候执行。
这里Math.abs用来求绝对值。数学函数有很多,sin、cos、tan分别返回弧度制的三角函数正弦、余弦、正切值,toRadians是将角度制转弧度制,toDegrees是将弧度制转角度制,PI还有E分别代表圆周率和自然对数的底。min和max返回两个数的最小值和最大值。random是生成大于等于0.0小于1.0的double类型的随机数,sqrt是开方,pow是次方。
由于精度问题,两数如果不能相等,就令它们的绝对值小于某数。
这是7-7:
for(i = 0;i < a.length();i++) { if(a.charAt(i) == '0' || a.charAt(i) == '1')
......
}
a.length()是数组的元素的最大值。
charAt是返回指定下标位置的字符。
这是第三次7-3:
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner s = new Scanner(System.in); int year = s.nextInt(); int month = s.nextInt(); int day = s.nextInt(); if(checkInputValidity(year,month,day)==false) { System.out.println("Date Format is Wrong");return; } else getNextDate(year,month,day); } public static boolean isLeapYear(int year) { if ((year%4==0&&year%100!=0)||(year%400==0)){ return true; } return false; } public static boolean checkInputValidity(int year,int month,int day) { int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12}; int[] monthOfThirty = new int[]{4,6,9,11}; if(year>=1900&&year<=2000) { if (month>=1&&month<=12) { if (day<=0){ return false; } if(month == 2) { if(isLeapYear(year)) { if(day<=29) { return true; } else { return false; } } else { if(day<=28) { return true; } else { return false; } } } for(int i=0;i<7;++i){ if (month==monthOfThirtyOne[i]){ // 1-31 if (day<=31){ return true; }else{ return false; } } } for(int i=0;i<4;++i) { if (month==monthOfThirty[i]){ // 1-30 if (day<=30){ return true; }else{ return false; } } } } } return false; } public static void getNextDate(int year,int month,int day) { int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12}; int[] monthOfThirty = new int[]{4,6,9,11}; int yearNext; int monthNext; int dayNext=day+1; int dayCarry=0; int monthCarry=0; if (month==2){ if (isLeapYear(year)){ if (day==29){ dayNext = 1; dayCarry = 1; } } else{ if (day==28){ dayNext = 1; dayCarry = 1; } } } else{ boolean isThirtyOne= false; for(int i=0;i<7;++i){ if (month==monthOfThirtyOne[i]){ isThirtyOne = true; if (day==31){ dayNext = 1; dayCarry = 1; } break; } } if (!isThirtyOne){ if (day==30){ dayNext = 1; dayCarry = 1; } } } if (month+dayCarry>12){ monthNext = 1; monthCarry = 1; }else{ monthNext = month+dayCarry; } yearNext = year+monthCarry; System.out.println("Next day is:"+yearNext +"-"+ monthNext +"-"+ dayNext); } }
说真的很多代码写的繁琐无用,都可以简化,而且格式非常不美观。
还有一点老师要求的是Date类结构,我没按结构写,虽然通过了测试,但写的不好。
这是7-4:
class DateUtil{ public int[] monthOfThirtyOne = new int[]{1,3,5,7,8,10,12}; public int[] monthOfThirty = new int[]{4,6,9,11}; public int sum[] = new int[20]; public int year,month,day; public DateUtil(DateUtil d){ this.day = d.getDay(); this.month = d.getMonth(); this.year = d.getYear(); sum[1] = 31; sum[2] = 28; sum[3] = 31; sum[4] = 30; sum[5] = 31; sum[6] = 30;sum[7] = 31;
sum[8] = 31; sum[9] = 30; sum[10] = 31; sum[11] = 30; sum[12] = 31; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public DateUtil(int a, int b, int c){ year = a; month = b; day = c; } public boolean checkInputValidity(){ if(year>=1820&&year<=2020) { if (month>=1&&month<=12) { if (day<=0){ return false; } if(month == 2) { if(isLeapYear(year)) { if(day<=29) { return true; } else { return false; } } else { if(day<=28) { return true; } else { return false; } } } for(int i=0;i<7;++i){ if (month==monthOfThirtyOne[i]){ // 1-31 if (day<=31){ return true; }else{ return false; } } } for(int i=0;i<4;++i) { if (month==monthOfThirty[i]){ // 1-30 if (day<=30){ return true; }else{ return false; } } } } } return false; } public boolean isLeapYear(int year){ if(year % 400 == 0||year % 4 == 0 && year % 100 != 0) return true; else return false; } public DateUtil getNextNDays(int n){ for (int i = 1; i <=n; i++) { day++; if(this.isLeapYear(year)==true && month == 2){ if(day > 29){ month++; day = 1; } } else if(day > sum[month]){ day = 1; month++; if(month > 12){ month = 1; year++; } } } if(n > 365){ if(this.isLeapYear(year+1) && month > 2){ year++; n = n - 366; } else if(this.isLeapYear(year) && month <= 2){ if(month == 2 && day == 29){ day = 1; month = 3; } year++; n = n - 366; } else{ year++; n = n - 365; } } return this; }
截了中间一小段,求下n天和上n天的代码没通过测试,我觉得是其中测试点是int类型最大值放入for循环导致运行超时,我看看能不能去掉for函数令写一遍。
采坑心得:
if(a*a+b*b-c*c < 0.1) System.out.println("Isosceles right-angled triangle");
这里写相等一直没过,是精度问题,一定要写小于一个比1小的数。
改进建议:
多刷题多听课,认真做笔记,及时预习复习。
总结:
只能说会了一点皮毛,会用Java写一点程序了,后面要慢慢精进。
数组、方法、对象和类、面向对象等等,什么都得一点点学,“十年磨一剑”,坚持下来。
建议:老师上课对基础知识做个总结,对语法格式做个统一要求。