wimmm

BLOG1-习题1-3总结

前言

在完成发布的前三个习题后做出此blog

第一次题目集题目量多,共九题,但题目都较为简单,基本考察的是基本的程序设计(从控制台读取输入,命名变量等)以及if-else语句或for循环的使用等。

第二次题目集则有难有易,共有三题,其中7-2较其他两题较难(主要是题目太长不易看懂),而7-1.7-3两题都是运用与字符串有关的函数来解决相关的问题(如字符串转化,查找字符串等),在前几周的自学中掌握了该类题目完成的方法。

第三次题目集则相比较于前面两次习题来说是比较困难的,除了第一题外其他题目的复杂程度高,需要分多个类,包含到了正则表达式有关知识点,且各个题目之间都有一定的关联性,由于开始动手的时间较晚,因此本次题目的完成度较低,成绩不理想。

设计与分析

习题二7-1

输入一个由英文字母组成的字符串(大小写均可),将所有英文字母转换成它们在字母表中的序号,例如:“AbbcD”转换为“12234”。

输入格式:

由英文字母组成的字符串(大小写均可)。例如:“AbbcD”
若包含非英文字母,视为非法输入。

输出格式:

所有英文字母转换成它们在字母表中的序号,例如:“12234”。
非法输入输出"Wrong Format".

import java.util.Scanner;

public class Main{
	
	public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
	    String str1 = sc.nextLine().toString();
        
        boolean isDigit = true;
        for(int i=0 ; i<str1.length() ; i++)
        {
            if(Character.isLetter(str1.charAt(i)) == false)
                {
                    isDigit = false;
                    break;
                
                } 
        }
        if(isDigit == true)
        {
            String str2 = str1.toLowerCase();
            byte[] bytes = str2.getBytes();
        for (int i = 0; i < bytes.length; i++) 
        {
            byte a = bytes[i];
            System.out.print(a - 96);
        }
        }
       else
       {
           System.out.print("Wrong Format");
       }

    }
}

 

本题较为简单,首先将字符串中的所有字母运用toLowerCase()变为小写字母,再用getBytes()将字符串转化为字节数组,最后根据小写字母的ascii码与数字的差进行转化。

 踩坑心得

刚开始在着手于判断整个字符串是否是全字母,在书写的时候用了更复杂的方法,而后找到了isLetter()函数来判断是否是字符

习题二7-2

RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送5~8位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(5~8位,具体位数由通信双方提前设置)前加上1位起始位“0”,在有效数据之后加上1位可选的奇偶校验位和1位结束位“1”。请编写程序,模拟串口接收处理程序,注:假定有效数据是8位,奇偶校验位采用奇校验。

输入格式:

由0、1组成的二进制数据流。例如:11110111010111111001001101111111011111111101111

输出格式:

过滤掉空闲、起始、结束以及奇偶校验位之后的数据,数据之前加上序号和英文冒号。
如有多个数据,每个数据单独一行显示。
若数据不足11位或者输入数据全1没有起始位,则输出"null data",
若某个数据的结束符不为1,则输出“validate error”。
若某个数据奇偶校验错误,则输出“parity check error”。
若数据结束符和奇偶校验均不合格,输出“validate error”。
如:11011或11111111111111111。
例如:
1:11101011
2:01001101
3:validate error

import java.util.Scanner;
public class chuankou {

public static void main(String[] args) {
            
            Scanner in = new Scanner(System.in);
           String str = in.next();
            if(str.length()<11)
            {
                System.out.print("null data");
            }
            if(str.matches("^[1]*")) 
            {
                System.out.print("null data");
            }
            int count = 0,i=0,num = 1,sum = 0;
            boolean par = falseboolean val = false;
            for(count = 0;count<str.length()-10;count++) 
            {
                if(str.charAt(count)=='0')
                {
                    System.out.print(num+":");
                    num++;
                    if(str.charAt(count+10)=='0')
                    {
                        val = false;
                    }
                    else 
                    {
                        val = true;
                        sum = 0;
                        for(i=count+1;i<count+9;i++) 
                        {
                            if(str.charAt(i)=='1') 
                            {
                                sum++;
                            }
                        }
                        if(sum%2==0) 
                        {
                            par = true;
                            
                            
                        }
                        else 
                        {
                            if(str.charAt(count+9)=='0') 
                            {
                                
                                par = true;
                            }
                            else 
                            {
                                par = false;
                            }
                        }
                    }
                    if(val == true) 
                    {
                        if(par == true) 
                        {
                            for(i=count+1;i<count+9;i++) 
                            {
                                System.out.print(str.charAt(i));
                            }
                            System.out.print("\n");
                        }
                        else 
                        {
                            System.out.println("parity check error");
                        }
                    }
                    else 
                    {
                        System.out.println("validate error");
                    }
                    count  = count+ 10;
                }
            }
        }
     
    }

        

