面向对象程序设计第一次博客作业
一、前言
习题集七第一次作业,并未涉及太多的有关面向对象程序设计的知识点,只需要熟悉Java的输入输出、判断以及String类的相关方法就能完成,无需专门创建类。相信老师设计此题目的主要目的恐怕是考核我们开学后的前两周自主学习Java基础语法的相关情况。总结习题集七的第一次作业所涉及的知识点为Java语言的基础语法,题量适中,难度偏低。
习题集七第二次作业,难度较上次作业有提升但也主要体现在此次作业的第二题7-2,另外两题则与第一次作业相同,难度上次作业有较大提升主要体现在输入情况的多样性,考察学生的逻辑思维能力。总结,习题集的第二次作业难度较上次作业有提升,涉及的知识点有1、运用将字符串转为字符数组的toCharArray()函数来获取数据流的长度 2、理解奇偶校验中奇校验的含义 3、substring()截取对应的字符串;难度中等;题量小。
习题集第三次作业题量小但难度大,主要涉及继承、多态性使用方法、ArrayList泛型的应用方法和正则表达式的运用,并考察学生对类的理解、对字符串相关函数的熟悉程度、理解题目逻辑的思维判断能力和完善算法的能力。这次作业的三题是环环相扣的,第二题是对第一题的拓展,第三题是对第一题的拓展,这就十分考验学生对代码结构的理解程度,只有在最初阶段就想到三题间并建立合适的类才能让自己越写越轻松,代码的结构也更加合理。
经过这三次的题目集训练,感觉能力得到了很大的提升。这三次训练让我巩固了自学的Java基础语法,同时在这次习题集体现了我对类的陌生但也让我对类的理解提升了一个层次。
二、设计与分析
(1)第一次作业的设计分析总结:
第一次作业的前七题都没有什么难度,无需介绍,我们先看到**7-9 二进制数值提取**,这题是输入一串字符串,让我们提取出其中的二进制数0和1,但它有特定的输入格式(一个由0、1构成的序列,以-1为结束符,非0、1字符视为正常输入,但忽略不计),如若没有结束符则判定为非法输入。那么,我们首先就需要判断输入的字符串是否有结束符
1 l = in.nextLine(); 2 char[] a = l.toCharArray(); 3 for(int i=0;i<l.length();i++){ 4 if(a[i]=='-') 5 b=1; 6 }
这里先将**字符串转换为字符数组之后对数组进行遍历**,判断该字符串是否具有结束符,**有则对字符数组进行遍历输出结束符前的二进制数**,没有则输出Wrong Format。 **7-7 判断三角形类型**,这题只需要先判断输入的三个数据是否在规定范围内,再判断能否个构成三角形,能则继续判断三角形种类,不能则输出Not a triangle。
(2)第二次作业的设计分析总结:
7-2 串口字符解析
圈复杂度
题目要求对输入的数据流进行过滤输出,首先就需要判断数据流的长度是否满足11位,再进行调用judge方法进行判断,判断是否存在有效数据(有效数据前一位为0)
1 public static boolean judge(char[] a) { 2 for(int i=0;i<a.length-1;i++) 3 { 4 if(a[i]=='0') 5 return false; 6 } 7 return true; 8 }
若judge方法返回 true 则说明存在的有效数据,进行下一步判断
1 int sum=0; 2 for(int i=0;i<arr.length;) { 3 if(s.charAt(i)=='0'&&arr.length-1-i>=10) 4 { 5 if(jiou(arr,i+1,i+10)==1&&end(arr,i+10)==1) 6 { 7 sum++; 8 System.out.println(sum+":"+s.substring(i+1, i+9)); 9 } 10 else if(jiou(arr,i+1,i+10)==0&&end(arr,i+10)==1) 11 { 12 sum++; 13 System.out.println(sum+":parity check error"); 14 } 15 else if(jiou(arr,i+1,i+10)==1&&end(arr,i+10)==0) 16 { 17 sum++; 18 System.out.println(sum+":validate error"); 19 } 20 else if(jiou(arr,i+1,i+10)==0&&end(arr,i+10)==0) 21 { 22 sum++; 23 System.out.println(sum+":validate error"); 24 } 25 i+=11; 26 } 27 else 28 i++; 29 }
如上图设置计数器sum保存有效数据的个数,设置for循环,根据奇校验位数以及结束符是否正确分类输出。
第三次作业的设计分析总结:
7-1 点线形系列1-计算两点之间的距离 :
圈复杂度
首先我们分析题目,输入连个点的坐标,计算两点之间的距离,那么我们可以用到面向对象的知识,首先创建一个Point类,其中包括私有数据x,y,通过Point里的方法访问坐标数据
1 class point { 2 3 private double x; 4 private double y; 5 public point(double x, double y) { 6 super(); 7 this.x = x; 8 this.y = y; 9 } 10 11 public double getx(){ 12 return x; 13 } 14 15 public double gety(){ 16 return y; 17 } 18 19 }
设置一个正则表达式df="([+-]?\\d+(\\.\\d+)?,[+-]?\\d+(\\.\\d+)?\\s?)+";,对符合正则表达式的字符串再通过String类的split()方法将输入的字符串以",\s"进行分割,生成一个长度为4的字符串数组tokens,再通过 Double.parseDouble(tokens[i]);语句将字符串数组中的每一个转化为double型传入一个新创建的double型数组中。之后再将新得到的长度为4的double型数组中的数据传入新创建的两个Point类对象的构造函数中,再调用计算方法算出两点间的距离并输出
7-2 点线形系列2-线的计算
圈复杂度
我们可以在基于第一题的基础上再创建一个Line类,Line类里存有私有数据斜率k,截距b,长度length
1 class line { 2 3 private double k; 4 private double b; 5 private double length; 6 7 public line(point p1,point p2) { 8 super(); 9 10 if(p1.getx()==p2.getx()) 11 this.k=Double.POSITIVE_INFINITY; 12 else 13 this.k=(p2.gety()-p1.gety())/(p2.getx()-p1.getx()); 14 15 this.length=Math.sqrt( Math.pow( Math.abs(p1.getx()-p2.getx()) ,2) + Math.pow( Math.abs(p1.gety()-p2.gety()) ,2) ); 16 17 this.b = p2.getx()*p1.gety()-p1.getx()*p2.gety(); 18 } 19 20 public double getk(){ 21 return k; 22 } 23 24 public double getb(){ 25 return b; 26 } 27 28 public double getlength(){ 29 return length; 30 } 31 32 }
1 Scanner input = new Scanner(System.in); 2 String s = input.nextLine(); 3 String[] tokens = str.split("[,\\s:]"); 4 double[] a=new double[tokens.length]; 5 for(int i=0;i<tokens.length;i++) { 6 a[i]=Double.parseDouble(tokens[i]);
如上代码,先输入一个字符串,再根据String[] tokens = str.split("[,\\s:]");语句将字符串划分,再创建一个double型数组用来接收强制转化后的数据
1 class judge{ 2 private static String df= "[1-5]:([+-]?\\d+(\\.\\d+)?,[+-]?\\d+(\\.\\d+)?\\s?)+"; 3 private static String df_1="\\d:([+-]?\\d+\\.?\\d*,?)+"; 4 5 public static void jd(String str,double[] site) { 6 7 if(str.matches(df_1)) 8 System.out.println("Wrong Format"); 9 else if(str.matches(df)&&site[0]==1) { 10 select.compute(site, 1); 11 } 12 else if(str.matches(df)&&site[0]==2) { 13 select.compute(site, 2); 14 } 15 else if(str.matches(df)&&site[0]==3) { 16 select.compute(site, 3); 17 } 18 else if(str.matches(df)&&site[0]==4) { 19 select.compute(site, 4); 20 } 21 else if(str.matches(df)&&site[0]==5) { 22 select.compute(site, 5); 23 } 24 else 25 System.out.println("Wrong Format"); 26 27 } 28 }
如上代码,创建了一个judge类,包含两个正则表达式私有数据,然后jd方法就是对接收过来的字符串str和double型数组进行分类判断并传入不同的数据(此数据为double数组和首位数)进select类的compute方法
在select类的compute方法中
进入select方法后先判断数组的长度是否正确,否的话则输出wrong number of points,然后再判断点是否重合,重合则输出points coincide
上面的都满足则对序号开始分类操作:
若序号为1,就先判断;两点的x轴坐标是否相同,相同则代表斜率不存在输出“Slope does not exist”,x轴坐标不相同,则通过System.out.println((site[4]-site[2])/(site[3]-site[1]));语句直接输出斜率。
若序号为2,就直接计算并输出第一个点与另外两点连线的垂直距离System.out.println(Math.abs(((site[4]-site[6])*site[1]+(site[5]-site[3])*site[2]+site[3]*site[6]-site[4]*site[5])/(Math.sqrt(Math.pow(site[4]-site[6], 2) +Math.pow(site[3]-site[5], 2)))));
若序号为3,通过三点间形成的线段的斜率来判断三点是否在一条直线上。
若序号为4,还是通过两点形成的线段的斜率和后两点形成的斜率来判断是否平行,但斜率相同的情况包括斜率不存在,所以应该判断四点是否同时满足前两点的横坐标相同且后两点的横坐标相同,满足则斜率不存在,即平行。其他情况与序号为4的算法相同
若序号为5,要先判断是否平行,算法与序号为4的算法相同,这里不再赘述。若不满足平行那就来判断输出交叉点是否在两条线段之内,通过上图中的算法进行判断。
7-3 点线形系列3-三角形的计算
圈复杂度
基于第二题再添加一个traingle三角形类,属性包括面积,周长和重心坐标
1 class rectangle { 2 3 line l1,l2,l3; 4 5 private double area; 6 private double primeter; 7 private point zx; 8 9 10 public rectangle(line l1,line l2,line l3,point p1,point p2,point p3) { 11 12 this.l1=l1; 13 this.l2=l2; 14 this.l3=l3; 15 16 double p; 17 p=(this.l1.getlength()+this.l2.getlength()+this.l3.getlength())/2; 18 area=Math.sqrt(p*(p-this.l1.getlength())*(p-this.l2.getlength())*(p-this.l3.getlength())); 19 20 primeter=this.l1.getlength()+this.l2.getlength()+this.l3.getlength(); 21 22 point zx=new point((p1.getx()+p2.getx()+p3.getx())/3.0,(p1.gety()+p2.gety()+p3.gety())/3.0); 23 this.zx=zx; 24 } 25 26 public double getarea(){ 27 return area; 28 } 29 30 public double getprimeter(){ 31 return primeter; 32 } 33 34 public point getzx(){ 35 return zx; 36 } 37 }
输入和判定操作与第二题类似这边附上源代码,感兴趣的可以和第二题进行比较

1 import java.util.Scanner; 2 import java.text.DecimalFormat; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 Scanner input = new Scanner(System.in); 8 String s = input.nextLine(); 9 10 String[] tokens = s.split("[,\\s:]"); 11 12 double[] a=new double[tokens.length]; 13 14 for(int i=0;i<tokens.length;i++) { 15 a[i]=Double.parseDouble(tokens[i]); 16 } 17 18 match(s,a); 19 } 20 21 public static void match(String str,double[] site) { 22 String df= "[1-5]:([+-]?\\d+(\\.\\d+)?,[+-]?\\d+(\\.\\d+)?\\s?){3,5}"; 23 String df_1="\\d:([+-]?\\d+\\.?\\d*,?)+"; 24 25 if(str.matches(df_1)) 26 System.out.println("Wrong Format"); 27 else if(str.matches(df)) { 28 select(site); 29 } 30 else 31 System.out.println("Wrong Format"); 32 } 33 34 public static void select(double[] site) { 35 36 DecimalFormat df = new DecimalFormat("0.0#####"); 37 38 if(site[0]==1) 39 { 40 if(site.length==7) 41 { 42 point a=new point(site[1],site[2]); 43 point b=new point(site[3],site[4]); 44 point c=new point(site[5],site[6]); 45 46 line d=new line(a,b); 47 line e=new line(a,c); 48 line f=new line(b,c); 49 50 if((d.getlength()+e.getlength())>f.getlength()&&(d.getlength()+f.getlength())>e.getlength()&&(f.getlength()+e.getlength())>d.getlength()) { 51 if( d.getlength() == e.getlength() && e.getlength() == f.getlength() ){ 52 System.out.println("true true"); 53 }else if( d.getlength() == e.getlength() || e.getlength() == f.getlength() || d.getlength() == f.getlength() ){ 54 System.out.println("true false"); 55 }else 56 System.out.println("false false"); 57 } 58 else { 59 System.out.println("data error"); 60 } 61 62 } 63 else 64 System.out.println("wrong number of points"); 65 66 } 67 else if(site[0]==2) 68 { 69 if(site.length==7) 70 { 71 point a=new point(site[1],site[2]); 72 point b=new point(site[3],site[4]); 73 point c=new point(site[5],site[6]); 74 75 line d=new line(a,b); 76 line e=new line(a,c); 77 line f=new line(b,c); 78 79 rectangle rec=new rectangle(d,e,f,a,b,c); 80 81 if((d.getlength()+e.getlength())>f.getlength()&&(d.getlength()+f.getlength())>e.getlength()&&(f.getlength()+e.getlength())>d.getlength()) { 82 System.out.println(df.format(rec.getprimeter())+" "+rec.getarea()+" "+df.format(rec.getzx().getx())+","+df.format(rec.getzx().gety())); 83 } 84 else { 85 System.out.println("data error"); 86 } 87 } 88 else 89 System.out.println("wrong number of points"); 90 } 91 else if(site[0]==3) 92 { 93 point a=new point(site[1],site[2]); 94 point b=new point(site[3],site[4]); 95 point c=new point(site[5],site[6]); 96 97 line d=new line(a,b); 98 line e=new line(a,c); 99 line f=new line(b,c); 100 101 double A,B,C; 102 A=coss(d,e,f); 103 B=coss(e,d,f); 104 C=coss(f,e,d); 105 106 107 if(site.length==7) { 108 if((d.getlength()+e.getlength())>f.getlength()&&(d.getlength()+f.getlength())>e.getlength()&&(f.getlength()+e.getlength())>d.getlength()) { 109 boolean flag1=false,flag2=false,flag3=false; 110 if(A>0||B>0||C>0) 111 { 112 if(A>0||B>0||C>0) 113 { 114 if(A<0||B<0||C<0) 115 flag1=true; 116 else if(A==0||B==0||C==0) 117 flag2=true; 118 else 119 flag3=true; 120 } 121 } 122 System.out.println(flag1+" "+flag2+" "+flag3); 123 } 124 else { 125 System.out.println("data error"); 126 } 127 128 } 129 else 130 System.out.println("wrong number of points"); 131 } 132 else if(site[0]==4) { 133 if(site.length==9) 134 { 135 point a=new point(site[1],site[2]); 136 point b=new point(site[3],site[4]); 137 point c=new point(site[5],site[6]); 138 139 line d=new line(a,b); 140 line e=new line(a,c); 141 line f=new line(b,c); 142 143 if((d.getlength()+e.getlength())>f.getlength()&&(d.getlength()+f.getlength())>e.getlength()&&(f.getlength()+e.getlength())>d.getlength()) { 144 System.out.println("1"); 145 } 146 else { 147 System.out.println("data error"); 148 } 149 150 } 151 else 152 System.out.println("wrong number of points"); 153 } 154 155 else { 156 if(site.length==7) 157 { 158 point a=new point(site[1],site[2]); 159 point b=new point(site[3],site[4]); 160 point c=new point(site[5],site[6]); 161 162 line d=new line(a,b); 163 line e=new line(a,c); 164 line f=new line(b,c); 165 166 if((d.getlength()+e.getlength())>f.getlength()&&(d.getlength()+f.getlength())>e.getlength()&&(f.getlength()+e.getlength())>d.getlength()) { 167 System.out.println("on the triangle"); 168 } 169 else { 170 System.out.println("data error"); 171 } 172 173 } 174 else 175 System.out.println("wrong number of points"); 176 } 177 178 179 } 180 181 public static double coss(line a,line b,line c) 182 { 183 double cos =(b.getlength()*b.getlength()+c.getlength()*c.getlength()-a.getlength()*a.getlength())/(2*b.getlength()*c.getlength()); 184 185 return cos; 186 } 187 188 189 } 190 191 class point { 192 193 private double x; 194 private double y; 195 public point(double x, double y) { 196 super(); 197 this.x = x; 198 this.y = y; 199 } 200 201 public double getx(){ 202 return x; 203 } 204 205 public double gety(){ 206 return y; 207 } 208 209 } 210 211 class line { 212 213 private double k; 214 private double b; 215 private double length; 216 217 public line(point p1,point p2) { 218 super(); 219 220 if(p1.getx()==p2.getx()) 221 this.k=Double.POSITIVE_INFINITY; 222 else 223 this.k=(p2.gety()-p1.gety())/(p2.getx()-p1.getx()); 224 225 this.length=Math.sqrt( Math.pow( Math.abs(p1.getx()-p2.getx()) ,2) + Math.pow( Math.abs(p1.gety()-p2.gety()) ,2) ); 226 227 this.b = p2.getx()*p1.gety()-p1.getx()*p2.gety(); 228 } 229 230 public double getk(){ 231 return k; 232 } 233 234 public double getb(){ 235 return b; 236 } 237 238 public double getlength(){ 239 return length; 240 } 241 242 } 243 244 class rectangle { 245 246 line l1,l2,l3; 247 248 private double area; 249 private double primeter; 250 private point zx; 251 252 253 public rectangle(line l1,line l2,line l3,point p1,point p2,point p3) { 254 255 this.l1=l1; 256 this.l2=l2; 257 this.l3=l3; 258 259 double p; 260 p=(this.l1.getlength()+this.l2.getlength()+this.l3.getlength())/2; 261 area=Math.sqrt(p*(p-this.l1.getlength())*(p-this.l2.getlength())*(p-this.l3.getlength())); 262 263 primeter=this.l1.getlength()+this.l2.getlength()+this.l3.getlength(); 264 265 point zx=new point((p1.getx()+p2.getx()+p3.getx())/3.0,(p1.gety()+p2.gety()+p3.gety())/3.0); 266 this.zx=zx; 267 } 268 269 public double getarea(){ 270 return area; 271 } 272 273 public double getprimeter(){ 274 return primeter; 275 } 276 277 public point getzx(){ 278 return zx; 279 } 280 }
我们直接进入select方法, 进入select方法后先判断数组的长度是否正确,否的话则输出wrong number of points
若序号为1,然后先创建三个Point类对象,再创建三个Line对象,并将分别三个Point对象传入三个Line对象里
point a=new point(site[1],site[2]); point b=new point(site[3],site[4]); point c=new point(site[5],site[6]); line d=new line(a,b); line e=new line(a,c); line f=new line(b,c);
通过Line类里的getlength()方法获取出三个Line对象的长度,根据三角形任意两边之和大于第三边的特性判断三边是否能够形成三角形,若判断不是三角形,则输出error data,是三角形则继续判断是否为等边三角形,再判断是否为等腰三角形。
若序号为2,同上先构建三个Point类,再创建三个Line类,再判断数组的长度是否正确,否的话则输出wrong number of points。长度正确再判断输入的三点是否构成三角形,若判断不是三角形,则输出error data,若构成三角形则直接调用Line类里的方法直接访问area,primeter和zc(重心坐标)
若序号为3,上先构建三个Point类,再创建三个Line类,再判断数组的长度是否正确,否的话则输出wrong number of points。长度正确再判断输入的三点是否构成三角形,若判断不是三角形,则输出error data,若构成三角形则select类里的coss方法获取每个角的cos值,来判断三角形的每个角是锐角、直角还是钝角。
说来惭愧,序号为4和5的我还在研究算法中,敬请期待。
三、采坑心得
第一次作业:
(1)第八题中最初的设计是设计一个数组长度极大的字符数组来接收用户输入的数据,再通过.length来获取输入数据的长度,这就不可避免地导致数组申请的内存空间被浪费,在了解到String类里的toCharArray()方法后就极好地解决了这个问题,通过先定义一个字符串变量来接收用户数据,在运用toCharArray()方法将字符串中的数据传递到一个新的字符数组中,高效的利用了内存空间。
(2)第九题中,需要我们判断三角形的种类,但其中需要判断的选项是有重合的,比如等腰直角三角形与等腰三角形和直角三角形,所以将对等腰直角三角形的判断放在普通的判断链中是不太合适的,我们最先判断三角形是否为等腰直角三角形,是则在做完输出语句后使用return语句直接结束程序,不再进行剩下的判断语句。
第二次作业:
(1)第二题串口字符分析,在打算输出过滤好的有效数据时,我原本设想是通过转化后的字符数组通过循环语句进行输出,但在了解到substring()方法后深切地感受到了它的便利性,直接省去了循环语句直接返回对应位置的字符串,大大地降低代码的重复和复杂度。
第三次作业:
(1)第二题一开始在使用str.split();切割字符串时没有在切割标志两边打中括号String[] tokens = str.split(",\\s:");
这就导致无法对字符串进行切割,转化后的字符串数组也为null
但在加上中括号之后则正常
这实在是不应该犯的低级错误,当时还调试了我好久都没高目标,哈哈。
四、改进建议
(1)需要养成及时写注释的习惯,在这次写博客的过程中就深刻体会到了这一点,因为前两次作业都过了有一段时间,这就导致我完全不记得流程,这就浪费了我大量时间来回顾题目复习代码,实在是费时费力。并且希望以后在审完题后花一段时间来构思代码,合理分配职责,让代码的复杂度下降,并提高代码整体的美观性。
(2)依据题目要求设计类,设计类的固有属性和方法,分配好各类间的职责,尽量做到职责单一化,并且规划好各类的关系。把需要重复出现的语句设计成一个方法,比如说对三点能否构成三角形的判断,我们可以将其设计在一个类的方法里,需要用时只需调用即可,降低代码的耦合度。
(3)对于方法或类的取名规则需要在学习一下,优化代码。
五、总结
这三次题目集最大的收获是深刻地理解了继承及抽象类的应用,让我深深地体会到了类的便利性,这是面向过程所不能带来的。这次的经历也让我知道了自己在算法方面也存在不足,无法设计出优良的代码结构。最后,在面对程序出现的各种错误时去面对出现的各种错误,遇到问题冷静处理分析,多方面寻找原因去解决,从而慢慢提高自己的代码能力,这也是一个合格的程序员所必须具备的能力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)