BLOG-1
BLOG1
前言:对于前三次的题目集难度评价为第一次较为简单,巩固了一些基础知识,虽然题目量较后两次题目集更多但大致为对基础的运用,第二次的题目较为普通且题量较少,第三次题目集中第一题较容易,后面几题较难,花费了大量时间去完成。三次作业大概知识点为字符串的输入,类型的强制转换,循环的使用,一维数组的使用,判断条件的使用,根据类图篡改程序为面向程序设计。
首先对print,printf,以及println的使用
print:将信息显示在命令窗口中,输出光标定位在最后一个字符之后。
System.out.print("a"); System.out.print(a);
printf:将信息进行格式化显示在命令窗口中,输出光标定位在最后一个字符之后。System.out.printf("a=%d",a);
println:将信息显示在命令窗口中,并输出后自动换行。
System.out.println("a"); System.out.println(a);
对charAt方法的使用,进行String内的内容进行一个一个的检查
class Test {
public static void main(String[] args) {
String s ="abcd";
System.out.println(s.charAt(1));
}
}
对length()函数的使用
for(int i=0;i<str.length();i++) {
a[i]=str.charAt(i);
if(a[i]=='1')
n++;
}
相比与c语言,多了Boolean类型的输入,Boolean返回值得true或false。
Float和double 的区别:float是单精度类型,精度是8位有效数字。double是双精度类型,精度是17位有效数字。
substring()函数的运用:通过使用该函数截取字符串的数据,substring(a,b)中的参数a其值可以从索引值a开始, a为字符串的下标数,则表示其从字符串为下标a的时候字符开始截取,并且截取b-a个位,当substring为substring(a)时,表示从下标为a的位置截取到字符串结尾。
Equals()函数的使用:测试是否在两个范围的元素是否相等,使用时为以下格式:
str.substring(j,j+2).equals("20");
Getter/Setter方法的使用:java中封装的特征,利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。
类型的强制转换:float b=(float)(high/0.0254);
一维数组的使用:数组一旦创建,在Java中规定,长度不可变。也可以在数组内提前放入数据。数组在内存方面储存的时候,数组中的元素内存地址是连续的。数组元素的下标从0开始,最后一个元素的下标是length()-1。
取余数对整形数内各个位置的比对:number=num%100;
classroom=num%10000/100;
house=num%1000000/10000;
year=num/1000000;
设计与分析:
对奇偶校验位的判断,在有效数据之后加上1位可选的奇偶校验位,对题目分析即为前8位有效数字加上后一位数字一起判断奇偶校验位。采用length()函数取出string内的长度,再对string里面的内容采用for循环进行一个一个的比对,输出其结果。
if(str.length()<11||n==str.length())
System.out.println("null data");
else {
for(int i=0;i<str.length();i++) {
if(a[i]=='0') {
for(int j=i+1;j<=i+9;j++) {
if(a[j]=='1')
d++;
}
int k=d%2;
d=0;
if(a[i+10]=='1'&&k==1) {
System.out.println(b+":"+str.substring(i+1,i+9));
b++;
}
else {
if(a[i+10]=='1'&&k==0) {
System.out.println(b+":"+"parity check error");
b++;
}
if(a[i+10]=='0'&&k==1) {
System.out.println(b+":"+"validate error");
b++;
}
if(a[i+10]=='0'&&k==0) {
System.out.println(b+":"+"validate error");
b++;
}
}
i=i+10;
}
}
}

对一元二次方程有几个解进行判断。代码如下:
public double getDiscriminant() {
double x = 0;
x=this.b*this.b - 4 * this.a * this.c ;
return x;
}
对函数进行公式求解x1,x2.
采用getter,setter使外部可以调用类的内部
public double getRoot1() {
double x1;
x1 = (-this.b + Math.pow(this.b*this.b - 4 * this.a * this.c,0.5)) / 2 * this.a;//采取公式求出函数的解。
return x1;
}
public double getRoot2() {
double x2;
x2 = (-this.b - Math.pow(this.b*this.b - 4 * this.a * this.c,0.5)) / 2 * this.a;//采取公式求出函数的解。
return x2;
}