本题虽然题目较长难以理解,但仔细阅读还是能够理解其中含义,首先我们应该判断正确的输入格式(使用了length()与正则表达式),再根据par与val两个判断工具实现8位数字数据的判断,再将其输出,稍微复杂的是检测的过程。

踩坑心得

在判断有效位时下了很多功夫,找不到从哪里开始判断,而且也没有看清题目分的是奇校验还是偶校验,所以一直过不了,后面运用判断工具来实现各项内容

习题二7-3

学校学生学号格式定义如下:
2位年级号+2位学院号+2位班级号+2位序号,如19041103,
编写程序处理用全院学生学号连接起来的长字符串,学院编号为20,包括17、18、19、20四个年级,请从字符串中提取特定两个班级202017班、202061班同学的学号后四位输出,输出编号之间用空格分隔,不换行。
注意:需要排除非法输入。

输入格式:

全院学生学号组成的长字符串(学号之间无分隔)
学号格式定义如下:
2位年级号+2位学院号+2位班级号+2位序号,如19041103,

输出格式:

特定两个班级202017班、202061班同学的学号后四位
如:1701 6103 1704

import java.util.Scanner;

public class Main{
    
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine().toString();
        int a=0,b=6;
        int c=str1.length();
        if(str1.length()%8==0)
        {
            for(int i=0;i<str1.length();i++)
            {
                if("202017".equals(str1.substring(a,b))==true||"202061".equals(str1.substring(a,b))==true)
                {
                    if(b+2==c)
                        System.out.print(str1.substring(a+4,b+2));
                    else
                        System.out.print(str1.substring(a+4,b+2) + " ");
                }
                a+=8;
                b+=8;
                
            }
            
        }
        else if(str1.contains(" "))
        {
            System.out.println("Wrong Format");
        }
        else
        {
            System.out.println("Wrong Format");
        }
    }
}

本题较为简单,首先判断输入格式,再通过字符串比较查找出202061与202017班的位置再将其输出即可。

踩坑心得

substring()函数的使用用来输出所要的内容范围,一开始是想运用数组和循环来输出特定范围的数字,后面发现从字符串到数组之间要进行转换等,比较的麻烦,又从书上学到了该函数,才转换了输出方式

习题三7-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”。

输出格式:

计算所得的两点之间的距离。例如:1.4142135623730951

package distance;
import java.util.Scanner;
    import java.util.regex.*;

    
public class main {

        
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            String str = sc.nextLine().toString();
            //String sub =   "";
            
            Pattern p = Pattern.compile("(-?|\\\\+?)([1-9][\\\\d]*\\\\.[0-9][\\\\d]*|[0]\\\\.[0-9]*|[1-9][\\\\d]*|0)[,](-?|\\\\+?)([1-9][\\\\d]*\\\\.[0-9][\\\\d]*|[0]\\\\.[0-9]*|[1-9][\\\\d]*|0)[ ](-?|\\\\+?)([1-9][\\\\d]*\\\\.[0-9][\\\\d]*|[0]\\\\.[0-9]*|[1-9][\\\\d]*|0)[,](-?|\\\\+?)([1-9][\\\\d]*\\\\.[0-9][\\\\d]*|[0]\\\\.[0-9]*|[1-9][\\\\d]*|0)");
            Matcher m=p.matcher(str); 
            if(m.find()==true)
            {
                String[] a = str.split(" ");
                
                String[] b = a[0].split(",");
                String[] c = a[1].split(",");
                double x1,x2,y1,y2;
                x1 = Double.parseDouble(b[0]);
                    
                y1 = Double.parseDouble(b[1]);
                    
                x2 = Double.parseDouble(c[0]);
                    
                y2 = Double.parseDouble(c[1]);
                
                //double x2 = Double.valueOf(b[0].toString());
                //double y2 = Double.valueOf(b[0].toString());
                //double value = Double.valueOf(.toString());
                double distance =(double) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
                
                System.out.print(distance);
            }
            else
            {
                System.out.println("Wrong Format");
            }
                
        }
    }

