OO前三次作业总结

目录

  • 作业总结
  • 设计与分析
  • 采坑心得
  • 改进建议
  • 心得体会

一、作业总结

  1. 作业一:作业一整体上难度不大,题目数虽然多但每道题题量相较于后续作业可以说很少,主要是起到一个入门的作用:熟悉Java基本的输入输出方法、常用的方法(如String类里的length()方法等)、如何调用方法以及对if……else和for循环语句的回顾,但也有很多入门者易采的坑,比如直接使用“==”来比较两个对象(尤其是String对象)等。
    总的来说,作业一就是为了起到让大家能尽快熟悉Java语法的基本使用,快速让大家入门的效果,但也有一些小坑需要注意,在后面的文章中再进行分析。

  2. 作业二:
    作业二相较于作业一难度有些许提升,但还没有体现出Java面向对象设计的特点,只是在题目本身上提升了点难度,总体来说中规中矩,对于较为熟练Java语法后且有一定编程经验的同学来说难度不大,稍加思索就可以轻松完成,题目的难点也集中在对各种情况讨论的
    不完整性导致出现疏忽,总体来说难度尚可。

  3. 作业三:
    从作业三开始,无论从题量,难度上都有了很大的提升,也开始体现Java面向对象设计的特点,要把工作重点由设计如何实现某些功能的方法转化为了设计让谁去完成某些功能的类,可以说对于那些对面向对象编程还不够熟悉的同学来说难度比较大,而且题目本身的坑也极多,情况很繁杂,非常容易出现讨论不完全的情况,出现某些个测试点无法通过的情况,个人觉得从作业一、二到三的跨度有些大,因为一二中很少出现需要单独设计类的情况,而到了三不仅要去设计类,而且设计难度还很大(情况太多,很容易考虑不完全),对于那些对面向对象编程理解不够深刻的同学来说很“阴间”,此部分也是后续分析的主要内容。

二、设计与分析

  1. 作业一:
    作业一难度很小,题目意思也很简单,基本没有什么需要思考的地方,只要熟悉了Java一些基本方法,跟着题目意思设计就可以了,重点说一些需要注意的坑,到第三部分再详细描述。
  2. 作业二:
    作业二的2-1(7-1 字母-数字转换),2-3(7-3 String的格式判断与内容提取)这两道题基本没什么绕圈圈的地方,都是对JavaString类基本方法的考察,这里只简单分享一下我的思路:
    2-1:字母-数字转换:

  • 第一,先读取用户输入的字符串str,第二,判断其是否规范(有没有除字母以外的其他字符),第三进行字符转数字。
    判断是否规范使用如下方法:
点击查看代码
public boolean isStandard(String str) { Pattern pattern = Pattern.compile("[^a-zA-Z]"); Matcher matcher = pattern.matcher(str); if (matcher.find()) return false; else return true; }
  • 当然也可以采用遍历字符串各个字符,看每个字符的ASCII码是否处于65-90或者97-122之间来进行判断。
    字符转数字:
点击查看代码
public void letter_num(String str) { String s = str.toLowerCase(Locale.ROOT); for (int i = 0; i < s.length(); i++) { System.out.print(s.charAt(i) - 96); } }
  • 我是先把字符串所有大写字母统一转化为小写(利用toLowerCase方法),然后让其ASCII码值减去96即可获得对应字符。

  • 2-3:String的格式判断与内容提取


本题需要对各种不规范的情况讨论完全:

点击查看代码
public class Main { boolean flag = false; public static void main(String[] args) { String str = new Scanner(System.in).nextLine(); if (new Main().isStandard(str)){ new Main().work(str); }else System.out.println("Wrong Format"); } public boolean isStandard(String str) { if(str.length()%8 != 0) return false; for (int i = 0; i < str.length(); i+=8) { if((!str.substring(i,i+2).equals("17"))&&(!str.substring(i,i+2).equals("18"))&&(!str.substring(i,i+2).equals("19"))&&(!str.substring(i,i+2).equals("20"))) return false; } return true; } public void work(String str) { for (int i = 0; i < str.length(); i+=8) { if(str.substring(i,i+6).equals("202017")||str.substring(i,i+6).equals("202061")){ if(flag){ System.out.print(" "+str.substring(i+4,i+8)); } else{ flag = true; System.out.print(""+str.substring(i+4,i+8)); } } } } }

