OO课程第一阶段(前三次作业)总结Blog1
前言:学习OOP课程的第一阶段已经结束了,在此进行对于知识点,题量,难度的个人看法。
(1)相比于另外两次作业,第一次作业基本上是基本的编程的语法训练,题量大,难度小,利于我们熟悉Java的基本语法,旨在让同学们感受Java和c语言的联系和不同之处。这次作业虽然难度不大却是初学者很有必要掌握的,因此,第一次作业为我们带来的对Java语言的理解和认知作用不容小觑。
(2)第二次作业有明显难度上的提高,提高在需要自己去学习新的知识点: 字母-数字转换,串口字符解析,以及String的格式判断与内容提取。但相比于第三次作业,仍是没有很透彻的体现出Java语言的特点和优势,是c语言和Java的过度,第二次作业之后的题目,明显有浓烈的Java语言特点。
(3)第三次作业难度极具增加,开始展现出与C语言不同的编程方式,对于类的构造,运用,是这次作业需要掌握的内容,第三次作业中每道题目都有自己独特的难点,对于初学者来说有相当大的难度,其难度主要体现在知识点的综合运用,不仅仅需要类的知识,还需要大数,字符匹配,替代等方法去辅助题目的完成,其中许多的细节性的问题难以把控。最终是未达到满分遗憾结束,但是我积累了相当宝贵经验,学习到了宝贵的知识,正所谓“不积跬步,无以至千里”。
各题目:设计与分析、采坑心得、改进建议 。
(1)7-2 串口字符解析
设计与分析
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a = in.next(); if(a.length()<11) { System.out.print("null data"); return; } if(a.matches("^[1]*$")) { System.out.print("null data"); return; } int start = 0,i=0,num = 1,sum = 0; boolean parity = false,validate = false; for(start = 0;start<a.length()-10;start++) { if(a.charAt(start)=='0') { System.out.print(num+":"); num++; if(a.charAt(start+10)=='0') { validate = false; }else { validate = true; sum = 0; for(i=start+1;i<start+9;i++) { if(a.charAt(i)=='1') { sum++; } } if(sum%2==0) { if(a.charAt(start+9)=='1') { parity = true; }else { parity = false; } }else { if(a.charAt(start+9)=='0') { parity = true; }else { parity = false; } } } if(validate == true) { if(parity == true) { for(i=start+1;i<start+9;i++) { System.out.print(a.charAt(i)); } System.out.print("\n"); }else { System.out.println("parity check error"); } }else { System.out.println("validate error"); } start = start + 10; } } } }
该题较简单,不需要构建多个类去完成,仅仅是通过简单的主函数便可以完成全部的功能,虽然形式简单,但是还是出现了对bug的不断调试。以下阐述我的采坑心得:
踩坑心得
开始的时候对奇偶校验位理解不够,后研究资料理解:
1.偶校验码
8位数据位和1位校验位,共9个数据,其中1的个数必须为偶数
一般校验位可以由八位数据位按照二进制方式直接相加(不考虑进位)得到。
11001010的校验位a=(1+1+0+0+1+0+1+0)=0;
所以发送数据时为110010100.
2.奇校验码
8位数据位和1位校验位,共9个数据,其中1的个数必须为奇数
一般校验位可以由八位数据位直接相加取反(同样不考虑进位)。
11001010的校验位a=~(1+1+0+0+1+0+1+0)=1;
所以发送数据时为110010101.
改进建议
1个起始位‘0’+八个有效数据+一个奇校验位+一个结束位 = 11位
找到0后开始对他后面10位做处理
先判断最后一位是不是结束1,再判断是否奇校验正确,通过两次判断结果来输出。
这个题只要是结尾错了,那就是“validate error”,所以可以先判断结尾,结尾正确再去判断是否奇校验正确。
(2)7-1 点线形系列1-计算两点之间的距离
设计与分析
import java.util.Scanner; public class Main{ public static void main(String args[]) { int flag=1; Scanner in = new Scanner(System.in); String str = in.nextLine(); String s[] = str.split(" "); for(int i=0;i<s.length;i++) { String[] a = s[i].split(","); if(a.length>2) flag=0; for(int j=0;j<a.length;j++) { int count=0; if(a[j].charAt(0)=='0'&&a[j].length()>1) if(a[j].charAt(1)!='.') flag=0; if(a[j].charAt(0)=='+'||a[j].charAt(0)=='-') { if(a[j].charAt(1)=='0') { if(a[j].charAt(2)!='.') flag=0; } if(a[j].charAt(1)<'0'||a[j].charAt(1)>'9') flag=0; } for(int k=0;k<a[j].length();k++) { if(a[j].charAt(k)=='.') { count++; if(k==a[j].length()-1) flag=0; } } if(count>1) flag=0; } } if(flag==0) { System.out.println("Wrong Format"); } else if(flag==1&&s.length>2||s.length<2) { System.out.println("wrong number of points"); } else { double x1,y1,x2,y2; String[] p= str.split("[ ,]"); x1 = Double.parseDouble(p[0]); y1 = Double.parseDouble(p[1]); x2 = Double.parseDouble(p[2]); y2 = Double.parseDouble(p[3]); double distance = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); System.out.println(distance); } } }
该题有一点难度,经过一系列调试,总结出踩坑心得:
踩坑心得
使用java自带的Point类
import java.awt.Point;//引用awt包下的Point类,此类的功能是表示 (x,y) 坐标空间中的位置的点
改进建议
改进后的计算两点和的代码
double distance = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
(3)7-2 点线形系列2-线的计算
import java.util.Scanner;
class Point {
private int x, y;// x,y为点的坐标
//求两点之间的距离
public double distance(Point p1) {
return Math.sqrt((p1.x -this.x)*(p1.x -this.x)+(p1.y-this.y)*(p1.y-this.y));
}
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public Point() {
super();
x = y =0;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
class Line{
Point p1,p2;
public Line(Point x,Point y){
p1=x;
p2=y;
}
public Point getP1() {
return p1;
}
public void setP1(Point p1) {
this.p1 = p1;
}
public Point getP2() {
return p2;
}
public void setP2(Point p2) {
this.p2 = p2;
}
public double getLength() {
return p1.distance(p2);
}
public String toString() {
return "Line [p1=" + p1 + ", p2=" + p2 + "]";
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
while(n!=0) {
int a=sc.nextInt();
int b=sc.nextInt();
int c=sc.nextInt();
int d=sc.nextInt();
n--;
Point x=new Point(a,b);
Point y=new Point(c,d);
Line l =new Line(x,y);
System.out.println(l.toString());
System.out.println("此线段的长度为:"+String.format("%.1f", l.getLength()));
//l.getLength();
}
}
}
踩坑心得
错误写法:只有一个类Main,所有问题交给main方法执行,无法做到资源的重复利用,从而减少解决相关问题时间和资源。
改进建议
1)定义两个Point对象p1,p2;
2)写出有参构造方法,传递两个对象值给p1,p2
3)为p1,p2写出setters,和getters方法
4)为Line写出一个getLength方法求直线中两点的长度
5) 为LIne写一个ToString方法,方法如下所示:
public String toString() { return “Line [p1=” + p1 + “, p2=” + p2 + “]”; }
import java.text.NumberFormat; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a = in.nextLine(); if(chack_in(a)) { System.out.print(""); }else if(chack_point_sum(a)) { System.out.print(""); }else { String[] aa = a.split(":"); String[] point = aa[1].split(" "); switch(aa[0]) { case "1": operation_1(point); break; case "2": operation_2(point); break; case "3": operation_3(point); break; case "4": operation_4(point); break; case "5": operation_5(point); break; } } in.close(); } //操作1// public static void operation_1(String[] point) { Triangle triangle = new Triangle(); String[] point1 = point[0].split(","); String[] point2 = point[1].split(","); String[] point3 = point[2].split(","); triangle.p1.input(Double.parseDouble(point1[0]), Double.parseDouble(point1[1])); triangle.p2.input(Double.parseDouble(point2[0]), Double.parseDouble(point2[1])); triangle.p3.input(Double.parseDouble(point3[0]), Double.parseDouble(point3[1])); if(triangle.chack_triangle()){ System.out.print("data error"); }else { if(triangle.shape_line_triangle()==1) { System.out.print("true true"); }else { System.out.print("true false"); } } } //操作2// public static void operation_2(String[] point) { Triangle triangle = new Triangle(); String[] point1 = point[0].split(","); String[] point2 = point[1].split(","); String[] point3 = point[2].split(","); triangle.p1.input(Double.parseDouble(point1[0]), Double.parseDouble(point1[1])); triangle.p2.input(Double.parseDouble(point2[0]), Double.parseDouble(point2[1])); triangle.p3.input(Double.parseDouble(point3[0]), Double.parseDouble(point3[1])); if(triangle.chack_triangle()){ System.out.print("data error"); }else { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(6); System.out.print(nf.format(triangle.caluate_C())+" "+nf.format(triangle.caluate_S())+" "+ nf.format(triangle.caluate_gravity_point().read_x())+" "+nf.format(triangle.caluate_gravity_point().read_y())); } } //操作3// public static void operation_3(String[] point) { Triangle triangle = new Triangle(); String[] point1 = point[0].split(","); String[] point2 = point[1].split(","); String[] point3 = point[2].split(","); triangle.p1.input(Double.parseDouble(point1[0]), Double.parseDouble(point1[1])); triangle.p2.input(Double.parseDouble(point2[0]), Double.parseDouble(point2[1])); triangle.p3.input(Double.parseDouble(point3[0]), Double.parseDouble(point3[1])); if(triangle.chack_triangle()){ System.out.print("data error"); }else { if(triangle.shape_horn_triangle()==1) { System.out.print("false false true"); }else if(triangle.shape_horn_triangle()==0) { System.out.print("false true false"); }else { System.out.print("true false false"); } } } //操作4// public static void operation_4(String[] point) { Triangle triangle = new Triangle(); Triangle triangle1 = new Triangle(); Line line = new Line(); String[] point1 = point[0].split(","); String[] point2 = point[1].split(","); String[] point3 = point[2].split(","); String[] point4 = point[3].split(","); String[] point5 = point[4].split(","); line.p1.input(Double.parseDouble(point1[0]), Double.parseDouble(point1[1])); line.p2.input(Double.parseDouble(point2[0]), Double.parseDouble(point2[1])); triangle.p1.input(Double.parseDouble(point3[0]), Double.parseDouble(point3[1])); triangle.p2.input(Double.parseDouble(point4[0]), Double.parseDouble(point4[1])); triangle.p3.input(Double.parseDouble(point5[0]), Double.parseDouble(point5[1])); Line l1 = new Line(); l1.p1=triangle.p1;l1.p2=triangle.p2; Line l2 = new Line(); l2.p1=triangle.p1;l2.p2=triangle.p3; Line l3 = new Line(); l3.p1=triangle.p2;l3.p2=triangle.p3; if(line.p1.chack_point(line.p2)){ System.out.print("points coincide"); }else if(triangle.chack_triangle()){ System.out.print("data error"); }else { if(line.if_parallel(l3)==0||line.if_parallel(l2)==0||line.if_parallel(l1)==0) { System.out.print("The point is on the edge of the triangle"); }else { System.out.print(triangle.caluate_sum_intersection(line)); } } } //操作5// public static void operation_5(String[] point) { Triangle triangle = new Triangle(); Point p = new Point(); String[] point1 = point[0].split(","); String[] point2 = point[1].split(","); String[] point3 = point[2].split(","); String[] point4 = point[3].split(","); p.input(Double.parseDouble(point1[0]), Double.parseDouble(point1[1])); triangle.p1.input(Double.parseDouble(point2[0]), Double.parseDouble(point2[1])); triangle.p2.input(Double.parseDouble(point3[0]), Double.parseDouble(point3[1])); triangle.p3.input(Double.parseDouble(point4[0]), Double.parseDouble(point2[1])); Line l1 = new Line(); l1.p1=triangle.p1;l1.p2=triangle.p2; Line l2 = new Line(); l2.p1=triangle.p1;l2.p2=triangle.p3; Line l3 = new Line(); l3.p1=triangle.p2;l3.p2=triangle.p3; if(triangle.chack_triangle()){ System.out.print("data error"); }else { if(l1.if_on_line(p)||l2.if_on_line(p)||l3.if_on_line(p)) { System.out.print("on the triangle"); }else { if(triangle.if_inside(p)) { System.out.print("in the triangle"); }else { System.out.print("outof the triangle"); } } } } //检查总字符串的格式// public static boolean chack_in(String a) { boolean ttr = false; String[] aa = a.split(":"); String[] point = aa[1].split(" "); if(aa[0].length()!=1) { ttr = true; }else if(aa[0].charAt(0)!='1'&&aa[0].charAt(0)!='2'&&aa[0].charAt(0)!='3' &&aa[0].charAt(0)!='4'&&aa[0].charAt(0)!='5') { ttr = true; } if(aa.length!=2) { ttr = true; } for(int i=0;i<point.length;i++) { if(point[i].length()==0) { ttr = true ; } } for(int i=0;i<point.length;i++ ) { for(int j=0;j<point[i].length();j++) { if(point[i].contains(",")) { String[] number = point[i].split(","); if(number.length==2) { if(number[0].length()>=2) { if(number[0].charAt(0)=='0'&&number[0].charAt(1)=='0') { ttr = true; } } if(number[1].length()>=2) { if(number[1].charAt(0)=='0'&&number[1].charAt(1)=='0') { ttr = true; } } if(!number[0].matches("^([+-]?\\d+)(.\\d+)?")) { ttr = true ; } if(!number[1].matches("^([+-]?\\d+)(.\\d+)?")) { ttr = true ; } }else { ttr = true ; } }else { ttr = true ; } } } return ttr; } //检查总字符串所含的点的个数// public static boolean chack_point_sum(String a) { boolean arry = false; int cnt = 0; String[] aa = a.split(":"); String[] point = aa[1].split(" "); cnt = point.length; if(a.charAt(0)=='1'&&cnt!=3) { arry = true; }else if(a.charAt(0)=='2'&&cnt!=3) { arry = true ; }else if(a.charAt(0)=='3'&&cnt!=3) { arry = true ; }else if(a.charAt(0)=='4'&&cnt!=5) { arry = true ; }else if(a.charAt(0)=='5'&&cnt!=4) { arry = true ; } return arry; } } //点类// class Point { private double x,y; //读入x y 的值// public void input(double a,double b) { x = a; y = b; } //读取x的值// public double read_x() { return x; } //读取y的值// public double read_y() { return y; } //计算两点的距离// public double caluate_distance(Point p) { return Math.sqrt((x-p.x )*(x-p.x )+(y-p.y )*(y-p.y)); } //检查线的两点是否重合// public boolean chack_point(Point p) { boolean wssa = false ; if(Math.abs(x-p.read_x())<1e-15&&Math.abs(y-p.read_y())<1e-15) { wssa = true ; } return wssa; } } //线段// class Line{ Point p1 = new Point(); Point p2 = new Point(); //检查线段的斜率是否存在// public boolean chack_slope() { boolean wssa = true ; if(Math.abs(p1.read_x()-p2.read_x())<1e-15) { wssa = false ; } return wssa; } //计算线段的斜率// public double caluate_slope() { return (p1.read_x()-p2.read_y())/(p1.read_x()-p2.read_y()); } //计算点到直线的距离// public double caluate_distance(Point a) { double distance ; if(if_on_line(a)){ distance = 0; }else { distance = Math.abs(a.read_x()*p1.read_y()+p1.read_x()*p2.read_y()+p2.read_x()*a.read_y() -a.read_x()*p2.read_y()-p1.read_x()*a.read_y()-p2.read_x()*p1.read_y())/p1.caluate_distance(p2); } return distance ; } //判断点是否再直线上// public boolean if_on_line(Point p) { boolean jes = false ; Line l1 = new Line(); Line l2 = new Line(); l1.p1=p1;l1.p2=p; l2.p1=p2;l2.p2=p; if(l1.caluate_slope()==l2.caluate_slope()) { jes = true; } return jes; } //判断点是否在线段内// //在线段内返回true,在线段外返回false// public boolean if_in_line(Point p) { boolean jes = true ; if(p.caluate_distance(p1)>p1.caluate_distance(p2)||p.caluate_distance(p2)>p1.caluate_distance(p2)) { jes = false ; } return jes; } //判断两直线是否平行// //若两直线平行返回1,若两直线重合返回0,若两直线相交返回-1 public int if_parallel(Line l) { int cnt ; double x1 = (p1.read_x()-p2.read_x())*(l.p1.read_x()-l.p2.read_x()) +(p1.read_y()-p2.read_y())*(l.p1.read_y()-l.p2.read_y()); if(x1/(p1.caluate_distance(p2)*l.p1.caluate_distance(p2))!=1) { cnt=-1; }else { if(l.caluate_distance(p1)==0) { cnt=0; }else { cnt=1; } } return cnt; } //计算两直线交点,返回Point// public Point caluate_intersection(Line a) { Point p = new Point(); double dx1 = p1.read_x()-p2.read_x(); double dx2 = a.p1.read_x()-a.p2.read_x(); double dy1 = p1.read_x()-p2.read_x(); double dy2 = a.p1.read_x()-a.p2.read_x(); double mid1 = dy1/dx1; double mid2 = dy2/dx2; double rx = (a.p2.read_y()-p2.read_y()-a.p2.read_y()*mid2+p2.read_y()*mid1)/(mid1-mid2); double ry = (rx-p2.read_x())*mid1+p2.read_y(); p.input(rx, ry); return p; } } //三角形// class Triangle{ Point p1 = new Point(); Point p2 = new Point(); Point p3 = new Point(); //检查三点是否构成三角形// //若构成三角形返回false,若不构成三角形返回true// public boolean chack_triangle() { boolean err = true ; if(Math.abs(p1.caluate_distance(p2)-p1.caluate_distance(p3))<p2.caluate_distance(p3) &&Math.abs(p1.caluate_distance(p3)+p1.caluate_distance(p2))>p2.caluate_distance(p3)){ err = false ; } return err ; } //判断是否为等边三角形,或等腰三角形// //若为等腰三角形,返回0// //若为等边三角形,返回1// public int shape_line_triangle() { int shape = 0; if(Math.abs(p1.caluate_distance(p2)-p1.caluate_distance(p3))<1e-15&& Math.abs(p2.caluate_distance(p1)-p2.caluate_distance(p3))<1e-15) { shape = 1; } return shape; } //计算三角形面积,返回面积// public double caluate_S() { return Math.abs(p1.read_x()*p2.read_y()+p2.read_x()*p3.read_y()+p3.read_x()*p1.read_y() -p1.read_x()*p3.read_y()-p2.read_x()*p1.read_y()-p3.read_x()*p2.read_y())/2; } //计算三角形的周长,返回周长// public double caluate_C() { return p1.caluate_distance(p2)+p1.caluate_distance(p3)+p2.caluate_distance(p3); } //计算三角形的重心坐标,返回Point// public Point caluate_gravity_point() { Point p = new Point(); double dx = (p1.read_x()+p2.read_x()+p3.read_x())/3; double dy = (p1.read_y()+p2.read_y()+p3.read_y())/3; p.input(dx, dy); return p; } //判断三角形是锐角三角形还是直角三角形或钝角三角形// //若是锐角三角形返回1,若是直角三角形返回0,若是钝角三角形则返回-1// public int shape_horn_triangle() { int shape ; double j1 = (p2.read_x()-p1.read_x())*(p3.read_x()-p1.read_x()) +(p2.read_y()-p1.read_y())*(p3.read_y()-p1.read_y()); double j2 = (p3.read_x()-p2.read_x())*(p1.read_x()-p2.read_x()) +(p3.read_y()-p2.read_y())*(p1.read_y()-p2.read_y()); double j3 = (p1.read_x()-p3.read_x())*(p2.read_x()-p3.read_y()) +(p1.read_y()-p3.read_y())*(p2.read_y()-p3.read_y()); if(j1<0||j2<0||j3<0) { shape = 1; }else if(j1==0||j2==0||j3==0) { shape = 0 ; }else { shape = -1; } return shape; } //计算直线与三角形的交点// //返回交点个数// public int caluate_sum_intersection(Line a) { int sum = 0; Line l1 = new Line(); l1.p1=p1;l1.p2=p2; Line l2 = new Line(); l2.p1=p1;l2.p2=p3; Line l3 = new Line(); l3.p1=p2;l3.p2=p3; if(l1.if_parallel(a)==1) { Point point1 = a.caluate_intersection(l2); if(l2.if_in_line(point1)) { sum++; } Point point2 = a.caluate_intersection(l3); if(l3.if_in_line(point2)) { sum++; } }else if(l2.if_parallel(a)==1) { Point point1 = a.caluate_intersection(l1); if(l1.if_in_line(point1)) { sum++; } Point point2 = a.caluate_intersection(l3); if(l3.if_in_line(point2)) { sum++; } }else if(l3.if_parallel(a)==1) { Point point1 = a.caluate_intersection(l1); if(l1.if_in_line(point1)) { sum++; } Point point2 = a.caluate_intersection(l2); if(l2.if_in_line(point2)&&point1.chack_point(point2)) { sum++; } }else { Point point1 = a.caluate_intersection(l1); if(l1.if_in_line(point1)) { sum++; } Point point2 = a.caluate_intersection(l2); if(l2.if_in_line(point2)&&point1.chack_point(point2)) { sum++; } Point point3 = a.caluate_intersection(l2); if(l2.if_in_line(point3)&&point1.chack_point(point3)&&point2.chack_point(point3)) { sum++; } } return sum; } //判断点是否再三角形内部// public boolean if_inside(Point a) { boolean rea = false ; Line l1 = new Line(); l1.p1=p1;l1.p2=a; Line l2 = new Line(); l2.p1=p2;l2.p2=a; Line l3 = new Line(); l3.p1=p3;l3.p2=a; Line l4 = new Line(); l4.p1=p1;l4.p2=p2; Line l5 = new Line(); l5.p1=p2;l5.p2=p3; Line l6 = new Line(); l6.p1=p3;l6.p2=p1; if(!l5.if_in_line(l1.caluate_intersection(l5))||!l4.if_in_line(l3.caluate_intersection(l4)) ||!l6.if_in_line(l2.caluate_intersection(l6))) { rea = true; } return rea; } }
踩坑心得
代码调试了很久,最终也没能通过全部的测试点,留下了些许遗憾。
改进建议
public double caluate_C();//计算三角形的周长
public double caluate_S();//计算三角形的面积
public Point caluate_gravity_point();//计算三角形的重心
public int caluate_sum_intersection();//计算直线与三角形的交点个数
public Point if_inside();//判断点是否在三角形内部
public boolean chack_triangle();//判断三角形是否合法
总结:
首先在第一阶段的学习中,通过循序渐进的方式从开始认识Java再到本阶段的最高潮---类设计。学习的东西虽然基础,但是掌握却需要大量联系。从最基本的语法认知,到主动自己上网查找所需要功能的写法,再到初入Java面向对象编程的基本---类设计,这带给我们的是从以前C语言编程到Java语言编程习惯的改变。作为初学者,发现还有许多东西需要去掌握:
1.类与类之间的关系,当能够了解,并运用类与类之间的关系,则能解决大多数问题,许多时候正是不知如何进行将类互相呼应,导致代码亢长,产生垃圾代码,这不利于学习;
2.正则表达式,许多问题围绕着对于字符串的处理,若用常规方法,则是耗时巨大,效率极低的,正则表达式的使用则会将问题简化,将字符串处理模式化;