本题需要用到正则表达式判断输入格式是否正确(浮点数,浮点数 浮点数,浮点数),通过split()字符串分割先根据空格分成两个坐标再根据“,”分割成x与y,再通过string和double的强制转换获取x与y的double值,最后根据斜率的计算公式获得并输出自己的结果

踩坑心得

在正则表达式方面掌握艰难,又根据老师发出的网址进行了理解与掌握,在double转string方面也学习到了几种方法,刚开始利用字符表达式判断的时候就想运用多个if-else语句一个一个符号一个符号判断,结果发现很麻烦,判断失败且输入过不了测试点,于是便决定整个字符串进行判断才成功识别。

习题三7-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",

输出格式:

见题目描述。

package distance;
import java.util.Scanner;
import java.util.regex.*;

public class dianxain {

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String str = sc.nextLine().toString();
    Pattern a = Pattern.compile("1:([+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?)\s+[+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?");
    Pattern b = Pattern.compile("2:([+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?)\s+[+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?,[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?");
    Pattern c = Pattern.compile("3:([+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?)\s+[+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?,[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?");
    Pattern d = Pattern.compile("4:([+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?)\s+[+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?,[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\\\\\\\\\d]+(.[\\\\\\\\\\\\\\\\d]*)?,[+-]?[\\\\\\\\\\\\\\\\d]+(.[\\\\\\\\\\\\\\\\d]*)?");
    Pattern e = Pattern.compile("5:([+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\d]*)?)\s+[+-]?[\\\\d]+(.[\\\\d]*)?,[+-]?[\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?,[+-]?[\\\\\\\\d]+(.[\\\\\\\\d]*)?)\\s+[+-]?[\\\\\\\\\\\\\\\\d]+(.[\\\\\\\\\\\\\\\\d]*)?,[+-]?[\\\\\\\\\\\\\\\\d]+(.[\\\\\\\\\\\\\\\\d]*)?");
    Matcher a1=a.matcher(str);
    Matcher b1=b.matcher(str);
    Matcher c1=c.matcher(str);
    Matcher d1=d.matcher(str);
    Matcher e1=e.matcher(str);
    if(a1.find()==true)
    {
        String st=str.replace(":",",");
        String s=st.replace(" ",",");
        String m[] = s.split(",");
        double x1 = Double.parseDouble(m[1]);
        double y1 = Double.parseDouble(m[2]);
        double x2 = Double.parseDouble(m[3]);
        double y2 = Double.parseDouble(m[4]);
        if(x1!=x2) 
        {
            double xielu = (y2-y1)/(x2-x1);
            System.out.print(xielu);
        }
        else if(x1==x2&&y1==y2)
            System.out.print("points coincide");
        else               
           System.out.print("Slope does not exist");
    }
    