判断year是否为闰年:年份能被4和100整除或被400整除。
取得year-month-day的下n天日期与取得year-month-day的前n天日期:通过天数的累加和累减进行计算,n值够大时考虑年份的变化,累加时应考虑年份的闰年与平年,以及跨年时的变化和跨月时的变化。累减时与累加考虑的条件大致相同。
判断两个日期是否相等:
if(this.year == date.year&&this.month == date.month&&this.day == date.day)
return true;
return false;
比较当前日期与date的大小(先后):用判断大小进行比较。
if (this.year > date.year)
return true;
if (this.year == date.year) {
if (this.month > date.month)
return true;
if (this.month == date.month) {
if (this.day >= date.day)
return true;
}
}
return false;
求当前日期与date之间相差的天数:从第一个输入的数值一次一次累加,每累加一次判断所得值是否与 第二次的数值相等。
if(this.equalTwoDates(date)){//如果两天的日期相等
return 0;
}
else if(!this.compareDates(date)){//如果日期大小不对
b1=date;
b2=this;
}
if(!compareDates(date)) {
for(;;) {
if(isLeapYear(this.year)) {
a[2] = 29;
}
else {
a[2] = 28;
}
this.day=this.day+1;
days++;
if(this.day >a[month]) {
if(this.month==12) {
this.month = 1;
this.year = this.year + 1;
this.day = 1;
}
else {
this.month = this.month + 1;
this.day = 1;
}
}
if(equalTwoDates(date))
break;
}
}
return days;
}

此题所考察的是对第二题的修改,将其修改为多个类进行编译。但这题给出了相应的类图,我们要对其给出的类图进行编写代码。满足其相应要求。
此题计算当前日期与date之间相差天数时,不得采用累加方式计算,否则会运行超时。这时可设计一个范围之外的固定值,将输入的两个数据与其进行相减,所得出的两个数字再进行相减,取绝对值则为天数之差。
for(int i = 1820 ; i < day.month.year.value ; i++) {
if (((i%4==0&&i%100!=0)||i%400==0)){
sum1 = sum1 + 366;
}
else{
sum1 = sum1 +365;
}
}
for(int i = 1;i < day.month.value;i++) {
if (day.month.year.isLeapYear()){
a[1]=29;
}
else{
a[1]=28;
}
sum1 = sum1 + a[i-1];
}
sum1 = sum1 + day.getValue();
for(int j = 1820 ; j < date.day.month.year.value ; j++) {
if (((j%4==0&&j%100!=0)||j%400==0))
sum2 = sum2 + 366;
else
sum2 = sum2 +365;
}
for(int j = 1;j < date.day.month.value;j++) {
if (date.day.month.year.isLeapYear())
a[1] = 29;
else
a[1]=28;
sum2 = sum2 + a[j-1];
}
sum2 = sum2 + date.day.value;
days = Math.abs(sum2-sum1);
其余几种方法与前一题基本相似,只为类之间调用对象的区别。几个类之间进行应用其内部私有元素,采用getter和setter函数.
随便举一个例子: public DateUtil getPreviousNDays(int n){//取得year-month-day的前n天日期
int[] a = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
if(checkInputValidity()){
while(n>=0) {
if(day.month.year.isLeapYear()) {
a[1] = 29;
}
else {
a[1] = 28;
}
if(this.getDay().getValue()-n<0){
if(this.day.month.getValue()>1){
day.month.monthReduction();
n=n-this.getDay().getValue();
day.setValue(a[day.month.getValue()-1]);
}
else{
day.month.year.yearReduction();
day.month.setValue(12);;
n=n-day.getValue();
day.setValue(a[11]);;
}
}
else {
day.setValue(day.getValue()-n);
n=-1;
}
}
}
Returnnew DateUtil(day.month.year.getValue(),day.month.getValue(),day.getValue());
}
本题采用了聚合。例如,一个订单对象包含一些商品对象。聚合,意味着一个类的对象包含另一个类的对象。强调的是整体与部分之间的关系.

