面向对象程序设计第二次blog
一、前言
第四次题目集总结——
- 题量:较多
- 难度:较高
- 知识点:
- 获取输入字符串的特定字符类型
- 获取并储存、计算
- 循环、选择、字符串、数组的使用
- 继承
- 类的设计
- 总结:题目比较难,题量较少,需要用到正则表达式,以及合理的类的设计
期中考试题目集总结——
- 题量:较少
- 难度:较高
- 知识点:
- 继承与多态
- 容器
- 总结:题目数量少,需对继承与多态比较了解。
第五次题目集总结——
- 题量:较少
- 难度:高
- 知识点:
- 复杂的数学运算
- 对五边形、四边形、三边形、点、线、面的判断
- 继承与多态
- 合理的类的设计
二、设计与分析
题目集4——
7-1 sdut-String-2 识蛟龙号载人深潜,立科技报国志(II)(正则表达式)
请编写程序,实现如下功能:读入关于蛟龙号载人潜水器探测数据的多行字符串,从给定的信息找出数字字符,输出每行的数字之和。
提示 若输入为“2012年2月”,则该行的输出为:2014。若干个连续的数字字符作为一个整体,以十进制形式相加。
输入格式:
读入关于蛟龙号载人潜水器探测数据的多行字符串,每行字符不超过80个字符。
以"end"结束。
输出格式:
与输入行相对应的各个整数之和。
输入样例1:
2012年6月27日11时47分,中国“蛟龙”再次刷新“中国深度”——下潜7062米
6月15日,6671米
6月19日,6965米
6月22日,6963米
6月24日,7020米
6月27日,7062米
下潜至7000米,标志着我国具备了载人到达全球99%以上海洋深处进行作业的能力
end
输出样例1:
9165
6692
6990
6991
7050
7095
7099
代码————
1
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] str = new String[20];
String a = in.next();
char[] newstr ;
int[] all = new int[100];
int no = 0;
while(a!="end")
{
str[no] = a;
newstr = str[no].toCharArray();
int time = 0;//记录该行字符串所有的数的数量
int[] shuzi = new int[100];//每行字符串的数字组成的数组
for(int i=0; i<newstr.length; i++)//循环找数字
{
if(newstr[i]<='9'&&newstr[i]>='0')//每一次经过文字第一次找到数字就得到该处的数
{
int weishu=0;//位数
int[] gewei = new int[100];//记录各位所对应的数字
for(int j = i;j<i+4;j++ )//循环求该数
{
if(newstr[j]<='9'&&newstr[j]>='0')//如果是数字则用数组记录各位所对应的数字并让位数加1
{
gewei[weishu]=newstr[j];
weishu++;
}
else//如果读到文字则计算该数,并用数组记录
{
shuzi[time]=(int) (gewei[0]*(Math.pow(10, weishu))+gewei[1]*(Math.pow(10, weishu-1))+gewei[2]*(Math.pow(10, weishu-2))+gewei[3]*(Math.pow(10, weishu-3)));
System.out.print(shuzi[time]);
time++;
}
j++;
}
i=i+weishu+1;
}
// System.out.print(myCharArray[i] + " "); //将每个字符打印出来
}
// System.out.println( no+"."+str[no]);
int sum=0;
for(int i = 0;i<time;i++)
{
sum=sum+shuzi[i];
}
all[no]=sum;
a = in.next();
no++;
}
if(a=="end")
{
for(int i=0;i<no;i++)
{
System.out.println(all[i]);
}
}
// for(int i=0;i<time;i++)
// {
// System.out.println(shuzi[i]);
// i++;
// }
//
}
}
需要使用正则表达式来获取每行的多组数字并相加,并用循环计算并输出。
正则表达式简介
- 正则表达式是由一些具有特殊含义的字符组成的字符串,多用于查找、替换符合规则的字符串。在表单验证、Url映射等处都会经常用到。
一、元字符
元字符:即为有特定含义的字符,常见的元字符如下
- . 匹配除换行符以外的任意字符
- \w 匹配字母或数字或下划线或汉字
- \s 匹配任意的空白符
- \d 匹配数字
- \b 匹配单词的开始或结束
- ^ 匹配字符串的开始(在集合字符里[^a]表示非(不匹配)的意思
- $ 匹配字符串的结束
二、反义字符
反义字符:多用于查找除某个字符以外其他任意字符均可以的情况
常用的反义字符如下:
- \W 匹配任意不是字母,数字,下划线,汉字的字符
- \S 匹配任意不是空白符的字符
- \D 匹配任意非数字的字符
- \B 匹配不是单词开头或结束的位置
- [^x] 匹配除了x以外的任意字符
- [^aeiou] 匹配除了aeiou这几个字母以外的任意字符
三、限定字符
限定字符多用于重复匹配次数
常用的限定字符如下
- * 重复零次或更多次
- + 重复一次或更多次
- ? 重复零次或一次
- {n} 重复n次
- {n,} 重复n次或更多次
- {n,m} 重复n到m次
详解和示例:
(1)\d* 匹配重复0次或多次数字 例如:可能为空 或 任意数字 (2,3。。。。)
(2)\d+ 匹配重复1次或多次数字 例如:可能为1个或多个数字 1,23,234,2345,........
(3)\d? 匹配重复次个或者一次数字 例如:可能为空或者任意的一个数字(1,2,。。。)
(4)\d{8}匹配重复8次数字 例如:123456768
(5)\d{4,}匹配重复至少4次数字 例如:1234,12345,124244,。。。。。
(6)^\d{8,11}$ 匹配重复8-11次数字 例如:12345678,123456789,1234567890,12345678901
四、转义字符
在实际的开发中,可能会遇到要比配元字符的情况,这个时候就需要进行字符转义,如元字符 . * \ 需要转换为\. \* \\
五、字符分枝
字符分枝多用于满足不同情况的选择,用“|”将不同的条件分割开来,比如有些固定电话区号有三位,有些有四位,这个时候可以采用字符分枝
六、字符分组
字符分组多用于将多个字符重复,主要通过使用小括号()来进行分组
形如:(\d\w){3} 重复匹配3次(\d\w)
常用于表示IP地址 形如: ((25[0-5]|2[0-4][0-9]|[0-1]\d\d)\.){3}(25[0-5]|2[0-4][0-9]|[0-1]\d\d)
七、懒惰匹配和贪婪匹配
贪婪匹配:正则表达式中包含重复的限定符时,通常的行为是匹配尽可能多的字符。
懒惰匹配:有时候需要匹配尽可能少的字符。
常用的懒惰匹配限定符如下
- *? 重复任意次,但尽可能少重复
- +? 重复1次或更多次,但尽可能少重复
- ?? 重复0次或1次,但尽可能少重复
- {n,m}? 重复n到m次,但尽可能少重复
- {n,}? 重复n次以上,但尽可能少重复
其他语法
- \a 报警字符(打印它的效果是电脑嘀一声)
- \b 通常是单词分界位置,但如果在字符类里使用代表退格
- \t 制表符,Tab
- \r 回车
- \v 竖向制表符
- \f 换页符
- \n 换行符
- \e Escape
- \0nn ASCII代码中八进制代码为nn的字符
- \xnn ASCII代码中十六进制代码为nn的字符
- \unnnn Unicode代码中十六进制代码为nnnn的字符
- \cN ASCII控制字符。比如\cC代表Ctrl+C
- \A 字符串开头(类似^,但不受处理多行选项的影响)
- \Z 字符串结尾或行尾(不受处理多行选项的影响)
- \z 字符串结尾(类似$,但不受处理多行选项的影响)
- \G 当前搜索的开头
- \p{name} Unicode中命名为name的字符类,例如\p{IsGreek}
- (?>exp) 贪婪子表达式
- (?<x>-<y>exp) 平衡组
- (?im-nsx:exp) 在子表达式exp中改变处理选项
- (?im-nsx) 为表达式后面的部分改变处理选项
- (?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
- (?(exp)yes) 同上,只是使用空表达式作为no
- (?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
- (?(name)yes) 同上,只是使用空表达式作为no
常用的实用正则表达式整理
- 只能输入数字:"^[0-9]*$"。
- 只能输入n位的数字:"^"d{n}$"。
- 只能输入至少n位的数字:"^"d{n,}$"。
- 只能输入m~n位的数字:。"^"d{m,n}$"
- 只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。
- 只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。
- 只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"。
- 只能输入非零的正整数:"^"+?[1-9][0-9]*$"。
- 只能输入非零的负整数:"^"-[1-9][]0-9"*$。
- 只能输入长度为3的字符:"^.{3}$"。
- 只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。
- 只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。
- 只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。
- 只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"。
- 只能输入由数字、26个英文字母或者下划线组成的字符串:"^"w+$"。
- 验证用户密码:"^[a-zA-Z]"w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。
- 验证是否含有^%&’,;=?$""等字符:"[^%&’,;=?$"x22]+"。
- 只能输入汉字:"^["u4e00-"u9fa5]{0,}$"
- 验证Email地址:"^"w+([-+.]"w+)*@"w+([-.]"w+)*"."w+([-.]"w+)*$"。
- 验证InternetURL:"^http://(["w-]+".)+["w-]+(/["w-./?%&=]*)?$"。
- 验证电话号码:"^("("d{3,4}-)|"d{3.4}-)?"d{7,8}$"正确格式为:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
- 验证身份证号(15位或18位数字):"^"d{15}|"d{18}$"。
- 验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。
- 验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。
- 利用正则表达式限制网页表单里的文本框输入内容:
- 用正则表达式限制只能输入中文:οnkeyup="value=value.replace(/[^"u4E00-"u9FA5] /g,’’)" onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^"u4E00-"u9FA5]/g,’’))"
- 用正则表达式限制只能输入全角字符: οnkeyup="value=value.replace(/[^"uFF00-"uFFFF]/g,’’)" onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^"uFF00-"uFFFF]/g,’’))"
- 用正则表达式限制只能输入数字:οnkeyup="value=value.replace(/[^"d]/g,’’) "onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^"d]/g,’’))"
- 用正则表达式限制只能输入数字和英文:οnkeyup="value=value.replace(/["W]/g,’’) "onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^"d]/g,’’))"
题目集4——
以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
选项4中,若前两个输入线的点重合,输出"points coincide"。
1
import java.scene.shape.Line;
import java.scene.shape.QuadCurve;
import java.scene.shape.TriangleMesh;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.List;
public class Main{
public static void main(String[] args) {
process();
// System.out.println(isNumeric("++1"));
}
public static void process() {
Scanner scanner = new Scanner(System.in);
String input = null;
while ((input = scanner.nextLine()) != null) {
int in = input.length();
int index = 0;
for (; index < in; index++) {
if (input.charAt(index) == ':') break;
}
//得到选项
String selection = input.substring(0, index);
// System.out.println(selection);
//选项不是一到五就报错
if (selection.length() < 1) {
System.out.println("wrong selection for input [○・`Д´・ ○]");
continue;
}
//得到坐标集合
List<double[]> list = getSelection(input, index + 1);
//出错了,结束这一轮
if (list == null) continue;
int n = list.size();
switch (selection) {
case "1":
if(!printCntError(n, 4)) break;
if (isPointsCoincide(list)) {
System.out.println("points coincide");
break;
}
if(!isQuadrilateral(list)){
System.out.println("not a quadrilateral");
break;
}
list = notCoincidePointsCnt(list);
System.out.println(isQuadrilateral(list) + "," + isParallelogram(list));
break;
if(!printCntError(n, 4)) continue;
if (isPointsCoincide(list)) {
System.out.println("points coincide");
continue;
}
if(!isQuadrilateral(list)){
System.out.println("not a quadrilateral");
continue;
}
System.out.println(isQuadrilateral(list) + "," + isParallelogram(list));
break;
case "2":
if(!printCntError(n, 4)) continue;
if (isPointsCoincide(list)) {
System.out.println("points coincide");
continue;
}
if(!isQuadrilateral(list)){
System.out.println("not a quadrilateral");
continue;
}
System.out.println(isDiamond(list) + "," + isRectangle(list) + "," + isSquare(list));
break;
case "3":
if (isPointsCoincide(list)) {
System.out.println("points coincide");
continue;
}
if(!isQuadrilateral(list)){
System.out.println("not a quadrilateral");
continue;
}
BigDecimal bigDecimal = new BigDecimal(getPerimeter(list));
bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP);
//
System.out.print(isConcavePolygon(list) + ",");
System.out.println(new BigDecimal(getPerimeter(list)).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue() + "," +
new BigDecimal(getQuadrilateral(list)).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
break;
case "4":
if(!printCntError(n, 6)) continue;
List<double[]> doubles = notCoincidePointsCnt(list);
if (doubles.size() < 3) {
System.out.println("not a quadrilateral or triangle");
continue;
}
if (doubles.size() < 4){
System.out.println("not a quadrilateral");
continue;
}
break;
case "5":
if(!printCntError(n, 4)) continue;
doubles = notCoincidePointsCnt(list);
if (doubles.size() < 3) {
System.out.println("not a quadrilateral or triangle");
continue;
}
if (doubles.size() < 4){
System.out.println("not a quadrilateral");
continue;
}
break;
default:
System.out.println("wrong selection for input [○・`Д´・ ○]");
break;
}
}
// quadrilateral
}
//得到四边形周长
static double getPerimeter(List<double[]> list) {
List<Line2D.Double> lineList = getLineList(list);
double res = 0.0;
for (int i = 0; i < lineList.size(); i++) {
res += Point.distance(lineList.get(0).getX1(), lineList.get(0).getY1(), lineList.get(0).getX2(), lineList.get(0).getY2());
}
return res;
}
//是否为凸多边形
static boolean isConcavePolygon(List<double[]> list) {
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
double t1 = (p4.getX() - p1.getX()) * (p2.getY() - p1.getY()) - (p4.getY() - p1.getY()) * (p2.getX() - p1.getX());
double t2 = (p1.getX() - p2.getX()) * (p3.getY() - p2.getY()) - (p1.getY() - p2.getY()) * (p3.getX() - p2.getX());
double t3 = (p2.getX() - p3.getX()) * (p4.getY() - p3.getY()) - (p2.getY() - p3.getY()) * (p4.getX() - p3.getX());
double t4 = (p3.getX() - p4.getX()) * (p1.getY() - p4.getY()) - (p3.getY() - p4.getY()) * (p1.getX() - p4.getX());
return t1 * t2 * t3 * t4 > 0;
// if t1 * t2 < 0 and t1*t4< 0:
// return t1
// if t1 * t2 < 0 and t2*t3< 0:
// return t2
// if t2 * t3 < 0 and t3*t4< 0:
// return t3
// if t3 * t4 < 0 and t4*t1< 0:
// return t4
}
//四边形的面积
static double getQuadrilateral(List<double[]> list) {
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
if (!isConcavePolygon(list)) {
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
double t1 = (p4.getX() - p1.getX()) * (p2.getY() - p1.getY()) - (p4.getY() - p1.getY()) * (p2.getX() - p1.getX());
double t2 = (p1.getX() - p2.getX()) * (p3.getY() - p2.getY()) - (p1.getY() - p2.getY()) * (p3.getX() - p2.getX());
double t3 = (p2.getX() - p3.getX()) * (p4.getY() - p3.getY()) - (p2.getY() - p3.getY()) * (p4.getX() - p3.getX());
double t4 = (p3.getX() - p4.getX()) * (p1.getY() - p4.getY()) - (p3.getY() - p4.getY()) * (p1.getX() - p4.getX());
if (t1 * t2 < 0 && t1 * t4 < 0){
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
if (t1 * t2 < 0 && t2 * t3 < 0){
return getTriangleArea(p1, p2, p4) + getTriangleArea(p2, p3, p4);
}
if (t2 * t3 < 0 && t3 * t4 < 0) {
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
if (t3 * t4 < 0 && t4 * t1 < 0) {
return getTriangleArea(p1, p2, p4) + getTriangleArea(p2, p3, p4);
}
return -1;
}
//三角形面积
static double getTriangleArea(Point2D p1, Point2D p2, Point2D p3) {
double a = Point.distance(p1.getX(), p1.getY(), p2.getX(), p2.getY());
double b = Point.distance(p2.getX(), p2.getY(), p3.getX(), p3.getY());
double c = Point.distance(p1.getX(), p1.getY(), p3.getX(), p3.getY());
double s = a + b + c;
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
}
//判断一个点是否多边形内部
//判断一个点是否多边形的边上
public static boolean isOnLine(double[] point, List<double[]> list) {
list = notCoincidePointsCnt(list);
List<Line2D.Double> lineList = getLineList(list);
if (list.size() == 3) {
return isOnLine(point, lineList.get(0).getP1(), lineList.get(0).getP2()) || isOnLine(point, lineList.get(1).getP1(), lineList.get(1).getP2())
|| isOnLine(point, lineList.get(2).getP1(), lineList.get(2).getP2()) || isOnLine(point, lineList.get(3).getP1(), lineList.get(3).getP2());
} else if (list.size() == 4) {
return isOnLine(point, lineList.get(0).getP1(), lineList.get(0).getP2()) || isOnLine(point, lineList.get(1).getP1(), lineList.get(1).getP2())
|| isOnLine(point, lineList.get(2).getP1(), lineList.get(2).getP2()) || isOnLine(point, lineList.get(3).getP1(), lineList.get(3).getP2());
}
return false;
}
//判断一个点在一条线段上 (a,b)是这个点
public static boolean isOnLine(double[] point, Point2D linePoint1, Point2D linePoint2) {
double a = point[0];
double b = point[1];
double x1 = linePoint1.getX();
double y1 = linePoint1.getY();
double x2 = linePoint2.getX();
double y2 = linePoint2.getY();
boolean bl = false;
double p = (y2 - y1) / (x2 - x1);
if (p <= 0) {
if (x1 > x2) {
if (y1 > y2) {
if (a > x2 && a < x1 && b >= y2 && b <= y1) {
bl = true;
}
} else {
if (a > x2 && a < x1 && b >= y1 && b <= y2) {
bl = true;
}
}
} else {
if (y1 > y2) {
if (a > x1 && a < x2 && b >= y2 && b <= y1) {
bl = true;
}
} else {
if (a > x1 && a < x2 && b >= y1 && b <= y2) {
bl = true;
}
}
}
} else {
if (x1 > x2) {
if (y1 > y2) {
if (a > x2 && a < x1 && b > y2 && b < y1) {
bl = true;
}
} else {
if (a > x2 && a < x1 && b > y1 && b < y2) {
bl = true;
}
}
} else {
if (y1 > y2) {
if (a > x1 && a < x2 && b > y2 && b < y1) {
bl = true;
}
} else {
if (a > x1 && a < x2 && b > y1 && b < y2) {
bl = true;
}
}
}
}
return bl;
}
//是否为正方形
static boolean isSquare(List<double[]> list) {
return isDiamond(list) && isRectangle(list);
}
//是否为矩形
static boolean isRectangle(List<double[]> list) {
if (!isParallelogram(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
double mx = (p1.getX() + p2.getX() + p3.getX() + p4.getX()) / 4;
double my = (p1.getY() + p2.getY() + p3.getY() + p4.getY()) / 4;
return Point.distance(p1.getX(), mx, p2.getY(), my) == Point.distance(p2.getX(), mx, p3.getY(), my) &&
Point.distance(p2.getX(), mx, p3.getY(), my) == Point.distance(p3.getX(), mx, p4.getY(), my) &&
Point.distance(p3.getX(), mx, p4.getY(), my) == Point.distance(p4.getX(), mx, p1.getY(), my) &&
Point.distance(p4.getX(), mx, p1.getY(), my) == Point.distance(p1.getX(), mx, p2.getY(), my);
// return ((lineList.get(0).y1 - lineList.get(0).y2) / (lineList.get(0).x1 - lineList.get(0).x2))
// * ((lineList.get(1).y1 - lineList.get(1).y2) / (lineList.get(1).x1 - lineList.get(1).x2)) == -1 ;
}
//是否是菱形
static boolean isDiamond(List<double[]> list) {
if (!isParallelogram(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
// System.out.println(lineList.size());
// for (Line2D.Double aDouble : lineList) {
// System.out.println(aDouble.getP1() +" : " + aDouble.getP2());
// }
return Point.distance(lineList.get(0).getX1(), lineList.get(0).getY1(), lineList.get(0).getX2(), lineList.get(0).getY2()) ==
Point.distance(lineList.get(1).getX1(), lineList.get(1).getY1(), lineList.get(1).getX2(), lineList.get(1).getY2());
}
//是否是平行四边形
static boolean isParallelogram(List<double[]> list) {
if (!isQuadrilateral(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
return Point2D.distance(lineList.get(0).getX1(), lineList.get(0).getY1(), lineList.get(0).getX2(), lineList.get(0).getY2()) ==
Point2D.distance(lineList.get(2).getX1(), lineList.get(2).getY1(), lineList.get(2).getX2(), lineList.get(2).getY2());
}
//是否为四边行
static boolean isQuadrilateral(List<double[]> list){
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
return !((italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3)));
}
//斜率
static double italic(Point2D p1, Point2D p2){
return (p1.getX() - p2.getX()) / (p1.getY() - p2.getY());
}
//是否为重合
static boolean isPointsCoincide(List<double[]> list) {
int n = list.size();
list = notCoincidePointsCnt(list);
return list.size() < n;
}
//返回两点间的距离
static double getDistance(int index1, int index2, List<double[]> list) {
return Point.distance(list.get(index1)[0], list.get(index1)[1], list.get(index2)[0], list.get(index2)[1]);
}
//得到非对角线边的集合
public static List<Line2D.Double> getLineList(List<double[]> list) {
List<Line2D.Double> lineList = new ArrayList<>();
if (!Line2D.linesIntersect(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1])) {
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(0)[0], list.get(0)[1]));
} else {
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(0)[0], list.get(0)[1]));
}
return lineList;
}
//得到去重后的集合
static List<double[]> notCoincidePointsCnt(List<double[]> list) {
List<double[]> temp = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
int j = i + 1;
for (; j < list.size(); j++) {
if (list.get(i)[0] == list.get(j)[0] && list.get(i)[1] == list.get(j)[1]) break;
}
if (j < list.size()) {
int k = 0;
for (; k < temp.size(); k++) {
if (list.get(k)[0] == list.get(j)[0] && list.get(k)[1] == list.get(j)[1]) break;
}
if (k < temp.size()) continue;
}
temp.add(list.get(i));
}
System.out.println(Arrays.toString(temp));
return temp;
}
//打印坐标数量错误信息
public static boolean printCntError(int real, int expect) {
if (real != expect) System.out.println("wrong number of points");
return real == expect;
}
//获得选项
public static List<double[]> getSelection(String str, int start) {
List<double[]> list = new ArrayList<>();
int index = 0;
int n = str.length();
StringBuffer sbf = null;
for (int i = start; i < n; ) {
//空格就跳过
if (str.charAt(i) == ' ') {
i++;
continue;
}
sbf = new StringBuffer();
list.add(new double[2]);
//第一个坐标遇到’,‘停止
while (i < n && str.charAt(i) != ',') {
sbf.append(str.charAt(i));
i++;
}
//不是合法的数字或者没有对应的y坐标就报错
if (i >= n || !isNumeric(sbf.toString())) {
System.out.println("Wrong Format");
return null;
} else list.get(index)[0] = Double.parseDouble(sbf.toString());
i++;
sbf = new StringBuffer();
//第一个坐标遇到空格停止
while (i < n && str.charAt(i) != ' ') {
sbf.append(str.charAt(i));
i++;
}
//不是合法的数字就报错
if (!isNumeric(sbf.toString())) {
System.out.println("Wrong Format");
return null;
} else list.get(index++)[1] = Double.parseDouble(sbf.toString());
}
return list;
}
//判断是否为数字
public static boolean isNumeric(String str) {
if (str.length() < 1) return false;
if (str.charAt(0) == '-') {
str = str.substring(1, str.length());
}
if (str.length() < 1) return false;
if (str.charAt(0) == '0' && str.length() == 1) return true;
int dotCnt = 0;
if (str.charAt(0) == '.' || str.charAt(str.length() - 1) == '.') return false;
if (str.charAt(0) == '0' && (str.length() < 3 || str.charAt(1) != '.')) return false;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '.') {
if (dotCnt > 0) return false;
dotCnt++;
} else if (str.charAt(i) < '0' || str.charAt(i) > '9') return false;
}
return true;
}
}
/*
return (getDistance(0, 1, list) == getDistance(2,3, list)
&& getDistance(1, 2, list) == getDistance(0,3, list)) ||
(getDistance(0, 3, list) == getDistance(2,1, list)
&& getDistance(0, 2, list) == getDistance(1,3, list)) ||
(getDistance(0, 2, list) == getDistance(1,3, list)
&& getDistance(1, 2, list) == getDistance(0,3, list)) ||
(getDistance(0, 1, list) == getDistance(2,3, list)
&& getDistance(0, 2, list) == getDistance(1,3, list)) ||
(getDistance(0, 3, list) == getDistance(2,1, list)
&& getDistance(3, 2, list) == getDistance(0,1, list)) ||
(getDistance(0, 2, list) == getDistance(1,3, list)
&& getDistance(3, 2, list) == getDistance(0,1, list)) ;
*/
输入的格式是否错误判断不全面,类的设计也不好,有好多重复代码,把功能细化可以使代码更简洁易懂并减少代码的重复。
- 类的设计要符合的原则
- 单一职责原则(Single Resposibility Principle,SRP)
- 开放封闭原则(Open Closed Principle,OCP)
- 里氏替换原则(Liskov Substituion Principle,LSP)
- 依赖倒置原则(Dependecy Inversion Principle,DIP)
- 接口分离原则(Interface Segregation Principle,ISP)
7-1、2 点线形系列5-凸五边形的计算-1
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
1:输入五个点坐标,判断是否是五边形,判断结果输出true/false。
2:输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。 若五个点坐标无法构成五边形,输出"not a pentagon"
3:输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"。
以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
1)符合要求的输入:顶点重复或者z与xy都相邻,如:x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
2) 不符合要求的输入:z不与xy都相邻,如:z x y s、x z s y、x s z y
输入格式:
基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
代码———
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.List; public class Main { public static void main(String[] args) {
process(); } public static void process() {
Scanner scanner = new Scanner(System.in);
String input = null;
while ((input = scanner.nextLine()) != null) {
int in = input.length();
int index = 0;
for (; index < in; index++) {
if (input.charAt(index) == ':') break;
}
//得到选项
String selection = input.substring(0, index);
// System.out.println(selection);
//选项不是一到五就报错
if (selection.length() < 1) {
System.out.println("wrong selection for input");
continue;
}
//得到坐标集合
List<double[]> list = getSelection(input, index + 1);
// for (double[] doubles : list) {
// System.out.println(Arrays.toString(doubles));
// }
//出错了,结束这一轮
if (list == null) continue;
int n = list.size();
List<double[]> tempList;
List<Line2D.Double> lineList;
switch (selection) {
case "1":
if(!printCntError(n, 5)) break;
System.out.println("false");
break; case "2":
if(!printCntError(n, 5)) break;
if (isPointsCoincide(list)) {
System.out.println("points coincide");
break;
}
if(!isPentagon(list)){
System.out.println("not a pentagon");
break;
}
list = notCoincidePointsCnt(list);
System.out.println("true "+ alldistance(list)+ " " + getarea(list));
// System.out.println(isDiamond(list) + "," + isRectangle(list) + "," + isSquare(list));
break;
case "3":
if(!printCntError(n, 7)) break;
if (isPointsCoincide(list)) {
System.out.println("points coincide");
break;
}
if(!isQuadrilateral(list)){
System.out.println("The line is coincide with one of the lines");
break;
}
list = notCoincidePointsCnt(list);
BigDecimal bigDecimal = new BigDecimal(getPerimeter(list));
bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP);
lineList = getLineList(list);
//是否为凹多边形
System.out.print(isConvexPolygon(lineList) + ",");
System.out.println(new BigDecimal(getPerimeter(list)).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue() + "," +
new BigDecimal(getQuadrilateralArea(lineList)).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
break;
case "4":
if(!printCntError(n, 6)) break;
Line2D.Double line = new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1]);
tempList = new ArrayList<>();
//将第一个点提取出来
for(int i = 2; i < list.size(); i++){
tempList.add(list.get(i));
}
//list也整理完毕了
list = tempList;
list = notCoincidePointsCnt(list);
lineList = getLineList(list);
removeOverNode(lineList);
//是四边形
if (lineList.size() == 4 && isQuadrilateral(list)){
if(isLineOnQuadrilateral(line, lineList)){
System.out.println("The line is coincide with one of the lines");
break;
}
double[] result = getDivideAreaForQuadrilateral(line, lineList);
result[0] = new BigDecimal(result[0]).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
result[1] = new BigDecimal(result[1]).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println(Math.min(result[0], result[1]) + "," + Math.max(result[0], result[1]));
}
else if(lineList.size() == 3 && isTriangle(new LinkedList<>(lineList), lineList.get(0))){
if(isLineOnTriangle(line, lineList)){
System.out.println("The line is coincide with one of the lines");
break;
}
double[] result = getTriangleAreaForDivided(line, lineList);
result[0] = new BigDecimal(result[0]).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
result[1] = new BigDecimal(result[1]).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println(Math.min(result[0], result[1]) + "," + Math.max(result[0], result[1]));
}
//啥也不是
else {
System.out.println("not a quadrilateral or triangle");
}
break;
case "5":
if(!printCntError(n, 5)) break;
Point2D point = new Point2D.Double(list.get(0)[0], list.get(0)[1]);
tempList = new ArrayList<>();
//将第一个点提取出来
for(int i = 1; i < list.size(); i++){
tempList.add(list.get(i));
}
//list也整理完毕了
list = tempList;
list = notCoincidePointsCnt(list);
lineList = getLineList(list);
removeOverNode(lineList);
if(lineList.size() == 4 && isQuadrilateral(list)) {
//是四边形
if (isOnLine(new double[]{point.getX(), point.getY()}, lineList))
System.out.println("on the quadrilateral");
//判断是否在内部
else System.out.println(isInternal(point, lineList) ? "in the quadrilateral" : "out of the quadrilateral");
}
//是三角形
else if (lineList.size() == 3 && isTriangle(new LinkedList<>(lineList), lineList.get(0))){
if(isOnLine(new double[]{point.getX(), point.getY()}, lineList)) System.out.println("on the triangle");
//判断是否在内部
else System.out.println(isInternal(point, lineList) ? "in the triangle" : "out of the triangle");
break;
}
//不是三角形
else {
System.out.println("not a quadrilateral or triangle");
}
break;
default:
// System.out.println("wrong selection for input [○・`Д´・ ○]");
break;
}
}
// quadrilateral
} //删除变成三角形多余的点
private static void removeOverNode(List<Line2D.Double> lineList) {
boolean flag = true;
while(flag || lineList.size() == 2){
flag = false;
for(int i = 0; i < lineList.size() - 1; i++){
for(int j = i + 1; j < lineList.size(); j++){
if(Line2D.linesIntersect(lineList.get(i).getP1().getX(), lineList.get(i).getP1().getY(), lineList.get(i).getP2().getX(), lineList.get(i).getP2().getY(),
lineList.get(j).getP1().getX(), lineList.get(j).getP1().getY(), lineList.get(j).getP2().getX(), lineList.get(j).getP1().getY())
&& italic(lineList.get(i).getP1(), lineList.get(i).getP2()) == italic(lineList.get(j).getP1(), lineList.get(j).getP2())){
Line2D.Double l1 = lineList.remove(j);
Line2D.Double l2 = lineList.remove(i);
Line2D.Double merge = merge(l1, l2);
lineList.add(merge);
flag = true;
break;
}
}
if(flag) break;
}
}
if(lineList.size() < 3 || lineList.size() == 4) return;
if(lineList.get(0).getP1().getX() == lineList.get(1).getP1().getX() && lineList.get(0).getP1().getY() == lineList.get(1).getP1().getY()){
lineList.remove(lineList.size() - 1);
Line2D.Double temp = lineList.remove(lineList.size() - 1);
lineList.add(new Line2D.Double(temp.getP2(), temp.getP1()));
lineList.add(new Line2D.Double(lineList.get(0).getP2(), lineList.get(1).getP1()));
}else if(lineList.get(0).getP2().getX() == lineList.get(1).getP1().getX() && lineList.get(0).getP2().getY() == lineList.get(1).getP1().getY()){
lineList.remove(lineList.size() - 1);
lineList.add(new Line2D.Double(lineList.get(1).getP2(), lineList.get(0).getP1()));
}
else if(lineList.get(0).getP1().getX() == lineList.get(1).getP2().getX() && lineList.get(0).getP1().getY() == lineList.get(1).getP2().getY()){
lineList.remove(lineList.size() - 1);
lineList.add(new Line2D.Double(lineList.get(0).getP2(), lineList.get(1).getP1()));
}else if(lineList.get(0).getP2().getX() == lineList.get(1).getP2().getX() && lineList.get(0).getP2().getY() == lineList.get(1).getP2().getY()){
lineList.remove(lineList.size() - 1);
Line2D.Double temp = lineList.remove(lineList.size() - 1);
lineList.add(new Line2D.Double(temp.getP2(), temp.getP1()));
lineList.add(new Line2D.Double(lineList.get(1).getP2(), lineList.get(0).getP1()));
}
}
//5: 2.1,1 1,1 2,1 3,3 2,3 //合拼俩个线段
private static Line2D.Double merge(Line2D.Double line1, Line2D.Double line2){
if(line1.x1 == line2.x1 && line1.y1 == line2.y1){
if(isOnLine(new double[]{line1.x2, line1.y2}, line2.getP1(), line2.getP2())){
return line2;
}else if(isOnLine(new double[]{line2.x2, line2.y2}, line1.getP1(), line1.getP2())){
return line1;
}
return new Line2D.Double(line1.x2, line1.y2, line2.x2, line2.y2);
}
else if(line1.x1 == line2.x2 && line1.y1 == line2.y2){
if(isOnLine(new double[]{line1.x2, line1.y2}, line2.getP1(), line2.getP2())){
return line2;
}else if(isOnLine(new double[]{line2.x1, line2.y1}, line1.getP1(), line1.getP2())){
return line1;
}
return new Line2D.Double(line1.x2, line1.y2, line2.x1, line2.y1);
}
else if(line1.x2 == line2.x1 && line1.y2 == line2.y1){
if(isOnLine(new double[]{line1.x1, line1.y1}, line2.getP1(), line2.getP2())){
return line2;
}else if(isOnLine(new double[]{line2.x2, line2.y2}, line1.getP1(), line1.getP2())){
return line1;
}
return new Line2D.Double(line1.x1, line1.y1, line2.x2, line2.y2);
}else{
if(isOnLine(new double[]{line1.x1, line1.y1}, line2.getP1(), line2.getP2())){
return line2;
}else if(isOnLine(new double[]{line2.x1, line2.y1}, line1.getP1(), line1.getP2())){
return line1;
}
return new Line2D.Double(line1.x1, line1.y1, line2.x1, line2.y1);
}
} //得到四边形周长
static double getPerimeter(List<double[]> list) {
List<Line2D.Double> lineList = getLineList(list);
double res = 0.0;
for (int i = 0; i < lineList.size(); i++) {
res += Point.distance(lineList.get(i).getX1(), lineList.get(i).getY1(), lineList.get(i).getX2(), lineList.get(i).getY2());
}
return res;
} //是否为凸多边形
//四边形的面积
static boolean isConvexPolygon(List<Line2D.Double> lineList) {
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
double t1 = (p4.getX() - p1.getX()) * (p2.getY() - p1.getY()) - (p4.getY() - p1.getY()) * (p2.getX() - p1.getX());
double t2 = (p1.getX() - p2.getX()) * (p3.getY() - p2.getY()) - (p1.getY() - p2.getY()) * (p3.getX() - p2.getX());
double t3 = (p2.getX() - p3.getX()) * (p4.getY() - p3.getY()) - (p2.getY() - p3.getY()) * (p4.getX() - p3.getX());
double t4 = (p3.getX() - p4.getX()) * (p1.getY() - p4.getY()) - (p3.getY() - p4.getY()) * (p1.getX() - p4.getX());
return t1 * t2 * t3 * t4 > 0; // if t1 * t2 < 0 and t1*t4< 0:
// return t1
// if t1 * t2 < 0 and t2*t3< 0:
// return t2
// if t2 * t3 < 0 and t3*t4< 0:
// return t3
// if t3 * t4 < 0 and t4*t1< 0:
// return t4
} //得到四边形的面积
static double getQuadrilateralArea(List<Line2D.Double> lineList) {
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
if (isConvexPolygon(lineList)) {
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
double t1 = (p4.getX() - p1.getX()) * (p2.getY() - p1.getY()) - (p4.getY() - p1.getY()) * (p2.getX() - p1.getX());
double t2 = (p1.getX() - p2.getX()) * (p3.getY() - p2.getY()) - (p1.getY() - p2.getY()) * (p3.getX() - p2.getX());
double t3 = (p2.getX() - p3.getX()) * (p4.getY() - p3.getY()) - (p2.getY() - p3.getY()) * (p4.getX() - p3.getX());
double t4 = (p3.getX() - p4.getX()) * (p1.getY() - p4.getY()) - (p3.getY() - p4.getY()) * (p1.getX() - p4.getX()); if (t1 * t2 < 0 && t1 * t4 < 0){
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
if (t1 * t2 < 0 && t2 * t3 < 0){
return getTriangleArea(p1, p2, p4) + getTriangleArea(p2, p3, p4);
}
if (t2 * t3 < 0 && t3 * t4 < 0) {
return getTriangleArea(p1, p2, p3) + getTriangleArea(p1, p3, p4);
}
if (t3 * t4 < 0 && t4 * t1 < 0) {
return getTriangleArea(p1, p2, p4) + getTriangleArea(p2, p3, p4);
}
return -1;
} //三角形面积
static double getTriangleArea(Point2D p1, Point2D p2, Point2D p3) {
double a = Point.distance(p1.getX(), p1.getY(), p2.getX(), p2.getY());
double b = Point.distance(p2.getX(), p2.getY(), p3.getX(), p3.getY());
double c = Point.distance(p1.getX(), p1.getY(), p3.getX(), p3.getY());
double s = (a + b + c) / 2;
double res = Math.sqrt(s * (s - a) * (s - b) * (s - c));
return res;
} //得到交点数量
static int intersectionCnt(Line2D line, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D lp1 = line.getP1();
Point2D lp2 = line.getP1();
return getIntersection(lp1, lp2, p1, p2) + getIntersection(lp1, lp2, p2, p3) + getIntersection(lp1, lp2, p3, p1);
} // 求两条平面直线的交点
private static Point2D.Double intersectPoint(Line2D line1, Line2D line2) {
Point2D a = line1.getP1();
Point2D b = line1.getP2();
Point2D c = line2.getP1();
Point2D d = line2.getP2(); double deita = (b.getX() - a.getX()) * (c.getY() - d.getY()) - (d.getX() - c.getX()) * (a.getY() - b.getY());
double x = (c.getY() * d.getX() - c.getX() * d.getY()) * (b.getX() - a.getX())
- (a.getY() * b.getX() - a.getX() * b.getY()) * (d.getX() - c.getX());
x /= deita;
double y = (a.getY() * b.getX() - a.getX() * b.getY()) * (c.getY() - d.getY())
- (c.getY() * d.getX() - c.getX() * d.getY()) * (a.getY() - b.getY());
y /= deita;
return new Point2D.Double(x, y);
} //得到被划分后的三角形的面积
static double[] getTriangleAreaForDivided(Line2D line, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1(); Point2D lp1 = line.getP1();
Point2D lp2 = line.getP2(); Point2D np1 = null, np2 = null;
if(getIntersection(lp1, lp2, p1, p2) == 1){
np1 = intersectPoint(line, lineList.get(0));
}
if (getIntersection(lp1, lp2, p2, p3) == 1){
if (np1 == null) np1 = intersectPoint(line, lineList.get(1));
else np2 = intersectPoint(line, lineList.get(1));
}
if(getIntersection(lp1, lp2, p3, p1) == 1){
if (np2 == null) np2 = intersectPoint(line, lineList.get(2));
} double[] result = new double[2];
List<Line2D.Double> tempLineList = null; List<double[]> pList = new ArrayList<>();
if(getIntersection(lp1, lp2, p1, p2) == 1 && getIntersection(lp1, lp2, p2, p3) == 1){
pList.add(new double[]{p1.getX(), p1.getY()});
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
tempLineList = getLineList(pList);
result[0] = getQuadrilateralArea(tempLineList);
result[1] = getTriangleArea(np1, np2, p2);
}
else if(getIntersection(lp1, lp2, p1, p2) == 1 && getIntersection(lp1, lp2, p1, p3) == 1){
pList.add(new double[]{p2.getX(), p2.getY()});
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
tempLineList = getLineList(pList);
result[0] = getQuadrilateralArea(tempLineList);
result[1] = getTriangleArea(np1, np2, p1);
}else{
pList.add(new double[]{p1.getX(), p1.getY()});
pList.add(new double[]{p2.getX(), p2.getY()});
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
tempLineList = getLineList(pList);
result[0] = getQuadrilateralArea(tempLineList);
result[1] = getTriangleArea(np1, np2, p3);
} return result;
} //得到划分后四边形的面积
static double[] getDivideAreaForQuadrilateral(Line2D line, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1(); Point2D lp1 = line.getP1();
Point2D lp2 = line.getP2(); Point2D np1 = null, np2 = null;
if(getIntersection(lp1, lp2, p1, p2) == 1){
np1 = intersectPoint(line, lineList.get(0));
}
if (getIntersection(lp1, lp2, p2, p3) == 1){
if (np1 == null) np1 = intersectPoint(line, lineList.get(1));
else np2 = intersectPoint(line, lineList.get(1));
}
if(getIntersection(lp1, lp2, p3, p4) == 1){
if (np1 == null) np1 = intersectPoint(line, lineList.get(2));
else np2 = intersectPoint(line, lineList.get(2));
}
if(getIntersection(lp1, lp2, p4, p1) == 1){
if (np2 == null) np2 = intersectPoint(line, lineList.get(3));
} double[] result = new double[2];
List<double[]> pList = new ArrayList<>();
List<Line2D.Double> tempLineList = null; if(getIntersection(lp1, lp2, p1, p4) == 1 && getIntersection(lp1, lp2, p2, p3) == 1){
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p1.getX(), p1.getY()});
pList.add(new double[]{p2.getX(), p2.getY()});
tempLineList = getLineList(pList);
result[0] = getQuadrilateralArea(tempLineList);
pList.remove(pList.size() - 1);
pList.remove(pList.size() - 1);
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{p4.getX(), p4.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList);
}
else if(getIntersection(lp1, lp2, p1, p2) == 1 && getIntersection(lp1, lp2, p3, p4) == 1){
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p1.getX(), p1.getY()});
pList.add(new double[]{p4.getX(), p4.getY()});
tempLineList = getLineList(pList);
result[0] = getQuadrilateralArea(tempLineList);
pList.remove(pList.size() - 1);
pList.remove(pList.size() - 1);
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{p2.getX(), p2.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList);
}
else if(getIntersection(lp1, lp2, p1, p4) == 1 && getIntersection(lp1, lp2, p1, p2) == 1){
result[0] = getTriangleArea(p1, np1, np2);
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p4.getX(), p4.getY()});
pList.add(new double[]{p2.getX(), p2.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList) + getTriangleArea(p2, p3, p4);
}
else if(getIntersection(lp1, lp2, p1, p2) == 1 && getIntersection(lp1, lp2, p2, p3) == 1){
result[0] = getTriangleArea(p2, np1, np2);
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{p1.getX(), p1.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList) + getTriangleArea(p1, p3, p4);
}
else if(getIntersection(lp1, lp2, p3, p4) == 1 && getIntersection(lp1, lp2, p2, p3) == 1){
result[0] = getTriangleArea(p3, np1, np2);
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p4.getX(), p4.getY()});
pList.add(new double[]{p2.getX(), p2.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList) + getTriangleArea(p1, p2, p4);
}
else if(getIntersection(lp1, lp2, p1, p4) == 1 && getIntersection(lp1, lp2, p3, p4) == 1){
result[0] = getTriangleArea(p4, np1, np2);
pList.add(new double[]{np1.getX(), np1.getY()});
pList.add(new double[]{np2.getX(), np2.getY()});
pList.add(new double[]{p3.getX(), p3.getY()});
pList.add(new double[]{p1.getX(), p1.getY()});
tempLineList = getLineList(pList);
result[1] = getQuadrilateralArea(tempLineList) + getTriangleArea(p1, p2, p3);
} return result;
} //判斷一条直线是否与四边形共线
static boolean isLineOnQuadrilateral(Line2D line, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1(); Point2D lp1 = line.getP1();
Point2D lp2 = line.getP2();
double lSlope = italic(lp1, lp2); int intersection = getIntersection(lp1, lp2, p1, p2) + getIntersection(lp1, lp2, p2, p3) + getIntersection(lp1, lp2, p3, p4) + getIntersection(lp1, lp2, p4, p1);
if(intersection == 0){
return false;
}else if(intersection == 1){
return lSlope == italic(p1, p2) && getIntersection(lp1, lp2, p1, p2) == 1 ||
lSlope == italic(p2, p3) && getIntersection(lp1, lp2, p2, p3) == 1 ||
lSlope == italic(p3, p4) && getIntersection(lp1, lp2, p3, p4) == 1 ||
lSlope == italic(p4, p1) && getIntersection(lp1, lp2, p4, p1) == 1;
}else if(intersection == 2){
return lSlope == italic(p1, p2) && getIntersection(lp1, lp2, p1, p2) == 1 ||
lSlope == italic(p2, p3) && getIntersection(lp1, lp2, p2, p3) == 1 ||
lSlope == italic(p3, p4) && getIntersection(lp1, lp2, p3, p4) == 1 ||
lSlope == italic(p4, p1) && getIntersection(lp1, lp2, p4, p1) == 1;
}else if(intersection == 3){
return lSlope == italic(p1, p2) && getIntersection(lp1, lp2, p1, p2) == 1 ||
lSlope == italic(p2, p3) && getIntersection(lp1, lp2, p2, p3) == 1 ||
lSlope == italic(p3, p4) && getIntersection(lp1, lp2, p3, p4) == 1 ||
lSlope == italic(p4, p1) && getIntersection(lp1, lp2, p4, p1) == 1;
}
return false;
} //判斷一条直线是否与三角形共线
static boolean isLineOnTriangle(Line2D line, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1(); Point2D lp1 = line.getP1();
Point2D lp2 = line.getP2();
double lSlope = italic(lp1, lp2); int intersection = getIntersection(lp1, lp2, p1, p2) + getIntersection(lp1, lp2, p2, p3) + getIntersection(lp1, lp2, p3, p1);
if(intersection == 0){
return false;
}else if(intersection == 1){
return lSlope == italic(p1, p2) && getIntersection(lp1, lp2, p1, p2) == 1 ||
lSlope == italic(p2, p3) && getIntersection(lp1, lp2, p2, p3) == 1 ||
lSlope == italic(p1, p3) && getIntersection(lp1, lp2, p1, p3) == 1;
}else if(intersection == 2){
return lSlope == italic(p1, p2) && getIntersection(lp1, lp2, p1, p2) == 1 ||
lSlope == italic(p2, p3) && getIntersection(lp1, lp2, p2, p3) == 1 ||
lSlope == italic(p1, p3) && getIntersection(lp1, lp2, p1, p3) == 1;
}else{
return lSlope == italic(p1, p2) || lSlope == italic(p2, p3) || lSlope == italic(p1, p3);
} } //是否相交,是就加一
static int getIntersection(Point2D p1, Point2D p2, Point2D p3, Point2D p4){
return Line2D.linesIntersect(p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY(), p4.getX(), p4.getY()) ? 1 : 0;
} //判断一个点是在否多边形内部
static boolean isInternal(Point2D point, List<Line2D.Double> lineList){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
// 三角形
if(lineList.size() == 3){
double area = getTriangleArea(p1, p2, p3);
double internalArea = getTriangleArea(point, p1, p2) + getTriangleArea(point, p2, p3) + getTriangleArea(point, p3, p1);
return rfDouble(area) == rfDouble(internalArea);
}
//四边形
else{
Point2D p4 = lineList.get(3).getP1();
double area = getQuadrilateralArea(lineList); double internalArea = getTriangleArea(point, p1, p2) + getTriangleArea(point, p2, p3) + getTriangleArea(point, p3, p4) + getTriangleArea(point, p4, p1);
return rfDouble(area) == rfDouble(internalArea);
}
} //double运算
public static double rfDouble(double d){
return new BigDecimal(d).setScale(2, RoundingMode.HALF_UP).doubleValue();
} //判断一个点是否多边形的边上
public static boolean isOnLine(double[] point, List<Line2D.Double> lineList) {
if (lineList.size() == 3) {
return isOnLine(point, lineList.get(0).getP1(), lineList.get(0).getP2()) || isOnLine(point, lineList.get(1).getP1(), lineList.get(1).getP2())
|| isOnLine(point, lineList.get(2).getP1(), lineList.get(2).getP2());
} else if (lineList.size() == 4) {
return isOnLine(point, lineList.get(0).getP1(), lineList.get(0).getP2()) || isOnLine(point, lineList.get(1).getP1(), lineList.get(1).getP2())
|| isOnLine(point, lineList.get(2).getP1(), lineList.get(2).getP2()) || isOnLine(point, lineList.get(3).getP1(), lineList.get(3).getP2());
}
return false;
} //是否在线段上
public static boolean isOnLine(double[] point, Point2D point1, Point2D point2) {
return Point2D.distance(point1.getX(), point1.getY(), point2.getX(),point2.getY()) ==
Point2D.distance(point1.getX(), point1.getY(), point[0],point[1]) +
Point2D.distance(point[0], point[1], point2.getX(),point2.getY());
} //是否在直线上
public static boolean isOnLine2(double[] point, Point2D point1, Point2D point2){
double x = point[0];
double y = point[1];
boolean pdline = (x - point1.getX()) * (point1.getY() - point2.getY()) == (point1.getX() - point2.getX())
* (y - point1.getY());
return pdline;
} //判断一个点在一条线段上 (a,b)是这个点
public static boolean ifPointOnSegment(double[] point, Point2D linePoint1, Point2D linePoint2) { double a = point[0];
double b = point[1];
double x1 = linePoint1.getX();
double y1 = linePoint1.getY();
double x2 = linePoint2.getX();
double y2 = linePoint2.getY();
boolean bl = false;
double p = (y2 - y1) / (x2 - x1);
if (p <= 0) {
if (x1 > x2) {
if (y1 > y2) {
if (a > x2 && a < x1 && b >= y2 && b <= y1) {
bl = true;
}
} else {
if (a > x2 && a < x1 && b >= y1 && b <= y2) {
bl = true;
}
}
} else {
if (y1 > y2) {
if (a > x1 && a < x2 && b >= y2 && b <= y1) {
bl = true;
}
} else {
if (a > x1 && a < x2 && b >= y1 && b <= y2) {
bl = true;
}
}
}
} else {
if (x1 > x2) {
if (y1 > y2) {
if (a > x2 && a < x1 && b > y2 && b < y1) {
bl = true;
}
} else {
if (a > x2 && a < x1 && b > y1 && b < y2) {
bl = true;
}
}
} else {
if (y1 > y2) {
if (a > x1 && a < x2 && b > y2 && b < y1) {
bl = true;
}
} else {
if (a > x1 && a < x2 && b > y1 && b < y2) {
bl = true;
}
}
}
}
boolean coincide = (point[0] == linePoint1.getX() && point[1] == linePoint1.getY()) ||
(point[0] == linePoint2.getX() && point[1] == linePoint2.getY());
return bl || coincide;
} //是否为正方形
static boolean isSquare(List<double[]> list) {
return isDiamond(list) && isRectangle(list);
} //是否为矩形
static boolean isRectangle(List<double[]> list) {
if (!isParallelogram(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
double mx = (p1.getX() + p2.getX() + p3.getX() + p4.getX()) / 4;
double my = (p1.getY() + p2.getY() + p3.getY() + p4.getY()) / 4;
return rfDouble(Point.distance(p1.getX(), p2.getY(), mx, my)) == rfDouble(Point.distance(p2.getX(), p3.getY(), mx, my)) &&
rfDouble(Point.distance(p2.getX(), p3.getY(), mx, my)) == rfDouble(Point.distance(p3.getX(), p4.getY(), mx, my)) &&
rfDouble(Point.distance(p3.getX(), p4.getY(), mx, my)) == rfDouble(Point.distance(p4.getX(), p1.getY(), mx, my)) &&
rfDouble(Point.distance(p4.getX(), p1.getY(), mx, my)) == rfDouble(Point.distance(p1.getX(), p2.getY(), mx, my));
// return ((lineList.get(0).y1 - lineList.get(0).y2) / (lineList.get(0).x1 - lineList.get(0).x2))
// * ((lineList.get(1).y1 - lineList.get(1).y2) / (lineList.get(1).x1 - lineList.get(1).x2)) == -1 ;
} //2: 2.3,1.1 1.2,1.1 1.2,3.2 2.3,3.2 //是否是菱形
static boolean isDiamond(List<double[]> list) {
if (!isParallelogram(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
// System.out.println(lineList.size());
// for (Line2D.Double aDouble : lineList) {
// System.out.println(aDouble.getP1() +" : " + aDouble.getP2());
// }
return Point.distance(lineList.get(0).getX1(), lineList.get(0).getY1(), lineList.get(0).getX2(), lineList.get(0).getY2()) ==
Point.distance(lineList.get(1).getX1(), lineList.get(1).getY1(), lineList.get(1).getX2(), lineList.get(1).getY2());
} //是否是平行四边形
static boolean isParallelogram(List<double[]> list) {
if (!isQuadrilateral(list)) return false;
List<Line2D.Double> lineList = getLineList(list);
return Point2D.distance(lineList.get(0).getX1(), lineList.get(0).getY1(), lineList.get(0).getX2(), lineList.get(0).getY2()) ==
Point2D.distance(lineList.get(2).getX1(), lineList.get(2).getY1(), lineList.get(2).getX2(), lineList.get(2).getY2());
} //判断是否为三角形
static boolean isTriangle(LinkedList<Line2D.Double> lineList, Line2D stop){
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
if(italic(p1, p2) == italic(p2, p3)) return false;
lineList.addLast(lineList.pollFirst());
//循环了n次,返回true
if(lineList.getFirst() == stop){
return true;
}
return isTriangle(lineList, stop);
} //是否为四边行
static boolean isQuadrilateral(List<double[]> list){
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
return !((italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3))
|| (italic(p1, p2) == italic(p2, p3)));
} //是否为五边行
static boolean isPentagon(List<double[]> list){
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
Point2D p5 = lineList.get(4).getP1(); return !(prime_zx(p1, p2,p3)||prime_zx(p2, p3,p4)||prime_zx(p3, p4,p5)||prime_zx(p4, p5,p1)||prime_zx(p5, p1,p2)); } //求五边形周长
static double alldistance(List<double[]> list){
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
Point2D p5 = lineList.get(4).getP1();
double distance=0.0;
distance=finddis(p1,p2)+finddis(p3,p2)+finddis(p3,p4)+finddis(p4,p5)+finddis(p5,p1); return distance; }
static double getarea(List<double[]> list){
List<Line2D.Double> lineList = getLineList(list);
Point2D p1 = lineList.get(0).getP1();
Point2D p2 = lineList.get(1).getP1();
Point2D p3 = lineList.get(2).getP1();
Point2D p4 = lineList.get(3).getP1();
Point2D p5 = lineList.get(4).getP1();
double distance=0.0;
distance=finddis(p1,p2)+finddis(p3,p2)+finddis(p3,p4)+finddis(p4,p5)+finddis(p5,p1); return distance; }
static double finddis(Point2D p1, Point2D p2) {
double dis=Math.sqrt((p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY()));
return dis;
} /*
* 输入:三个坐标
* 处理:判断是否成一条直线
* 输出: true false
* */ public static boolean prime_zx(Point2D a,Point2D b,Point2D c) {
if (((c.getY() - b.getY()) * (c.getX() - a.getX())==(c.getY() - a.getY()) * (c.getX() - b.getX())))
return false;
else
return true;
} //斜率
static double italic(Point2D p1, Point2D p2){
return (p1.getX() - p2.getX()) / (p1.getY() - p2.getY());
} //是否为重合
static boolean isPointsCoincide(List<double[]> list) {
int n = list.size();
list = notCoincidePointsCnt(list);
return list.size() < n;
} //返回两点间的距离
static double getDistance(int index1, int index2, List<double[]> list) {
return Point.distance(list.get(index1)[0], list.get(index1)[1], list.get(index2)[0], list.get(index2)[1]);
} //得到非对角线边的集合
public static List<Line2D.Double> getLineList(List<double[]> list) {
List<Line2D.Double> lineList = new ArrayList<>();
if(list.size() == 2){
return null;
}
if(list.size() == 3){
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(0)[0], list.get(0)[1]));
return lineList;
}
if (!Line2D.linesIntersect(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1])) {
if(!Line2D.linesIntersect(list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1], list.get(0)[0], list.get(0)[1], list.get(3)[0], list.get(3)[1])){
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(0)[0], list.get(0)[1]));
}else{
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(0)[0], list.get(0)[1]));
}
} else {
if(!Line2D.linesIntersect(list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1], list.get(0)[0], list.get(0)[1], list.get(1)[0], list.get(1)[1])){
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(0)[0], list.get(0)[1]));
}else{
lineList.add(new Line2D.Double(list.get(0)[0], list.get(0)[1], list.get(2)[0], list.get(2)[1]));
lineList.add(new Line2D.Double(list.get(2)[0], list.get(2)[1], list.get(1)[0], list.get(1)[1]));
lineList.add(new Line2D.Double(list.get(1)[0], list.get(1)[1], list.get(3)[0], list.get(3)[1]));
lineList.add(new Line2D.Double(list.get(3)[0], list.get(3)[1], list.get(0)[0], list.get(0)[1]));
}
}
return lineList;
} //得到去重后的集合
static List<double[]> notCoincidePointsCnt(List<double[]> list) {
List<double[]> temp = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
int j = i + 1;
for (; j < list.size(); j++) {
if (list.get(i)[0] == list.get(j)[0] && list.get(i)[1] == list.get(j)[1]) break;
}
if(j == list.size()){
temp.add(list.get(i));
}
}
// for (double[] doubles : list) {
// System.out.println(Arrays.toString(doubles));
// }
return temp;
} //打印坐标数量错误信息
public static boolean printCntError(int real, int expect) {
if (real != expect) System.out.println("wrong number of points");
return real == expect;
} //获得选项
public static List<double[]> getSelection(String str, int start) {
List<double[]> list = new ArrayList<>();
int index = 0;
int n = str.length();
StringBuffer sbf = null;
for (int i = start; i < n; ) {
//空格就跳过
if (str.charAt(i) == ' ') {
i++;
continue;
}
sbf = new StringBuffer();
list.add(new double[2]);
//第一个坐标遇到’,‘停止
while (i < n && str.charAt(i) != ',') {
sbf.append(str.charAt(i));
i++;
}
//不是合法的数字或者没有对应的y坐标就报错
if (i >= n || !isNumeric(sbf.toString())) {
System.out.println("Wrong Format");
return null;
} else list.get(index)[0] = Double.parseDouble(sbf.toString());
i++;
sbf = new StringBuffer();
//第一个坐标遇到空格停止
while (i < n && str.charAt(i) != ' ') {
sbf.append(str.charAt(i));
i++;
}
//不是合法的数字就报错
if (!isNumeric(sbf.toString())) {
System.out.println("Wrong Format");
return null;
} else list.get(index++)[1] = Double.parseDouble(sbf.toString());
}
return list;
} //判断是否为数字
public static boolean isNumeric(String str) {
if (str.length() < 1) return false;
if (str.charAt(0) == '-') {
str = str.substring(1, str.length());
}
if (str.length() < 1) return false;
if (str.charAt(0) == '0' && str.length() == 1) return true;
int dotCnt = 0;
if (str.charAt(0) == '.' || str.charAt(str.length() - 1) == '.') return false;
if (str.charAt(0) == '0' && (str.length() < 3 || str.charAt(1) != '.')) return false;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '.') {
if (dotCnt > 0) return false;
dotCnt++;
} else if (str.charAt(i) < '0' || str.charAt(i) > '9') return false;
}
return true;
}
} /*
return (getDistance(0, 1, list) == getDistance(2,3, list)
&& getDistance(1, 2, list) == getDistance(0,3, list)) || (getDistance(0, 3, list) == getDistance(2,1, list)
&& getDistance(0, 2, list) == getDistance(1,3, list)) || (getDistance(0, 2, list) == getDistance(1,3, list)
&& getDistance(1, 2, list) == getDistance(0,3, list)) || (getDistance(0, 1, list) == getDistance(2,3, list)
&& getDistance(0, 2, list) == getDistance(1,3, list)) || (getDistance(0, 3, list) == getDistance(2,1, list)
&& getDistance(3, 2, list) == getDistance(0,1, list)) || (getDistance(0, 2, list) == getDistance(1,3, list)
&& getDistance(3, 2, list) == getDistance(0,1, list)) ; */
许多五边形的计算和判断不太会,特别时直线与多边形的交点判断与切割面积的计算,许多判断比如三边形、四边形、五边形的凹凸多边形判断太多重复,不简洁,输入格式和错误输入的判断也不完善,代码很长。
三、踩坑心得
1 Scanner input = new Scanner(System.in);
2 float kg = input.nextFloat();
3 float m = input.nextFloat();
4 double newkg,newm;
5 newkg = kg/(0.45359237);
6 newm = m/(0.0254);
7 System.out.println((float)newkg+" "+(float)newm);
- 数据浮点数类型不同时,需看输出需求进行强制转换。
- 要注意题目要求,充分理解题目再做,对于题目中的一些不理解的名词要查询,比如第二次作业中的7-2中的奇偶校验。
- 要创建类来完成代码所需要的功能,只用一个main来完成所有功能的话会造成代码非常冗杂,并且可读性较低
1 import java.util.Scanner;
2 public class Main {
3
4
5 public static void main(String[] args) {
6
7 Scanner sc=new Scanner(System.in);
8 double x1,x2,y1,y2;
9 String str;
10 str=sc.nextLine();
11 String[] StrArray = str.split(",| ");
12
13 try
14 {
15 x1=Double.valueOf(StrArray[0]);
16 y1=Double.valueOf(StrArray[1]);
17 x2=Double.valueOf(StrArray[2]);
18 y2=Double.valueOf(StrArray[3]);
19 for (int i = 4; i < StrArray.length; i++) {
20 double t=Double.valueOf(StrArray[i]);
21 }
22 if(StrArray.length>4)
23 {
24 System.out.println("wrong number of points");
25 }
26 else
27 {
28 double d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
29 d=Math.sqrt(d);
30 System.out.println(d);
31 }
32 }catch(Exception e)
33 {
34 System.out.println("Wrong Format");
35 }
36
37 }
38
39 }
四、总结
- 通过这三次题目集,对Java的实际应用在书本知识之外有了一些初步的认识,同时,通过实际练习,对于Java的一些简单的输入输出、简单的逻辑应用、一些数学运算以及一些特殊的函数和方法的应用更加熟练。
- 在做题目的过程中,通过查找资料,发现了许多新的方法,比如try catch。
- 同时,在做题过程中也更加清楚的了解到自己的不足之处,在哪一方面不太清楚,比如正则表达式就不会用,查找资料一时也不会用,需要多加学习。
- 希望老师在每次题目集时间截止之后能把题目集中比较难的题目集的答案或者思路发出来让我们自己进行对照。
- 继承与多态需要多学习,多参考模板,思考自己的类的设计有什么问题,为什么要那样设计。
- 设计类的时候要把功能细化,写代码前先画类图构思再下手,写代码时要注意写注释,不然过一段时间可能要画许多时间去理解自己写了什么
- 一定要多写多练才能发现自己的不足与错误。
面向对象程序设计第二次blog的更多相关文章
- 面向对象程序设计 第二次作业<1>
Github链接:https://github.com/zora02/object-oriented/tree/master/1001.A%2BB%20Format%20(20) 一.解题 题目 解题 ...
- 程序设计第二次作业<1>
面向对象程序设计第二次作业<1> Github 链接:https://github.com/Wasdns/object-oriented 题目: <1>第一次尝试 我立马认识到 ...
- 2017面向对象程序设计(Java)第二周学习总结
2017面向对象程序设计(Java)第二周学习总结 直系学妹学弟们好!额...不要问我为什么把学妹放前面,我也不知道!我只是你们和蔼可亲的学长一枚而已.也不要问为什么是第二周学习总结而不是第一周,因为 ...
- 201771010126 王燕《面向对象程序设计(java)》第二周学习总结
201771010126 王燕<面向对象程序设计(java)>第二周学习总结 一.理论知识学习部分 3.1j简单 的java应用程序 标识符由字母.下划线.美元符号和数字组成, 且第一个符 ...
- 王之泰201771010131《面向对象程序设计(java)》第二周学习总结
王之泰201771010131<面向对象程序设计(java)>第二周学习总结 第一部分:理论知识学习部分 第三章 第三章内容主要为Java语言的基础语法,主要内容如下 1.基础知识 1.1 ...
- 李清华201772020113《面向对象程序设计(java)》第二周学习总结
李清华201772020113<面向对象程序设计(java)>第二周学习总结 第一部分 理论知识 第三章 本章主要讲了java基本知识中的标识符,关键字,注释,以及数据类型,变量,运算符, ...
- java的第二个实验——JAVA面向对象程序设计
java的第二个实验——JAVA面向对象程序设计 北京电子科技学院 实 验 报 告 课程:Java程序设计 班级:1352 姓名:林涵锦 学号:20135213 成绩: ...
- 20155323刘威良第二次实验 Java面向对象程序设计
20155323刘威良第二次实验 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 ...
- 201871010116-祁英红《面向对象程序设计(java)》第二周学习总结
博文正文开头格式:(3分) 项目 内容 <面向对象程序设计(java)> https://home.cnblogs.com/u/nwnu-daizh/ 这个作业的要求在哪里 https:/ ...
- 扎西平措 201571030332 《面向对象程序设计 (JAVA)》第二周 学习总结
面向对象程序设计 (JAVA)>第二周 学习总结 项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这 ...
随机推荐
- All in one入门之All in one和三种PVE、ESXI、Windows Server方案
前言 All in one 前段时间,在某多多上花了446大洋弄了一台J4125准系统小主机,再花了一点钱买个杂牌msata和"全新"三星内存条,入坑了All in one. Al ...
- [数据与分析可视化] D3入门教程3-d3中的数据操作
d3.js入门教程3-d3.js中的数据操作 文章目录 d3.js入门教程3-d3.js中的数据操作 数学操作 对象和数组 过滤Filtering 排序Sorting 映射group 循环loop 重 ...
- Mybatis用List接收返回值
Mybatis 用 List 接收返回值 以 List<Map<String, Object>> 为例 1.XML内 resultType 为单条记录对应类型,设置成 java ...
- python之路32 网络并发线程方法 线程池 协程
多进程实现TCP服务端并发 服务端: import socket from multiprocessing import Process def get_server(): server = sock ...
- Java基础篇——JUC初步
1.基础知识 java默认的两个线程:Main线程+GC守护线程 java并不能开启线程,需要调用底层用c语言写的本地方法 wait和sleep的区别: wait方法会释放线程锁,并且只能在同步代码块 ...
- (11)go-micro微服务雪花算法
目录 一 雪花算法介绍 二 雪花算法优缺点 三 雪花算法实现 四 最后 一 雪花算法介绍 雪花算法是推特开源的分布式ID生成算法,用于在不同的机器上生成唯一的ID的算法. 该算法生成一个64bit的数 ...
- Windows 安装 Anaconda
下载 anaconda 官网 https://repo.anaconda.com/archive/ 国内镜像 https://mirrors.bfsu.edu.cn/anaconda/archive/ ...
- 序列化框架-Kyro简述
网上有很多资料说 Kryo 只能在 Java 上使用,这点是不对的,事实上除 Java 外,Scala 和 Kotlin 这些基于 JVM 的语言同样可以使用 Kryo 实现序列化. 1.使用方法 ( ...
- angular 父组件调用子组件方法---以及组件跨模块使用方法
如果要在父组件调用子组件 可以这样子 @ViewChild('mySun', { static: false }) mySun: MySunComponent; 使用方法: let res=this. ...
- C# 10 Lambda 语法的改进
C# 10 包括了对 Lambda 表达式的处理方式的许多改进: Lambda 表达式可以具有自然类型,这使编译器可从 Lambda 表达式或方法组推断委托类型. 如果编译器无法推断返回类型,Lamb ...