    else if(b1.find()==true)
    {
        String st=str.replace(":",",");
        String s=st.replace(" ",",");
        String m[] = s.split(",");
        double x1 = Double.parseDouble(m[1]);
        double y1 = Double.parseDouble(m[2]);
        double x2 = Double.parseDouble(m[3]);
        double y2 = Double.parseDouble(m[4]);
        double x3 = Double.parseDouble(m[5]);
        double y3 = Double.parseDouble(m[6]);
        if(((x1==x2)&&(y1==y2))||((x2==x3)&&(y2==y3))||((x1==x3&&y1==y3))) 
        {
            System.out.print("points coincide");
        }
        else 
        {
            double diatance =Math.abs(((y1-y2)*x3+(x2-x1)*y3+x1*y2-y1*x2))/(Math.sqrt((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2)));
            System.out.print(diatance);
        }  
    }
    else if(c1.find()==true)
    {
        String st=str.replace(":",",");
        String s=st.replace(" ",",");
        String m[] = s.split(",");
        double x1 = Double.parseDouble(m[1]);
        double y1 = Double.parseDouble(m[2]);
        double x2 = Double.parseDouble(m[3]);
        double y2 = Double.parseDouble(m[4]);
        double x3 = Double.parseDouble(m[5]);
        double y3 = Double.parseDouble(m[6]);
        if(((x1==x2)&&(y1==y2))||((x2==x3)&&(y2==y3))||((x1==x3&&y1==y3))) 
        {
            System.out.print("points coincide");
        }
        else 
        {
            if((y3-y2)/(x3-x2)==(y3-y1)/(x3-x1)||(y3-y1)/(x3-x1)==(y2-y1)/(x2-x1)||(y3-y2)/(x3-x2)==(y2-y1)/(x2-x1))
            {
                System.out.print("true");
            }
            else
            {
                System.out.print("false");
            }
            
        }
    }
    else if(d1.find()==true)
    {
        String st=str.replace(":",",");
        String s=st.replace(" ",",");
        String m[] = s.split(",");
        double x1 = Double.parseDouble(m[1]);
        double y1 = Double.parseDouble(m[2]);
        double x2 = Double.parseDouble(m[3]);
        double y2 = Double.parseDouble(m[4]);
        double x3 = Double.parseDouble(m[5]);
        double y3 = Double.parseDouble(m[6]);
        double x4 = Double.parseDouble(m[7]);
        double y4 = Double.parseDouble(m[8]);
        if((y2-y1)/(x2-x1)==(y3-y4)/(x3-x4))
        {
            System.out.print("true");
        }
        else
        {
            System.out.print("false");
        }    
    }
    else if(e1.find()==true)
    {
        String st=str.replace(":",",");
        String s=st.replace(" ",",");
        String m[] = s.split(",");
        double x1 = Double.parseDouble(m[1]);
        double y1 = Double.parseDouble(m[2]);
        double x2 = Double.parseDouble(m[3]);
        double y2 = Double.parseDouble(m[4]);
        double x3 = Double.parseDouble(m[5]);
        double y3 = Double.parseDouble(m[6]);
        double x4 = Double.parseDouble(m[7]);
        double y4 = Double.parseDouble(m[8]);
        if(((x1==x2)&&(y1==y2))||((x2==x3)&&(y2==y3))||((x1==x3&&y1==y3))||(x1==x4)&&(y1==y4)||(x2==x4)&&(y2==y4)||(x3==x4)&&(y3==y4)) 
        {
            System.out.print("points coincide");
        }
        else if((y1-y2)/(x1-x2)==(y3-y4)/(x3-x4))
        {
            System.out.print("is parallel lines,have no intersection point");
        }
        
    }
    else
    {
        System.out.println("Wrong Format");
    }
                
}
}

 

 

 

 虽然本题老师要求要多个类,但是由于掌握不是很完全代码比较多bug,所以就按照一个类进行书写。

首先是判断输入的字符串是不是如题目格式所输入,根据正则表达式,所输入的数字都是个位数来判断是哪一个选项,再将字符串中的“:”与“ ”转换成“,”,根据字符串分割获取x,y的值,再根据各自的选项进行操作并输出结果

踩坑心得

 本题和上一题有联系,都需要用到正则表达式去判断字符串的格式,本来是想运用到多个类去实现各个选项,但发现我现在的技术还不成熟,不能实现这项操作,于是就使用了if-else语句进行判断与选择,其实看起来复杂每个选项都是较为简单实现的,都是高中学习过的数学知识,但是在if的条件中老是在()上出现问题,要么多要么少

而且选项五的有bug测试过不了,不知道如何将求得的交点按规定格式输出,老是失败,就没有附上,我也还在学习着如何不书写在一个main函数里面

习题三7-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"