把握好“学院编号为20,包括17、18、19、20四个年级”这个信息进行判断即可,没有全通过就可能是漏考虑了某些情况导致的。

  • 2-2:串口字符解析:
    题目:RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送58位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(58位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。
    本题的一大难点就是能正确理解题意,把握所有的有效信息:可以采用遍历字符串,找到字符’0’所在的索引,然后以此为首字符,往后截取长度为11的字串进行单独分析,看第11位是不是结束位’1’,第10位奇校验码对不对,如果都符合,则把首字符’0’后面的8位数据再截出来作为一组数据,重复以上步骤即可。然后就是对一些非法情况的判断,比如压根就没有’0’,或者’0’之后的长度不足10位等等,都要进行讨论完全。
    PS:有关奇校验的步骤

点击查看代码
import java.util.Locale; import java.util.Scanner; public class Main { int Mnum = 1; public static void main(String[] args) { String str = new Scanner(System.in).nextLine(); new Main().work(str); } public void work(String str) { boolean flag = true; int num = 0; String tool = null; if (str.length() < 11) { System.out.println("null data"); return; } //101111111101 for (int i = 0; i < str.length();) { if (str.charAt(i) == '0') { num = 0; if (flag) flag = false; if(str.length()+1-i < 11) return; tool = str.substring(i, i + 11); if (tool.charAt(10) != '1') { System.out.println(Mnum++ + ":"+"validate error"); i += 11; continue; } for (int j = 1; j < 9; j++) { if (tool.charAt(j) == '1') num++; } if (tool.charAt(9) == '1') num++; if (num % 2 == 0) { System.out.println(Mnum++ + ":"+"parity check error"); i += 11; continue; } System.out.println(Mnum++ + ":" + tool.substring(1, 9)); i += 11; }else i++; } if (flag) { System.out.println("null data"); return; } } }
  1. 作业三:作业三三道题连贯性很强,后面的题可以用到前面的类,所以,重心在于设计出没有bug且泛用性、功能性都很强的类。
    3-1(点线形系列1-计算两点之间的距离)
    题目:
    输入连个点的坐标,计算两点之间的距离
    输入格式:
    4个double类型的实数,两个点的x,y坐标,依次是x1、y1、x2、y2,两个点的坐标之间以空格分隔,每个点的x,y坐标以英文“,”分隔。例如:0,0 1,1或0.1,-0.3 +3.5,15.6。
    若输入格式非法,输出"Wrong Format"。
    若输入格式合法但坐标点的数量超过两个,输出“wrong number of points”。

我们可以设计一个点类Point。首先思考点类应该具有那些内容:一个点的构造方法需要两个数(分别是该点的x和y坐标),应包含的属性有二维坐标系的两个坐标x和y,包含的方法有求与另一个点的距离方法distance(Point point),比较与另一个点是否相同,重写父类里的equals方法和toString方法(方便后续打印)。思路整理清楚之后我们就可以设计Point类如下:

点击查看代码
class Point { private double x; private double y; @Override public String toString() { /* if(x == -0.0) x = 0.0; if(y == -0.0) y = 0.0; */ return x + "," + y; } public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public double distance(Point point) { return Math.sqrt((x - point.x) * (x - point.x) + (y - point.y) * (y - point.y)); } @Override public boolean equals(Object obj) { Point obj1 = (Point) obj; if (obj1.getX() == this.x && this.y == obj1.getY()) return true; else return false; } }


设计完点类之后该题难点只剩下判断输入字符串是否合乎规范,这一点很容易踩坑,是大部分同学出错的点,第三部分进行分析,这里推荐使用正则表达式进行判断是否规范:
public boolean isStandard(String str) {

String[] s = str.split(" ", 0); String tool[] = null; for (String i : s) { tool = i.split(","); for (String j : tool) { String s = "1"; System.out.println(s.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$ ")); if (!j.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")) { System.out.print("Wrong Format"); return false; } } } if (s.length != 2) { System.out.print("wrong number of points"); return false; } return true;

}
解决完这两大难关之后,本题就可以说已经解决了,只需要在主类里面调用方法即可:
public static void main(String[] args) {

Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); if (new Main().isStandard(s)) { String tool[] = null; String[] point = s.split(" ", 0); tool = point[0].split(","); double x1 = Double.valueOf(tool[0]); double y1 = Double.valueOf(tool[1]); tool = point[1].split(","); double x2 = Double.valueOf(tool[0]); double y2 = Double.valueOf(tool[1]); Point p1 = new Point(x1,y1); System.out.println(p1.distance(new Point(x2,y2))); }

3-2(点线形系列2-线的计算)

  • 用户输入一组选项和数据,进行与直线有关的计算。选项包括:
    1:输入两点坐标,计算斜率,若线条垂直于X轴,输出"Slope does not exist"。
    2:输入三个点坐标,输出第一个点与另外两点连线的垂直距离。
    3:输入三个点坐标,判断三个点是否在一条线上,输出true或者false。
    4:输入四个点坐标,判断前两个点所构成的直线与后两点构成的直线是否平行,输出true或者false.
    5:输入四个点坐标,计算输出前两个点所构成的直线与后两点构成的直线的交点坐标,x、y坐标之间以英文分隔",",并输出交叉点是否在两条线段之内(不含四个端点)的判断结果(true/false),判断结果与坐标之间以一个英文空格分隔。若两条线平行,没有交叉点,则输出"is parallel lines,have no intersection point"。
    输入格式:
    基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。
    例如:1:0,0 1,1
    如果不符合基本格式,输出"Wrong Format"。
    如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
    不论哪个选项,如果格式、点数量都符合要求,但构成任一条线的两个点坐标重合,输出"points coincide",

  • 本题用到了线,所以我们可以基于上一题中的点类Point,设计一个线类Line。同样思考线类的内容:线类的构造方法需要两个点(两点组成一条线),前提是两点不能重复,所以需要在创建Line对象时进行判断两点是否相同,如若相同就不可以创建对象;线的属性有组成该线的两个点A和B(该线类不仅可以表达直线,也可以表示一条线段),组成一条直线的各个参数(这里推荐使用直线的一般式ax+by+c=0来表示直线,可以避免很多情况的讨论)a,b,c,由于我一开始使用的是y=kx+b来表示,需要对x=k这一斜率不存在的直线单独考虑,出现了很多错误,后续更改为一般式的时候,也没有完全作废掉原来的,所以我的Line类有些冗余,里面还保留了k(斜率),nok(表示斜率是否存在),x(就是斜率不存在时,x=k里面的k),特此提醒;线的方法可以很丰富,甚至在后续三角形、四边形等类中为了方便其设计,还要在Line类里面添加新的方法,所以,方法这一块可以很多,这里只列举几个常用的方法getX(double y)和getY(double x),给定x(或者y),来求直线上改点对应的y(或者x), distance(Point p)求直线到p点的距离,isParallel(Line line)该直线是否与line直线平行,isOne(Line line)该直线是否与line直线是同一条直线,seglen()返回该线段的长度,isOnSeg(Point p)p点是否处于该线段上,isOn(Point p)p点是否处于该直线上,Point point(Line line)求两直线交点。设计类如下:
    class Line {
    private double k = 0;
    private boolean nok = false;
    private double x;
    public double a;
    public double b;
    public double c;
    public Point A;
    public Point B;

    public double getK() {

    return k;

    }

    public Line(Point p1, Point p2) {
    this.a = p1.getY() - p2.getY();
    this.b = p2.getX() - p1.getX();
    this.c = p1.getX() * p2.getY() - p2.getX() * p1.getY();
    if ((p1.getX() - p2.getX()) == 0) {
    nok = true;
    x = p1.getX();
    k = Double.NaN;

    if (p1.getY() > p2.getY()) { A = p2; B = p1; } else { A = p1; B = p2; } } else { this.k = -(a / b); if (p1.getX() < p2.getX()) { A = p1; B = p2; } else { A = p2; B = p1; } }

    }

    public double getX(double y) {

    return -((c + b * y) / a);

    }

    public double getY(double x) {

    return -((c + a * x) / b);

    }

    public double distance(Point p) {

    double mol = Math.abs(a * p.getX() + b * p.getY() + c); double den = Math.sqrt(a * a + b * b); return mol / den;

    }

    public boolean isParallel(Line line) {

    if (Math.abs(a * line.b - b * line.a) < 0.000001) return true; else return false;

    }

    public boolean isOne(Line line) {
    if (!isParallel(line))
    return false;
    else {
    if (Math.abs(aline.c-line.ac)<0.00001)
    return true;
    else
    return false;
    }

    }

    public double seglen() {

    return A.distance(B);

    }

    public boolean isOnSeg(Point p) {

    if (!isOn(p)) return false; if (!nok) { if (p.getX() >= A.getX() && p.getX() <= B.getX()) return true; else return false; } else { if (p.getY() >= A.getY() && p.getY() <= B.getY()) return true; else return false; }

    }

    public boolean isOn(Point p) {

    if (nok) { if (p.getX() == this.x) return true; else return false; } double t = getY(p.getX()); if (Math.abs(t - p.getY()) < 0.000001) return true; else return false;

    }

    public Point point(Line line) {

    double x, y; x = (c * line.b - line.c * b) / (line.a * b - a * line.b); y = (a * line.c - line.a * c) / (line.a * b - a * line.b); return new Point(x, y);

    }

    public static boolean isLine(Point a, Point b) {

    if (a.getX() == b.getX() && a.getY() == b.getY()) return false; else return true;

    }
    }

解决完Line类之后,本题还有一个判断输入是否规范的难点,后面多道题与该题规则相同,后续不再赘述,推荐使用正则表达式:
public boolean isStandard(String str) {

str += " "; if (!str.matches("[1-5]:([+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?),[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?) ){2,}")) { System.out.println("Wrong Format"); return false; } String[] split1 = str.split(":"); String[] split2 = split1[1].split(" "); choice = Integer.valueOf(split1[0]); if (num(Integer.valueOf(split1[0])) != split2.length) { System.out.println("wrong number of points"); return false; } return true; }

主类main方法判断输入是否规范,如规范就把用户输入的选项和点保存下来(choice和points[]数组里),然后根据不同的choice调用不同的方法
public class Main {

static int choice; static Point points[] = null; public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); String str = scanner.nextLine(); if (new Main().isStandard(str)) { String[] split1 = str.split(":"); String[] split2 = split1[1].split(" "); points = new Point[split2.length]; int index = 0; for (String s : split2) { String[] split = s.split(","); double x = Double.valueOf(split[0]); double y = Double.valueOf(split[1]); points[index++] = new Point(x, y); } switch (choice) { case 1: new Main().work1(); break; case 2: new Main().work2(); break; case 3: new Main().work3(); break; case 4: new Main().work4(); break; case 5: new Main().work5(); break; } } }

五个选项都是对Line类方法的调用,只要类设计的完善且没有问题,整体上难度下降会很多:
public void work1() throws Exception {

if (!Line.isLine(points[0], points[1])) { System.out.println("points coincide"); System.exit(0); } if ((points[1].getX() - points[0].getX()) == 0) { System.out.println("Slope does not exist"); System.exit(0); } Line line = new Line(points[0], points[1]); System.out.println(line.getK()); } public void work2() { if (!Line.isLine(points[2], points[1])) { System.out.println("points coincide"); System.exit(0); } Line line = new Line(points[1], points[2]); System.out.println(line.distance(points[0])); } public void work3() { Line line = new Line(points[0], points[1]); if (line.isOn(points[2])) System.out.println("true"); else System.out.println("false"); } public void work4() { if (!Line.isLine(points[0], points[1])) { System.out.println("points coincide"); System.exit(0); } if (!Line.isLine(points[2], points[3])) { System.out.println("points coincide"); System.exit(0); } Line line1 = new Line(points[0], points[1]); Line line2 = new Line(points[2], points[3]); if (line1.isParallel(line2)) System.out.println("true"); else System.out.println("false"); } public void work5() { if (!Line.isLine(points[0], points[1])) { System.out.println("points coincide"); System.exit(0); } if (!Line.isLine(points[2], points[3])) { System.out.println("points coincide"); System.exit(0); } Line line1 = new Line(points[0], points[1]); Line line2 = new Line(points[2], points[3]); if (line1.isParallel(line2)) { System.out.println("is parallel lines,have no intersection point"); System.exit(0); } Point point = line1.point(line2); System.out.print(point + " "); if (point.equals(points[0]) || point.equals(points[1]) || point.equals(points[2]) || point.equals(points[3])) { System.out.println("false"); System.exit(0); } if (line1.isOnSeg(point) || line2.isOnSeg(point)) System.out.println("true"); else System.out.println("false"); }

3-3(点线形系列3-三角形的计算)

  • 用户输入一组选项和数据,进行与三角形有关的计算。选项包括:
    1:输入三个点坐标,判断是否是等腰三角形、等边三角形,判断结果输出true/false,两个结果之间以一个英文空格符分隔。
    2:输入三个点坐标,输出周长、面积、重心坐标,三个参数之间以一个英文空格分隔,坐标之间以英文","分隔。
    3:输入三个点坐标,输出是钝角、直角还是锐角三角形,依次输出三个判断结果(true/false),以一个英文空格分隔,
    4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
    5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
    必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"
    输入格式:
    基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
    输出格式:
    基本输出格式见每种选项的描述。
    异常情况输出:
    如果不符合基本格式,输出"Wrong Format"。
    如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
    如果输入的三个点无法构成三角形,输出"data error"。
    注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0
    选项4中所输入线的两个点坐标重合,输出"points coincide",

  • 老规矩,先设计一个三角形类triangle。Triangle类的构造方法需要三个点,属性有三个点A,B,C和三条边AB,BC,AC,方法也同Line类,可以不断丰富完善,boolean isTriangle(Point a, Point b, Point c)三点能否组成一线,double per(),public double area(), public Point core() 返回三角形的周长,面积和重心坐标 :
    class triangle {

    Point A, B, C; Line AB, AC, BC; public triangle(Point a, Point b, Point c) { if (!triangle.isTriangle(a, b, c)) return; A = a; B = b; C = c; AB = new Line(a, b); AC = new Line(a, c); BC = new Line(b, c); } public static boolean isTriangle(Point a, Point b, Point c) { if (!Line.isLine(a, b)) { return false; } Line line = new Line(a, b); if (line.isOn(c)) { return false; } else return true; } public double per() { return A.distance(B) + B.distance(C) + A.distance(C); } public double area() { double h = AB.distance(C); return h * A.distance(B) / 2; } public Point core() { double x = (A.getX() + B.getX() + C.getX()) / 3; double y = (A.getY() + B.getY() + C.getY()) / 3; return new Point(x, y); }

    }

点击查看代码
public void work1() throws Exception { if (!triangle.isTriangle(points[0], points[1], points[2])) { System.out.println("data error"); System.exit(0); } double a = points[0].distance(points[1]); double b = points[1].distance(points[2]); double c = points[2].distance(points[0]); if (a == b || a == c || b == c) System.out.print("true"); else System.out.print("false"); System.out.print(" "); if (a == b && b == c && a == c) System.out.print("true"); else System.out.print("false"); } public void work2() { if (!triangle.isTriangle(points[0], points[1], points[2])) { System.out.println("data error"); System.exit(0); } triangle triangle = new triangle(points[0], points[1], points[2]); Point core = triangle.core(); print(triangle.per()); System.out.print(" "); print(triangle.area()); System.out.print(" "); print(core.getX()); System.out.print(","); print(core.getY()); System.out.print(" "); } public void work3() { if (!triangle.isTriangle(points[0], points[1], points[2])) { System.out.println("data error"); System.exit(0); } triangle triangle = new triangle(points[0], points[1], points[2]); double a = (points[1].getX() - points[0].getX()) * (points[2].getX() - points[0].getX()) + (points[1].getY() - points[0].getY()) * (points[2].getY() - points[0].getY()); double b = (points[0].getX() - points[1].getX()) * (points[2].getX() - points[1].getX()) + (points[0].getY() - points[1].getY()) * (points[2].getY() - points[1].getY()); double c = (points[0].getX() - points[2].getX()) * (points[1].getX() - points[2].getX()) + (points[0].getY() - points[2].getY()) * (points[1].getY() - points[2].getY()); if (a <= 0) { if (a == 0) { System.out.println("false " + "true " + "flase"); System.exit(0); } if (a < 0) { System.out.println("true " + "false " + "false"); System.exit(0); } } if (b <= 0) { if (b == 0) { System.out.println("false " + "true " + "false"); System.exit(0); } if (b < 0) { System.out.println("true " + "false " + "false"); System.exit(0); } } if (c <= 0) { if (c == 0) { System.out.println("false " + "true " + "false"); System.exit(0); } if (c < 0) { System.out.println("true " + "false " + "false"); System.exit(0); } } System.out.println("false " + "false " + "true"); } public void work4() { if (points[0].equals(points[1])) { System.out.println("points coincide"); System.exit(0); } if (!triangle.isTriangle(points[2], points[3], points[4])) { System.out.println("data error"); System.exit(0); } triangle triangle = new triangle(points[2], points[3], points[4]); Line line = new Line(points[0], points[1]); if (triangle.AB.isOne(line) || triangle.AC.isOne(line) || triangle.BC.isOne(line)) { System.out.println("The point is on the edge of the triangle"); System.exit(0); } if (line.isParallel(triangle.AB)) { Point p1 = line.point(triangle.AC); Point p2 = line.point(triangle.BC); if (p1.equals(p2)) { System.out.println("1"); System.exit(0); } else { if (triangle.AC.isOnSeg(p1) && triangle.BC.isOnSeg(p2)) { System.out.print("2 "); double d1 = new triangle(p1, p2, triangle.C).area(); double d2 = triangle.area() - d1; if (d1 < d2) { print(d1); System.out.print(" "); print(d2); } else { print(d2); System.out.print(" "); print(d1); } } else { System.out.println("0"); System.exit(0); } } } else { if (line.isParallel(triangle.AC)) { Point p1 = line.point(triangle.AB); Point p2 = line.point(triangle.BC); if (p1.equals(p2)) { System.out.println("1"); System.exit(0); } else { if (triangle.AB.isOnSeg(p1) && triangle.BC.isOnSeg(p2)) { System.out.print("2 "); double d1 = new triangle(p1, p2, triangle.B).area(); double d2 = triangle.area() - d1; if (d1 < d2) { { print(d1); System.out.print(" "); print(d2); } } else { print(d2); System.out.print(" "); print(d1); } } else { System.out.println("0"); System.exit(0); } } } else { Point p1 = line.point(triangle.AB); Point p2 = line.point(triangle.AC); if (p1.equals(p2)) { System.out.println("1"); System.exit(0); } else { if (triangle.AB.isOnSeg(p1) || triangle.AC.isOnSeg(p2)) { System.out.print("2 "); double d1 = new triangle(p1, p2, triangle.A).area(); double d2 = triangle.area() - d1; if (d1 < d2) { { print(d1); System.out.print(" "); print(d2); } } else { print(d2); System.out.print(" "); print(d1); } } else{ System.out.println("0"); System.exit(0); } } } } } public void work5() { if (!triangle.isTriangle(points[1], points[2], points[3])) { System.out.println("data error"); System.exit(0); } triangle triangle = new triangle(points[1], points[2], points[3]); if (triangle.AB.isOnSeg(points[0]) || triangle.AC.isOnSeg(points[0]) || triangle.BC.isOnSeg(points[0])) { System.out.println("on the triangle"); System.exit(0); } double d1 = (triangle.AB.seglen()*triangle.AB.distance(points[0]))/2; double d2 = (triangle.AC.seglen()*triangle.AC.distance(points[0]))/2; double d3 = (triangle.BC.seglen()*triangle.BC.distance(points[0]))/2; if (Math.abs(d1+d2+d3-triangle.area())<0.00001) { System.out.println("in the triangle"); System.exit(0); } else { System.out.println("outof the triangle"); System.exit(0); } }

三、踩坑心得

  1. 作业一:
    1)Java里的“”符比较的是两个对象的地址,比较内容需要调用equal方法,其祖宗类Object里的方法equal方法默认也是比较两个对象的地址,所以需要手动重写你需要比较的内容,String类已经实现了重写,所以可以调用equal方法来比较两个字符串的内容是否相等。
    2)1-8里比较两个浮点数是否相等时不能直接使用“
    ”,因为浮点数总有误差存在,应该使得两个浮点数差值的绝对值小于一个足够小的数时,便认为其是相等的。

  2. 作业二:
    作业二整体上没什么容易踩的坑,大多也都是自己没有考虑到那种情况,结合测试点提醒也很容易想到,个人在做作业二时比较顺利。

  3. 作业三:
    1)3-1在输入是否规范的判断上确实很容易出错,比如“0.”“0.0”这样很难想到的情况,我在做这道题时也是在这一点一直出错,通过百度看别人的代码才明白的,确实很痛苦。
    2)3-2的“不论哪个选项,如果格式、点数量都符合要求,但构成任一条线的两个点坐标重合,输出"points coincide"”这一点也容易犯错,比如选择4要求输入四个点,前两个组成一条线,后两个组成一条线,都要进行判断是否不规范,第一次做的时候给忽略掉了,不知道有没有和我一样的错误
    3)3-2还容易出现的错误就是对直线各种情况没有讨论完全,比如刚开始我使用了y=kx+b的形式代表直线,会有很多情况需要讨论,及其阴间,后来在同学的提醒下更换成了一般式,就可以减少了很多讨论,在以后的设计中也应当采取“不求最简单,但求很泛用”的方法。
    4)3-3的“注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0”这一点在很多选项里都给忽略掉了,导致出现了很多莫名其妙的报错,还是审题不够认真
    四、改进建议

  • 在判断字符串是否符合规范的类型题里,正则表达式都很简单方便,所以推荐详细学习一下正则表达式以及Java中对于正则表达式的封装使用方法,可以整体上大幅降低这一类题的难度
  • 作业三的三个类,Point,Line,Triangle类可以添加更多好用的方法,来进一步降低后续题目的难度。
    五、心得体会
    1.这三次作业,由简到难,由浅入深,可以带你从Java的基础使用到面向对象思想的运用,可以说,做好这三次作业,尤其是作业三,可以帮你有效理解什么是面向对象编程。
    2.作业题的难点体现在两处,一是理解题目的意思并思考相应的算法解决,二是考虑到所有的情况。大部分情况下都是绊在第二点,各种各样的情况有时候真的很难完全考虑到,这时候更应该在设计算法时就应该理清楚思路,每一步都要分好情况讨论,尽量减少出错的可能性。
    3.个人的能力是有限的,有时候自己实在找不到自己漏掉了什么情况,一定要找同学帮忙,同时学习别人的算法思路,看看是否比自己的简便。

__EOF__

本文作者userName
本文链接https://www.cnblogs.com/kmld/p/16748690.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   WK666  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示