ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BLOG1-习题1-3总结

2022-04-11 10:02:24  阅读:228  来源: 互联网

标签:总结 p2 p1 Point BLOG1 double System 习题 public


前言

在完成发布的前三个习题后做出此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 = false;
            boolean 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函数在里面,可以划分成许多部分增强代码的可读性与实用性

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

 

 

标签:总结,p2,p1,Point,BLOG1,double,System,习题,public
来源: https://www.cnblogs.com/wimmm/p/16123103.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有