package homework_3.triangle;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {    

        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        InputData d = new InputData();
        ParseInput.paseInput(s, d);
        int choice = d.getChoice();
        ArrayList ps = d.getPoints();
        switch (choice) {
        case 1:
            handle1(ps);
            break;
        case 2:
            handle2(ps);
            break;
        case 3:
            handle3(ps);
            break;
        case 4:
            handle4(ps);
            break;
        case 5:
            handle5(ps);
            break;
        case 6:
            handle6(ps);
            break;
        }

    }

    public static void handle1(ArrayList<Point> ps) {
        PointInputError.wrongNumberOfPoints(ps, 3);
        Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2));
        System.out.println(t.isIsoscelesTriangle() + " " + t.isEquilateralTriangle());

    }
  public static void handle2(ArrayList<Point> ps) {
        PointInputError.wrongNumberOfPoints(ps, 3);
        Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2));
        double d = t.getPerimeter(), s = t.getArea();
        Point p = t.getMidpoint();        
        System.out.println(OutFormat.doubleFormat(d) + " " + OutFormat.doubleFormat(s) + " "
                + OutFormat.doubleFormat(p.x) + "," + OutFormat.doubleFormat(p.y));
    }

    public static void handle3(ArrayList<Point> ps) {
        PointInputError.wrongNumberOfPoints(ps, 3);
        Triangle t = new Triangle(ps.get(0), ps.get(1), ps.get(2));
        System.out.println(t.isObtuseTriangle() + " " + t.isRightTriangle() + " " + t.isAcuteTriangle());
    }    

    public static void handle4(ArrayList<Point> ps) {
        PointInputError.wrongNumberOfPoints(ps, 5);
        Line l = new Line(ps.get(0), ps.get(1));
        Triangle t = new Triangle(ps.get(2), ps.get(3), ps.get(4));
        if (t.judgeLineCoincide(l)) {
            System.out.println("The line is coincide with one of the triangle's edge");
            System.exit(0);
        }
        ps = t.getIntersections(l);
        int num = ps.size();
        if (num == 2) {
            double[] ds = t.calArea(ps.get(0), ps.get(1));
            Arrays.sort(ds);
            System.out.println(num + " " + OutFormat.doubleFormat(ds[0]) + " " + OutFormat.doubleFormat(ds[1]));
            // System.out.println(num);
        } else {
            System.out.println(num);
        }
    }
    public static void handle5(ArrayList<Point> ps) {
        PointInputError.wrongNumberOfPoints(ps, 4);
        Triangle t = new Triangle(ps.get(1), ps.get(2), ps.get(3));
        Point p = ps.get(0);
        int i = t.isInside(p);
        if(i==0) {
            System.out.println("on the triangle");
            return;
        }
        if(i==-1) {
            System.out.println("outof the triangle");
            return;
        }
        System.out.println("in the triangle");
    }
        
}


public class InputData {
    private int choice;;//用户输入的选择项
    private ArrayList<Point> points = new ArrayList();//用户输入的点坐标
    public int getChoice() {
        return choice;
    }
    public void setChoice(int choice) {
        this.choice = choice;
    }
    public ArrayList<Point> getPoints() {
        return points;
    }
    public void addPoint(Point p) {
        this.points.add(p);
    }
    
}
public class Line {
    private Point p1;//线上的第一个点
    private Point p2;//线上的第二个点


    public Line(double x1, double y1, double x2, double y2) {
        Point p1 = new Point(x1, y1);
        Point p2 = new Point(x2, y2);
        LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
        this.p1 = p1;
        this.p2 = p2;
    }

    public Line(Point p1, Point p2) {
        LineInputError.pointsCoincideError(p1, p2);//两点是否重合,重合则报错并退出
        this.p1 = p1;
        this.p2 = p2;
    }