踩坑心得:关于浮点数类型,一开始都用double输入,导致其中几个测试点无法通过,而且输出后的答案相较其结果小数点多了几位输出,后将double改为float测试点则通过.
当输入double类型判断两数值是否相等时,应考虑误差,采用两值相减小于等于0.1
if(a==c||a==b||b==c){
if(a*a+b*b-c*c<0.1||a*a+c*c-b*b<0.1||c*c+b*b-a*a<0.1){
System.out.println("Isosceles right-angled triangle");}
Else{
System.out.println("Isosceles triangle");}
错误代码如下:

关于奇数的判断未考虑到负数形式的奇数
for(int j = 0; j < n; j++)
if(a[j]=='1'||a[j]=='0') {
System.out.print(a[j]);
}
修改后:

对奇偶校验位奇校验位的判断,加上8位有效数字及后面那位,刚开始误认为只需判断前8位数,后一位位判断奇偶校验位导致题目仅仅只拿到一半分数。修改代码后如以下:
for(int i=0;i<str.length();i++) {
if(a[i]=='0') {
for(int j=i+1;j<=i+9;j++) {
if(a[j]=='1')
d++;
}
int k=d%2;
d=0;
if(a[i+10]=='1'&&k==1) {
System.out.println(b+":"+str.substring(i+1,i+9));
b++;
}
else {
if(a[i+10]=='1'&&k==0) {
System.out.println(b+":"+"parity check error");
b++;
}
if(a[i+10]=='0'&&k==1) {
System.out.println(b+":"+"validate error");
b++;
}
if(a[i+10]=='0'&&k==0) {
System.out.println(b+":"+"validate error");
b++;
}
}
i=i+10;
}
对于前n天和后n天的计算,采用一天一天的累加,导致运行超时,后对天数的计算加入年份的累加后运行就不超时了。
开始时: for (int i = 1; i <= n; i++) {
day.dayIncrement();;
if(day.month.year.isLeapYear()) {
a[2] = 29;
}
else {
a[2] = 28;
}
if (day.getValue() > a[day.month.getValue()-1]) {
day.setValue(1);;
day.month.monthIncrement();;
if (day.month.getValue() > 12) {
day.month.setValue(1);
day.month.year.yearIncrement();;
}
}
}
修改后: while(n>years){
day.month.year.yearIncrement();
n=n-years;
if(day.month.year.isLeapYear())
years=366;
else
years=365;
}
for (int i = 1; i <= n; i++) {
day.dayIncrement();;
if(day.month.year.isLeapYear()) {
a[2] = 29;
}
else {
a[2] = 28;
}
if (day.getValue() > a[day.month.getValue()-1]) {
day.setValue(1);;
day.month.monthIncrement();;
if (day.month.getValue() > 12) {
day.month.setValue(1);
day.month.year.yearIncrement();;
}
}
}
字符串的输出超过了所给的长度,导致运行没有结果。
心得与总结:
当对字符串进行应用时,要充分考虑字符串的长度,运用for循环查找是应多多观察,不要超过其所在范围,否则则会导致其输出空白。
对数值计算时,如果数值较大,避免一个一个的累加,导致运行超时。
对封装性的目的,保护某些属性和方法不被外部所看见,在外部使用时采取getter函数进行类里面数值的调用。
对浮点数数类型的相等具有误差性,应使用数相减的绝对值小于0.0001.
改进建议:
1.尽可能的使用代码的封装性,在代码的运行过程中,尽可能用到单一变量原则。2.通过对Debug的调试找出代码中相应的不足处,对其进行修改使其能够更加完美的运行。
3.减小程序计算量:例如在进行计算年份时,求后n天时当n过大时可以先进行年份的递加,再进行天数的递加。
4.避免没有必要的读写依赖:当数据保存到内存时存在读写依赖,即数据必须在正确写入后才能再次读取。
5.对函数和类的命名采用其相关的英文翻译,不使用中文拼音,因为若无注解,时间久后自己也会忘掉其含义和用途。
6可使用聚合关系,这样可使代码的调试更加方便。
总结:
1.经过本阶段三次题目级的训练,我学会了判断条件的使用.通过debug的调试相比之前更加紧密。让我的代码字符串内部数据的输出及内部数据的比对.对类的构建以及类之间的相互运用。在聚合方面的应用还是较为薄弱,应进行深度学习并应用.代码之间的联系比较松散,通过调试发现,容易出现bug。
2.当输入数据运行时,未有运行结果,则应考虑代码中是否超出所给字符串的长度。
3.课程所学习的内容较为复杂,作业的难度跨越较大,建议循序渐进。 第一次实验的内容较为简单,但看后续实验的文件,相较于第一次更复杂。
4. 老师可以适当告诉些题目的测试点,这样可以避免因测试点问题浪费大量时间。
5.老师在线上上课可以主动带来更多的互动,让学员有更多的参与感,更愿意投入到课程当中。

浙公网安备 33010602011771号