    /* 获取线条的斜率 */
    public Double getSlope() {
        // (x1-x2=0)注意考虑斜率不存在即返回double类型无穷大"Infinite"
        return (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
    }

    /* 判断x是否在线上 */
    public boolean isOnline(Point x) {
        //System.out.println("isOnline");
        //System.out.println(p1.x + "  " + p1.y + "  " + p2.x + "  " + p2.y + "  " + x.x + "  " + x.y + "  ");

        // 点重合
        if ((x.getX() == p1.getX() && x.getY() == p1.getY()) || (x.getX() == p2.getX() && x.getY() == p2.getY())) {
            return true;
        }
        Line l = new Line(p1, x);
        if (l.getSlope().isInfinite() && this.getSlope().isInfinite()) {
            return true;
        }

        /*
         * if (l.getSlope().isInfinite() || this.getSlope().isInfinite()) { return
         * false; }
         */

        // 此点与线上任意一点构成的线的斜率相等则此点在线上
        double b1 = l.getSlope(), b2 = this.getSlope();
        //System.out.println(b1 + "  " + b2 + " " + (b1- b2) + " " + (Math.abs(b1 - b2) < 0.00000000001));

        return Math.abs(b1 - b2)  < 0.00000000001;// b1==b2;
    }

    /* 获取点x到线的距离(最短距离,即垂线) */
    public double getDistance(Point x) {
        

     double distY = p2.getY() - p1.getY(); double distX = p2.getX() - p1.getX(); return Math.abs(x.getX() * distY - x.getY() * distX - p1.getX() * distY + p1.getY() * distX) / p1.getDistance(p2); } /* 判断x是否在线上且在两点之间 */ public boolean isBetween(Point x) { //System.out.println("isBetween" + " " + this.p1.x + " " + p1.y + " " + p2.x + " " + p2.y + " " + x.x + " " + x.y); if (!this.isOnline(x)) { return false; } // 与端点重合,认为不在在两点之间, if (x.equals(p1) || x.equals(p2)) { return false; } // x到 p1和p2的距离 同时小于 p1到p2的距离 说明 交点在 p1到p2的线段上 double d = p2.getDistance(p1); boolean b = x.getDistance(p2) < d && x.getDistance(p1) < d; //System.out.println("isBetween" + b); return b; } /* 判断p1、p2是否在x的同一侧 */ public boolean isSameSide(Point x) { // 点在线上且不在点之间 return isOnline(x) && !isBetween(x); } /* 获取p1、p2之间的中点 */ public Point getMiddlePoint() { Point p = new Point(); p.setX((p1.getX() + p2.getX()) / 2); p.setY((p1.getY() + p2.getY()) / 2); return p; } /* 获取线段的第一个坐标点 */ public Point getPointA() { return p1; } /* 获取线段的第二个坐标点 */ public Point getPointB() { return p2; } /* 获取与线条l之间的夹角,若两条线段交叉(交叉点位于其中一条线的两点之间),取较小的夹角 */ public double getAngle(Line l) { // 利用公式θ=arctan∣(k2- k1)/(1+ k1k2)∣,此时求较小的夹角 double k2 = getSlope(); double k1 = l.getSlope(); return (double) (Math.atan(Math.abs((k2 - k1) / (1 + k1 * k2))) * 180.0 / Math.PI);// 返回值为角度 } // 是否平行,平行返回true,否则false。 public boolean isParallel(Line l) { Double b1 = this.getSlope(); Double b2 = l.getSlope(); if ((b1.isInfinite()) && (b2.isInfinite())) { return true; } else { return (this.getSlope().doubleValue() == l.getSlope().doubleValue()); } } // 两条线是否重合,重合返回true,否则false。 public boolean isCoincide(Line l) { if (!this.isParallel(l)) { return false; } if (this.isOnline(l.p1)) { return true; } return false; } // 获取交叉点,若两条线平行,返回null。 public Point getIntersection(Line l) { // LineInputError.isParallelError(this, l); if (this.isParallel(l)) { return null; } if (p1.equals(l.p1) || p1.equals(l.p2)) { return p1; } if (p2.equals(l.p1) || p2.equals(l.p2)) { return p2; } Point p3 = l.p1, p4 = l.p2; double x_member, x_denominator, y_member, y_denominator; Point cross_point = new Point(); x_denominator = p4.x * p2.y - p4.x * p1.y - p3.x * p2.y + p3.x * p1.y - p2.x * p4.y + p2.x * p3.y + p1.x * p4.y - p1.x * p3.y; x_member = p3.y * p4.x * p2.x - p4.y * p3.x * p2.x - p3.y * p4.x * p1.x + p4.y * p3.x * p1.x - p1.y * p2.x * p4.x + p2.y * p1.x * p4.x + p1.y * p2.x * p3.x - p2.y * p1.x * p3.x; if (x_denominator == 0) cross_point.x = 0; else cross_point.x = x_member / x_denominator; y_denominator = p4.y * p2.x - p4.y * p1.x - p3.y * p2.x + p1.x * p3.y - p2.y * p4.x + p2.y * p3.x + p1.y * p4.x - p1.y * p3.x; y_member = -p3.y * p4.x * p2.y + p4.y * p3.x * p2.y + p3.y * p4.x * p1.y - p4.y * p3.x * p1.y + p1.y * p2.x * p4.y - p1.y * p2.x * p3.y - p2.y * p1.x * p4.y + p2.y * p1.x * p3.y; if (y_denominator == 0) cross_point.y = 0; else cross_point.y = y_member / y_denominator; // System.out.println(cross_point.x + ","+cross_point.y); return cross_point; // 平行返回(0,0) } } public class LineInputError { // 直线的两点重合的错误判断和提示。 public static void pointsCoincideError(Point p1, Point p2) { if ((p1.getX() == p2.getX()) && p1.getY() == p2.getY()) { System.out.println("points coincide"); System.exit(0); } } } package homework_3.triangle; import java.text.DecimalFormat; public class OutFormat { //按要求格式化实数的输出。 public static Double doubleFormat(double b) { DecimalFormat df = new DecimalFormat("#.000000"); Double output = Double.valueOf(df.format(b)); return output; } } public class ParseInput { /* * 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5 * 一个空InputData对象 * 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中 * 输出:包含选项值和所有点的Point对象的InputData对象。 */ public static void paseInput(String s, InputData d) { PointInputError.wrongChoice(s); d.setChoice(getChoice(s)); s = s.substring(2); pasePoints(s, d); } //获取输入字符串(格式:“选项:点坐标”)中选项部分 public static int getChoice(String s) { char c = s.charAt(0); return c-48; } /* * 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn * 一个空InputData对象 * 输出:所有点的Point对象 */ public static void pasePoints(String s, InputData d) { String[] ss = s.split(" "); if (ss.length == 0) return; for (int i = 0; i < ss.length; i++) { d.addPoint(readPoint(ss[i])); } } /* * 输入:包含单个点信息的字符串,格式:x,y * 输出:Point对象 */ public static Point readPoint(String s) { PointInputError.wrongPointFormat(s); String[] ss = s.split(","); double x = Double.parseDouble(ss[0]); double y = Double.parseDouble(ss[1]); // System.out.println("match"); return new Point(x, y); } } package homework_3.triangle; //用于定义一个“点”类 public class Point { public double x; public double y; public Point() { } public Point(double x,double y) { this.x=x; this.y=y; } /* 设置坐标x,将输入参数赋值给属性x */ public void setX(double x) { this.x = x; } /* 设置坐标y,将输入参数赋值给属性y */ public void setY(double y) { this.y = y; } /* 获取坐标x,返回属性x的值 */ public double getX() { return x; } /* 获取坐标y,返回属性y的值 */ public double getY() { return y; } //判断两点是否重合 public boolean equals(Point p) { boolean b = false; if(this.x==p.getX()&&this.y==p.getY()) { b=true; } return b; } /* 计算当前点和输入点p之间的距离 */ public double getDistance(Point p) { } } package homework_3.triangle; import java.util.ArrayList; public class PointInputError { //判断从字符串中解析出的点的数量是否合格。 public static void wrongNumberOfPoints(ArrayList ps, int num) { if (ps.size() != num) { System.out.println("wrong number of points"); System.exit(0); } } //判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序 public static void wrongPointFormat(String s) { if (!s.matches("[+-]?([1-9]\\d*|0)(\\.\\d+)?,[+-]?([1-9]\\d*|0)(\\.\\d+)?")) { System.out.println("Wrong Format"); System.exit(0); } } // 输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一 public static void wrongChoice(String s) { if (!s.matches("[1-5]:.+")) { System.out.println("Wrong Format"); System.exit(0); } } } package homework_3.triangle; import java.util.ArrayList; import java.util.Arrays; public class Triangle { private Point x; private Point y; private Point z; public Triangle(Point x, Point y, Point z) { this.x = x; this.y = y; this.z = z; if (!this.isTriangle()) { System.out.println("data error"); System.exit(0); } } /* 判断x\y\z三个点的坐标是否能构成一个三角形 */ public boolean isTriangle() { } /* 获取三角形的中点(三条中线的交点) */ public Point getMidpoint() { // 中点即重心,利用性质求解 Point p = new Point(); p.setX((this.x.getX() + this.y.getX() + this.z.getX()) / 3); p.setY((this.x.getY() + this.y.getY() + this.z.getY()) / 3); return p; } /* 获取三角形的三条边线 */ public Line[] getSideline() { // 设置第一条边线 Line line1 = new Line(x, y); // 设置第二条中线 Line line2 = new Line(x, z); // 设置第三条中线 Line line3 = new Line(y, z); Line[] lines = { line1, line2, line3 }; return lines; } /* 获取三角形的面积,此处采用海伦公式 */ public double getArea() { } /* 获取三角形的周长 */ public double getPerimeter() { return x.getDistance(y) + y.getDistance(z) + z.getDistance(x); } /* 判断是否等腰三角形 */ public boolean isIsoscelesTriangle() { } /* 判断是否等边三角形 */ public boolean isEquilateralTriangle() { } /* 判断是否直角三角形 */ public boolean isRightTriangle() { } /* 判断是否钝角三角形 */ public boolean isObtuseTriangle() { } /* 判断是否锐角三角形 */ public boolean isAcuteTriangle() { } //判断点p是否本三角形的顶点 public boolean isVertex(Point p) { return p.equals(x) || p.equals(y) || p.equals(z); } /* * 判断点p是否在本三角形内部(射线法) * 输出:1:在内部,-1:在外部,0:在三角形上 */ public int isInside(Point p) { //int i = 0; if (this.isOnTheEdge(p)) { return 0; } if (isVertex(p)) { return 0; } Point pb; Line l; if (p.x == 0 && p.y == 0) { pb = new Point(0, 1); l = new Line(p, pb); } else { pb = new Point(0, 0); l = new Line(p, pb); } ArrayList<Point> ps = this.getIntersections(l);//获取直线与三角形的交点列表 int num = ps.size(); if (num == 0||num==1) { return -1; } if(num == 2) { Line l1 = new Line(ps.get(0),ps.get(1)); if(l1.isBetween(p)) { return 1; }else { return -1; } } return 0; } // 获取直线l与三角形的交点,如果没有,数组为空。 public ArrayList<Point> getIntersections(Line l) { } public double[] calArea(Point p1, Point p2) { } public double calAreaDiffrence(Triangle t1) { double area = t1.getArea(); area = getArea() - area; return area; } public boolean judgeLineCoincide(Line l) { } public boolean isOnTheEdge(Point p) { } public Point getX() { return x; } public void setX(Point x) { this.x = x; } public Point getY() { return y; } public void setY(Point y) { this.y = y; } public Point getZ() { return z; } public void setZ(Point z) { this.z = z; } }

 

踩坑心得

本题在类的构造方面稍有欠缺,没能做出完整的题目,代码就暂时附上老师上课所书写的部分代码了,虽然老师在课上多有讲解,但是靠自己动手去写还是不能实现全部,而且不知道如何去依靠输入的坐标去判断各个条件是否满足

比如说要靠三个坐标去判断三角形的类型暂时没能想到

总结

三次题目集从难度从简单到复杂,最初是不需要太多设计就能写出来的简单程序,到了后面就设计时要考虑诸多因素,比如类的设计与多功能实现等。

通过这三次习题,学习并掌握了许多知识,从基本的程序设计,一个复杂度较高的程序,实现了自我学习自我设计的过程。

但是在书写代码的途中,代码含有较多且啰嗦的if-else语句,显得代码冗杂,没有好的书写代码的习惯,而且代码上注释少,让他人的可读性大大减小。

在习题二中并未想到运用正则表达式,但是通过习题三的练习可以发现正则表达式比大量的if-else语句来判断所需要的输入格式更加的简单,方便,不用判断一直进行判断

习题三后两题便开始了多个类的书写,让整个代码不只是只有一个main函数在里面,可以划分成许多部分增强代码的可读性与实用性

而且要增强自己的自我学习与知识摄入的能力,学习的知识及时消化应用,才能更好的掌握

 

 

posted on 2022-04-11 09:53  miw  阅读(63)  评论(0编辑  收藏  举报

导航