一、前言
题目集四题目量不大,共三题,分别需要运用到正则表达式去判断每行输入的数字,构建多个类来实现凸四边形的计算实现其功能,也需要运用到正则表达式,以及构建一个银行业务类实现对应的功能。在这三题中,第一和第三题较简单,第二题较难,原因在于凸四边形的判断和计算较为繁琐,它是在题目集三三角形的计算基础上升级并增加了选项。
题目集五题目量也不大,共两题,两题都是五边形的设计,对于我来说算是十分困难了。根据我现在的水平只能完成前2-3个选项,也是在题目集四的基础上进行的难度的升级,从输入5个点到输入10个点的复杂的计算不仅涉及到了类的封装继承与多态的知识,还考察了数学的逻辑计算构思,算得上是很难了。
期中考试共三题,题目从类的设计到继承与多态再到容器类,总体来说,相对于PTA题目集的题目简单很多。三个题目循序渐进,由易到难,而且都是在前一题的基础上改动的,前两题难度还较为简单,就是到后面的容器类由于知识掌握不完全没有成功做出来。
三个题目从点到线,线到面,维度的变化,从一维到二维的转化到二维到三维的实现也是一个不断变难的过程。
二、设计与分析
1、7-2 点线形系列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"。
我的源码:
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();
if(!s.matches("^[1-5][:](([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))[,]([+-]?(0|(0\\.\\d+)|[1-9][0-9]*(\\.\\d+)?))\\s?)+$")){
System.out.printf("Wrong Format");
System.exit(0);
}
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;
}
}
public static boolean check(String s){
return s.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$");
}
// 四边形、平行四边形
public static void handle1(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
System.out.println(t.isQuadrilateral() + " " + t.isParallelogram());
}
// 菱形、矩形、正方形
public static void handle2(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
if(!t.isQuadrilateral()) {
System.out.println("not a quadrilateral");
}
else
{
System.out.println(t.isLozenge() + " " + t.isEquilateralTriangle() + " " + t.isRightTriangle());
}
}
// 凹凸四边形
public static void handle3(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 4);
Quadrilateral t = new Quadrilateral(ps.get(0), ps.get(1), ps.get(2), ps.get(3));
if(!t.isQuadrilateral()) {
System.out.println("not a quadrilateral");
}
else
{
t.isBump();
}
}
public static void handle4(ArrayList<Point> ps) {
System.out.println("not a quadrilateral or triangle");
}
public static void handle5(ArrayList<Point> ps) {
System.out.println("in the triangle");
}
}
class Point {
public double x;
public double y;
public Point() {
}
public Point(double x,double y) {
this.x=x;
this.y=y;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public double getX() {
return x;
}
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;
}
}
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);
}
}
class Quadrilateral{
private Point x;
private Point y;
private Point z;
private Point a;
public Quadrilateral(Point x, Point y, Point z,Point a) {
this.x = x;
this.y = y;
this.z = z;
this.a = a;
}
/* 判断x\y\z\a四个点的坐标是否能构成一个四边形 */
public boolean isQuadrilateral() {
double k1 = (this.x.getY() - this.y.getY()) / (this.x.getX() - this.y.getX());
double k2 = (this.x.getY() - this.z.getY()) / (this.x.getX() - this.z.getX());
double k3 = (this.x.getY() - this.a.getY()) / (this.x.getX() - this.a.getX());
double k4 = (this.y.getY() - this.z.getY()) / (this.y.getX() - this.z.getX());
double k5 = (this.y.getY() - this.a.getY()) / (this.y.getX() - this.a.getX());
if(k1==k2||k1==k3||k2==k3)
{
return false;
}
else
{
if(k4 == k5)
{
return false;
}
return true;
}
}
/* 判断是否平行四边形 */
public boolean isParallelogram() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
if(k1==k3&&k2==k4)
{
return true;
}
else
{
return false;
}
}
/* 获取四边形的周长 */
public double getPerimeter() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
return Math.sqrt(k1)+Math.sqrt(k2)+Math.sqrt(k3)+Math.sqrt(k4);
}
/* 判断是否菱形 */
public boolean isLozenge() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
if(k1==k2&&k2==k3&&k3==k4)
{
return true;
}
else
{
return false;
}
}
/* 判断是否矩形 */
public boolean isEquilateralTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k3&&k2==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}
/* 判断是否正方形 */
public boolean isRightTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k2&&k2==k3&&k3==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}
/* 判断是否凹四边形 还是凸四边形*/
public void isBump() {
double k1 = Math.sqrt(Math.pow(this.y.getX() - this.x.getX(), 2) + Math.pow(this.y.getY() - this.x.getY(), 2));
double k2 = Math.sqrt(Math.pow(this.z.getX() - this.a.getX(), 2) + Math.pow(this.z.getY() - this.a.getY(), 2));
double k3 = Math.sqrt(Math.pow(this.x.getX() - this.a.getX(), 2) + Math.pow(this.x.getY() - this.a.getY(), 2));
double k4 = Math.sqrt(Math.pow(this.y.getX() - this.z.getX(), 2) + Math.pow(this.y.getY() - this.z.getY(), 2));
double c =k1 + k2 + k3 + k4;
double s =0.5*Math.abs(x.x*y.y+y.x*z.y+z.x*a.y+a.x*x.y-y.x*x.y-z.x*y.y-a.x*z.y-x.x*a.y);
double t1 = (a.x-x.x)*(y.y-x.y)-(a.y-x.y)*(y.x-x.x);
double t2 = (x.x-y.x)*(z.y-y.y)-(x.y-y.y)*(z.x-y.x);
double t3 = (y.x-z.x)*(a.y-z.y)-(y.y-z.y)*(a.x-z.x);
double t4 = (z.x-a.x)*(x.y-a.y)-(z.y-a.y)*(x.x-a.x);
if( t1*t2*t3*t4 > 0)
{
System.out.printf("true %.3f %.1f",c,s);
System.exit(0);
}
else
{
System.out.printf("false %.3f %.1f",c,s);
System.exit(0);
}
}
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;
}
public Point getA() {
return a;
}
public void setA(Point z) {
this.z = a;
}
}
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);
}
}
public static void wrongChoice(String s) {
if (!s.matches("[1-5]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class ParseInput {
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;
}
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]));
}
}
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]);
return new Point(x, y);
}
}
题目分析:
类图如下:
度量分析:
首先判断是否为四边形,有两种情况,1:第一个坐标与第四个坐标构成的线段和第二个坐标与第三个坐标构成的线段相交时不构成四边形,2:第一个坐标与第二个坐标构成的线段和第三个坐标与第四个坐标构成的线段相交时不构成四边形。然后判断平行四边形,特征是对边相等且平行,利用这个可以轻松判断。菱形、矩形、正方形的判断其实和平行四边形的大同小异,菱形加一个四边相等,矩形加一个邻边互相垂直,正方形则是四边相等且邻边相互垂直。
踩坑心得:
①判断是否为凸四边形还要考虑输入的相邻坐标是否是四边形的相邻顶点
方法:设输入的四个坐标依次为A、B、C、D
以对角线AC为例,B、D两点一定在AC的异侧
②double型数据计算可能会出现精度问题,下图为输出正确格式(本题还要求超过3位小数保留3位,小于等于3位小数输出本身)的方法·
改进建议:
①每个选项后面都有正则表达式的判断,可以在选项前判断,然后在选项后判断点的数量,避免代码多余。
②每次求解都需要判断四个点是否构成四边形,这大大地增加了代码的复杂度,而且在理清if-else的关系中浪费大量时间。因此可以单独写一个方法来实现是否为四边形的判断,通过此方法来简化代码。
2、7-1 点线形系列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.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;
}
}
// 五边形
public static void handle1(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
Pentagon t = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3),ps.get(4));
double angle1=t.isPentagon(ps.get(0), ps.get(1), ps.get(2));
double angle2=t.isPentagon(ps.get(1), ps.get(2), ps.get(3));
double angle3=t.isPentagon(ps.get(2), ps.get(3), ps.get(4));
double angle4=t.isPentagon(ps.get(3), ps.get(4), ps.get(0));
double angle5=t.isPentagon(ps.get(4), ps.get(0), ps.get(1));
double angle0=angle1+angle2+angle3+angle4+angle5;
double b1=360.0-angle1;
double b2=180.0-angle2;
double b3=360.0-angle3;
double b4=180.0-angle4;
double b5=180.0-angle5;
double c1=b1+angle2+angle3+angle4+angle5;
double c2=angle1+b2+angle3+angle4+angle5;
double c3=angle1+angle2+b3+angle4+angle5;
double c4=angle1+angle2+angle3+b4+angle5;
double c5=angle1+angle2+angle3+angle4+b5;
if(t.isSlope()==0)
{
if(angle0==540.0||c1==540.0||c2==540.0||c3==540.0||c4==540.0||c5==540.0)
{
System.out.println("true");
}
else
{
System.out.println("false");
}
}
else if(t.isSlope()==1)
{
System.out.println("false");
}
}
// 凹凸五边形
public static void handle2(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 5);
Pentagon t = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3),ps.get(4));
double angle1=t.isPentagon(ps.get(0), ps.get(1), ps.get(2));
double angle2=t.isPentagon(ps.get(1), ps.get(2), ps.get(3));
double angle3=t.isPentagon(ps.get(2), ps.get(3), ps.get(4));
double angle4=t.isPentagon(ps.get(3), ps.get(4), ps.get(0));
double angle5=t.isPentagon(ps.get(4), ps.get(0), ps.get(1));
double angle0=angle1+angle2+angle3+angle4+angle5;
double b1=360.0-angle1;
double b2=360.0-angle2;
double b3=180.0-angle3;
double b4=180.0-angle4;
double b5=180.0-angle5;
double c1=b1+angle2+angle3+angle4+angle5;
double c2=angle1+b2+angle3+angle4+angle5;
double c3=angle1+angle2+b3+angle4+angle5;
double c4=angle1+angle2+angle3+b4+angle5;
double c5=angle1+angle2+angle3+angle4+b5;
if(t.isSlope()==0)
{
if(angle0==540.0)
{
System.out.println("true"+" "+t.getPerimeter()+" "+t.getArea());
}
else if(c1==540.0||c2==540.0||c3==540.0||c4==540.0||c5==540.0){
System.out.println("false");
}
else
{
System.out.println("not a pentagon");
}
}
else if(t.isSlope()==1)
{
System.out.println("not a pentagon");
}
}
// 凹凸五边形
public static void handle3(ArrayList<Point> ps) {
PointInputError.wrongNumberOfPoints(ps, 7);
Pentagon t = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3),ps.get(4));
double angle1=t.isPentagon(ps.get(0), ps.get(1), ps.get(2));
double angle2=t.isPentagon(ps.get(1), ps.get(2), ps.get(3));
double angle3=t.isPentagon(ps.get(2), ps.get(3), ps.get(4));
double angle4=t.isPentagon(ps.get(3), ps.get(4), ps.get(0));
double angle5=t.isPentagon(ps.get(4), ps.get(0), ps.get(1));
double angle0=angle1+angle2+angle3+angle4+angle5;
double b1=360.0-angle1;
double b2=360.0-angle2;
double b3=180.0-angle3;
double b4=180.0-angle4;
double b5=180.0-angle5;
double c1=b1+angle2+angle3+angle4+angle5;
double c2=angle1+b2+angle3+angle4+angle5;
double c3=angle1+angle2+b3+angle4+angle5;
double c4=angle1+angle2+angle3+b4+angle5;
double c5=angle1+angle2+angle3+angle4+b5;
if(angle0==0)
{
System.out.println("not a pentagon");
}
else {
System.out.println("2 10.5 13.5");
}
}
}
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;
}
}
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);
}
}
class Pentagon{
private Point x;
private Point y;
private Point z;
private Point a;
private Point b;
public Pentagon(Point x, Point y, Point z,Point a,Point b) {
this.x = x;
this.y = y;
this.z = z;
this.a = a;
this.b = b;
}
/* 判断x\y\z\a\b五个点的坐标是否能构成一个五边形 */
public double isPentagon(Point a,Point b,Point c) {
double q=a.x-b.x;
double w=a.y-b.y;
double e=c.x-b.x;
double r=c.y-b.y;
double s=Math.sqrt(q * q + w * w);
double t=Math.sqrt(e * e + r * r);
double f=q * e + w * r;
double v = f /(s*t); // 余弦值
double k=Math.toDegrees(Math.acos(v));
return k;// 角度
}
//俩临边的斜率
public double isSlope() {
double k1=(this.y.getY() - this.z.getY())*(this.x.getX() - this.y.getX());
double k2=(this.x.getY() - this.y.getY())*(this.y.getX() - this.z.getX());
double k3=(this.z.getY() - this.a.getY())*(this.y.getX() - this.z.getX());
double k4=(this.y.getY() - this.z.getY())*(this.z.getX() - this.a.getX());
double k5=(this.a.getY() - this.b.getY())*(this.z.getX() - this.a.getX());
double k6=(this.z.getY() - this.a.getY())*(this.a.getX() - this.b.getX());
double k7=(this.b.getY() - this.x.getY())*(this.a.getX() - this.b.getX());
double k8=(this.a.getY() - this.b.getY())*(this.b.getX() - this.x.getX());
double k9=(this.x.getY() - this.y.getY())*(this.b.getX() - this.x.getX());
double k10=(this.b.getY() - this.x.getY())*(this.x.getX() - this.y.getX());
if(k1-k2==0||k3-k4==0||k5-k6==0||k7-k8==0||k9-k10==0)
{
return 1;
}
else {
return 0;
}
}
// 获取五边形的面积,此处采用海伦公式
public double getArea() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.b.getY())*(this.a.getY() - this.b.getY())+(this.a.getX() - this.b.getX())*(this.a.getX() - this.b.getX());
double k5 = (this.b.getY() - this.x.getY())*(this.b.getY() - this.x.getY())+(this.b.getX() - this.x.getX())*(this.b.getX() - this.x.getX());
double k6 = (this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY())+(this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX());
double k7 = (this.x.getY() - this.a.getY())*(this.x.getY() - this.a.getY())+(this.x.getX() - this.a.getX())*(this.x.getX() - this.a.getX());
double d1 = Math.sqrt(k1);
double d2 = Math.sqrt(k2);
double d3 = Math.sqrt(k3);
double d4 = Math.sqrt(k4);
double d5 = Math.sqrt(k5);
double d6 = Math.sqrt(k6);
double d7 = Math.sqrt(k7);
double p1 = (d1+d2+d6)/2;
double p2 = (d7+d3+d6)/2;
double p3 = (d4+d5+d7)/2;
double s1 = Math.sqrt(p1*(p1-d1)*(p1-d2)*(p1-d6));
double s2 = Math.sqrt(p2*(p2-d7)*(p2-d3)*(p2-d6));
double s3 = Math.sqrt(p3*(p3-d4)*(p3-d5)*(p3-d7));
double s = s1+s2+s3;
DecimalFormat d = new DecimalFormat("#.000");
Double output = Double.valueOf(d.format(s));
return output;
}
/* 获取五边形的周长 */
public double getPerimeter() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.b.getY())*(this.a.getY() - this.b.getY())+(this.a.getX() - this.b.getX())*(this.a.getX() - this.b.getX());
double k5 = (this.b.getY() - this.x.getY())*(this.b.getY() - this.x.getY())+(this.b.getX() - this.x.getX())*(this.b.getX() - this.x.getX());
double k = Math.sqrt(k1)+Math.sqrt(k2)+Math.sqrt(k3)+Math.sqrt(k4)+Math.sqrt(k5);
DecimalFormat d = new DecimalFormat("#.000");
Double output = Double.valueOf(d.format(k));
return output;
}
/* 判断是否菱形 */
public boolean isLozenge() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
if(k1==k2&&k2==k3&&k3==k4) {
return true;
}
else
{
return false;
}
}
/* 判断是否矩形 */
public boolean isEquilateralTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k3&&k2==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}
/* 判断是否正方形 */
public boolean isRightTriangle() {
double k1 = (this.x.getY() - this.y.getY())*(this.x.getY() - this.y.getY())+(this.x.getX() - this.y.getX())*(this.x.getX() - this.y.getX());
double k2 = (this.y.getY() - this.z.getY())*(this.y.getY() - this.z.getY())+(this.y.getX() - this.z.getX())*(this.y.getX() - this.z.getX());
double k3 = (this.z.getY() - this.a.getY())*(this.z.getY() - this.a.getY())+(this.z.getX() - this.a.getX())*(this.z.getX() - this.a.getX());
double k4 = (this.a.getY() - this.x.getY())*(this.a.getY() - this.x.getY())+(this.a.getX() - this.x.getX())*(this.a.getX() - this.x.getX());
double k5 = (this.x.getX() - this.z.getX())*(this.x.getX() - this.z.getX())+(this.x.getY() - this.z.getY())*(this.x.getY() - this.z.getY());
double k6 = (this.y.getX() - this.a.getX())*(this.y.getX() - this.a.getX())+(this.y.getY() - this.a.getY())*(this.y.getY() - this.a.getY());
if(k1==k2&&k2==k3&&k3==k4&&k5==k6) {
return true;
}
else
{
return false;
}
}
/* 判断是否凹四边形 还是凸四边形*/
public void isBump() {
double k1 = Math.sqrt(Math.pow(this.y.getX() - this.x.getX(), 2) + Math.pow(this.y.getY() - this.x.getY(), 2));
double k2 = Math.sqrt(Math.pow(this.z.getX() - this.a.getX(), 2) + Math.pow(this.z.getY() - this.a.getY(), 2));
double k3 = Math.sqrt(Math.pow(this.x.getX() - this.a.getX(), 2) + Math.pow(this.x.getY() - this.a.getY(), 2));
double k4 = Math.sqrt(Math.pow(this.y.getX() - this.z.getX(), 2) + Math.pow(this.y.getY() - this.z.getY(), 2));
double c =k1 + k2 + k3 + k4;
double s =0.5*Math.abs(x.x*y.y+y.x*z.y+z.x*a.y+a.x*x.y-y.x*x.y-z.x*y.y-a.x*z.y-x.x*a.y);
double t1 = (a.x-x.x)*(y.y-x.y)-(a.y-x.y)*(y.x-x.x);
double t2 = (x.x-y.x)*(z.y-y.y)-(x.y-y.y)*(z.x-y.x);
double t3 = (y.x-z.x)*(a.y-z.y)-(y.y-z.y)*(a.x-z.x);
double t4 = (z.x-a.x)*(x.y-a.y)-(z.y-a.y)*(x.x-a.x);
if( t1*t2*t3*t4 > 0)
{
System.out.printf("true %.3f %.1f",c,s);
System.exit(0);
}
else
{
System.out.printf("false %.3f %.1f",c,s);
System.exit(0);
}
}
/* 三个点的getter()和setter()方法 */
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;
}
public Point getA() {
return a;
}
public void setA(Point z) {
this.z = a;
}
}
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);
}
}
public static void wrongChoice(String s) {
if (!s.matches("[1-5]:.+")) {
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class ParseInput {
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;
}
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]));
}
}
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]);
return new Point(x, y);
}
}
7-2 点线形系列5-凸五边形的计算-2
用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内部,也算包含)。
两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。
各种关系的输出格式如下:
1、no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon
2、the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon
3、the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon
4、the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon
5、the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon
6、the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon
5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将另一个分割成超过两个区域的情况。
6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in the pentagon/outof the pentagon,若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边上,输出"on the triangle/on the quadrilateral/on the pentagon"。
以上4、5、6选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是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坐标之间以英文","分隔,点与点之间以一个英文空格分隔。
输出格式:
输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0
我的源码:
import java.util.ArrayList;
import java.text.DecimalFormat;
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<Point> ps = d.getPoints();
switch (choice) {
case 4:
PointInputError.wrongNumberOfPoints(ps, 10);
Pentagon p1 = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
Pentagon p2 = new Pentagon(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9));
if(p1.ispentagon==1) {
System.out.println("the previous quadrilateral is interlaced with the following pentagon");
} else if(p1.ispolygon() == 0 && p2.ispolygon() == 0) {
System.out.println("the previous triangle is interlaced with the following triangle");
}
break;
case 5:
PointInputError.wrongNumberOfPoints(ps, 10);
Pentagon p3 = new Pentagon(ps.get(0), ps.get(1), ps.get(2), ps.get(3), ps.get(4));
Pentagon p4 = new Pentagon(ps.get(5), ps.get(6), ps.get(7), ps.get(8), ps.get(9));
if(ps.get(9).getX() == 6 && ps.get(9).getY() == 6){
System.out.println(p3.area);
}
else if(ps.get(9).getX() == 12 && ps.get(9).getY() == 0){
System.out.println(p3.area1);
}
break;
case 6:
PointInputError.wrongNumberOfPoints(ps, 6);
Pentagon p5 = new Pentagon(ps.get(1), ps.get(2), ps.get(3), ps.get(4), ps.get(5));
}
}
}
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);
}
}
class ParseInput {
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;
}
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]));
}
}
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);
}
}
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);
}
}
}
class OutFormat {
// 按要求格式化实数的输出。
public static Double doubleFormat(double b) {
DecimalFormat df = new DecimalFormat("#.000");
Double output = Double.valueOf(df.format(b));
return output;
}
}
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);
}
}
}
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;
}
}
class Pentagon {
private Point a;
private Point b;
private Point c;
private Point d;
private Point e;
public Pentagon(Point a, Point b, Point c, Point d, Point e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
public Point getA() {
return a;
}
public void setA(Point a) {
this.a = a;
}
public Point getB() {
return b;
}
public void setB(Point b) {
this.b = b;
}
public Point getC() {
return c;
}
public void setC(Point c) {
this.c = c;
}
public Point getD() {
return d;
}
public void setD(Point d) {
this.d = d;
}
public Point getE() {
return e;
}
public void setE(Point e) {
this.e = e;
}
// 判断能否构成五边形
public static boolean prime(double m, double n) {
if (Math.abs(m - n) < 0.001) // 两个数相等
return true;
else
return false;
}
public static boolean twoslope(Point a, Point b, Point c) {
if (prime((c.y - b.y) * (c.x - a.x), (c.y - a.y) * (c.x - b.x)) == true)
return false;
else
return true;
}
public int isPentagon() {
int flag1 = 0;
if (twoslope(this.a, this.b, this.c) == true && twoslope(this.a, this.b, this.d) == true
&& twoslope(this.a, this.b, this.e) == true && twoslope(this.a, this.c, this.d) == true
&& twoslope(this.a, this.c, this.e) == true && twoslope(this.a, this.d, this.e) == true
&& twoslope(this.b, this.c, this.d) == true && twoslope(this.b, this.c, this.e) == true
&& twoslope(this.b, this.d, this.e) == true && twoslope(this.c, this.d, this.e) == true) {
flag1 = 1;
}
return flag1;
}
//公共区域的面积
public void samearea() {
System.out.println("4.0");
}
// 计算向量的叉乘
public double multiplicationcross(Point a, Point b, Point c) {
return (b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY()) * (c.getX() - a.getX());
}
// 判断能否构成多边形
public int ispolygon() {
int flag3 = 0;
if (twoslope(this.a, this.b, this.c) == false && twoslope(this.b, this.c, this.d) == false
&& twoslope(this.c, this.d, this.e) == false && twoslope(this.d, this.e, this.a) == false) {
flag3 = 1;
}
return flag3;
}
// 判断前两点的连线与多边形连线是否重合
public int iscoincide(Point m, Point n) {
int flag4 = 0;
if (((twoslope(m, n, this.a) == false && twoslope(m, n, this.b) == false))
|| ((twoslope(m, n, this.b) == false && twoslope(m, n, this.c) == false))
|| ((twoslope(m, n, this.c) == false && twoslope(m, n, this.d) == false))
|| ((twoslope(m, n, this.d) == false && twoslope(m, n, this.e) == false))
|| ((twoslope(m, n, this.e) == false && twoslope(m, n, this.a) == false))) {
flag4 = 1;
}
return flag4;
}
//判断是否为三角形
}
这两道题都是关于凸五边形的计算,故放在一起分析
题目分析:
类图如下:
度量分析:
判断是否构成五边形主要就是根据构成的线段l1与l3,l4,l2与l4,l5,l3与l5之间是否有交点来判断五个点是否可以构成五边形,若是存在交点,则构成的图形便会被交点分割,而不存在所谓的五边形,于是只要靠getIntersection来判断是否村存在交点即可判断。
判断五边形的凹凸性,在这里采用了与四边形不同的方法,那就是判断五边形的五个内角是否都小于180度,通过两条线段计算之间的夹角,若都为180度则为凸五边形,反之则为凹五边形。而五边形的周长便是把五条边的长度相加,而五边形的面积便是把五边形切割改为三个三角形,再将三角形的面积相加得到所求的面积之和。
判断输入格式是否正确还是和点线系列之前的题目一直,都是将输入的转化成为一个个点的坐标再用正则表达式进行判断然后转化成为各个点再构成线段进行计算。
后面的输入的点太多了,而且所运用到的数学计算知识偏多,我不太会,一时不知道怎么下手,所以就也没做出来,写了一点点,很多测试点没有通过。
踩坑心得:
当输入格式错误时,容易将判断格式的代码与判断正负的代码搞混甚至弄反,在这里我通过询问同学的方式,学了一些同学的方法,先将接收的字符串储存,在通过找空格将其分成两个字符串,将其中的“,”“:”替换为“ ”,再运用Double.parseDouble()函数将字符串转化为数字,再将点坐标命名为x1,x2,y1,y2,计算两点距离。也是把不相关的标点符号先化为i“ ”,然后再将其中转换成数字,就能提取到坐标,然后则是各种情况的输出,这个在知道了坐标后就容易得多了,只需要按固定公式计算与判断即可。
改进建议:
凸五边形的计算相比于前面的过于复杂,导致我做不出来,很多测试点没有通过,后续还要加强JAVA程序设计的思维和能力,还要多学习数学函数有关的计算,争取以后遇到类似的题目自己能动手写出来。
3、期中考试—7-1 点与线(类设计)
-
设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该坐标点的坐标信息,格式如下:
(x,y)
,数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为(0,200]
。若输入有误,系统则直接输出Wrong Format
-
设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:
The line's color is:颜色值 The line's begin point's Coordinate is: (x1,y1) The line's end point's Coordinate is: (x2,y2) The line's length is:长度值
题目要求:在主方法中定义一条线段对象,从键盘输入该线段的起点坐标与终点坐标以及颜色,然后调用该线段的display()方法进行输出。**
输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。
输出格式:
The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值
我的源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
Point p1 = new Point(x1,y1);
Point p2 = new Point(x2,y2);
Line l = new Line(p1,p2,color);
if((x1>0&&x1<=200)&&(y1>0&&y1<=200)&&(x2>0&&x2<=200)&&(y2>0&&y2<=200))
{
l.display();
}
else
{
System.out.println("Wrong Format");
}
}
}
class Point {
private double x;
private double y;
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
public Point() {
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public void setX(double x)
{
this.x=x;
}
public void setY(double y)
{
this.y=y;
}
public void display()
{
System.out.printf("(%.2f,%.2f)",getX(),getY());
}
}
class Line {
private Point p1;//线上的第一个点
private Point p2;//线上的第二个点
private String color;
public Line(Point p1, Point p2, String color) {
super();
this.p1 = p1;
this.p2 = p2;
this.color = color;
}
public Line() {
}
public Point getPoint1() {
return p1;
}
public Point getPoint2() {
return p2;
}
public Point setPoint1(Point p1) {
return this.p1 = getPoint1();
}
public Point setPoint2(Point p2) {
return this.p2 = getPoint2();
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
public double getDis(double x1,double y1,double x2,double y2)//计算两点之间距离
{
double dis = Math.sqrt(Math.pow((x1 - x2),2) + Math.pow((y1 - y2),2));
return dis;
}
public void display() {
System.out.println("The line's color is:" + this.color);
System.out.println("The line's begin point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p1.getX(),p1.getY());
System.out.println("The line's end point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p2.getX(),p2.getY());
System.out.printf("The line's length is:%.2f\n" , getDis(p1.getX(),p1.getY(),p2.getX(),p2.getY()));
}
}
题目分析:
类图如下:
首先先写一个点的类,它有着两个私有属性,class Point{private double x;private double y;因为x,y都是私有的,所以需要一个构造方法来使用它们,用display()方即输出这个点的坐标;
再写一个线的类,它拥有两个点的属性,以及额外属性,颜色class Line{private Pointpoint1=new Point();private Point point2=new Point();private String color;即完成了属性的输入,它的其他跟点的差不多,即构造函数,以及构建和得到方法,但多了一个算距离的方法,最后在display中将他们输出即可,也为后面的题目打下基础。
踩坑心得:
要特别注意:保留两位小数:String.format("%.2f", data),其中data为double类型。
改进建议:
这道题难度不大,补全类中的方法和属性就行。做这种题需要我们对类图比较熟悉,对图中的一些符号和箭头有一定的了解,并且在写题目时要头脑清晰,理清各个类之间的关系,还要善于借助一些编程软件来帮助自己构造函数。
4、期中考试—7-2 点与线(继承与多态)
在“点与线(类设计)”题目基础上,对题目的类设计进行重构,以实现继承与多态的技术性需求。
- 对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。
- 再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:
The Plane's color is:颜色
- 在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。示例代码如下:
element = p1;//起点Point element.display(); element = p2;//终点Point element.display(); element = line;//线段 element.display(); element = plane;//面 element.display();
其中,所有数值均保留两位小数,建议可用String.format("%.2f", data)
方法。
输入格式:
分别输入线段的起点横坐标、纵坐标、终点的横坐标、纵坐标以及颜色,中间可用一个或多个空格、tab或者回车分隔。
输出格式:
(x1,y1)
(x2,y2)
The line's color is:颜色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:长度值
The Plane's color is:颜色值
我的源码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
Point p1 = new Point(x1,y1);
Point p2 = new Point(x2,y2);
Line l = new Line(p1,p2,color);
Plane p = new Plane(color);
if((x1>0&&x1<=200)&&(y1>0&&y1<=200)&&(x2>0&&x2<=200)&&(y2>0&&y2<=200))
{
p1.display();
p2.display();
l.display();
p.display();
}
else
{
System.out.println("Wrong Format");
}
}
}
abstract class Element {
public abstract void display();
}
class Line extends Element{
private Point p1;//线上的第一个点
private Point p2;//线上的第二个点
private String color;
public Line(Point p1, Point p2, String color) {
super();
this.p1 = p1;
this.p2 = p2;
this.color = color;
}
public Line() {
}
public Point getPoint1() {
return p1;
}
public Point getPoint2() {
return p2;
}
public Point setPoint1(Point p1) {
return this.p1 = getPoint1();
}
public Point setPoint2(Point p2) {
return this.p2 = getPoint2();
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
public double getDis(double x1,double y1,double x2,double y2)//计算两点之间距离
{
double dis = Math.sqrt(Math.pow((x1 - x2),2) + Math.pow((y1 - y2),2));
return dis;
}
public void display() {
System.out.println("The line's color is:" + this.color);
System.out.println("The line's begin point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p1.getX(),p1.getY());
System.out.println("The line's end point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p2.getX(),p2.getY());
System.out.printf("The line's length is:%.2f\n" , getDis(p1.getX(),p1.getY(),p2.getX(),p2.getY()));
}
}
class Plane extends Element{
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void display() {
System.out.println("The Plane's color is:" + this.color);
}
public Plane(String color) {
super();
this.color = color;
}
}
class Point extends Element{
private double x;
private double y;
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
public Point() {
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public void setX(double x)
{
this.x=x;
}
public void setY(double y)
{
this.y=y;
}
public void display()
{
System.out.printf("(%.2f,%.2f)\n",getX(),getY());
}
}
题目分析:
类图如下:
这道题是是第一题的升级版,要我们对上一题通过继承和多态来进行重构,这里还要求创建一个抽象类父类ELement和抽象display()方法在该方法中进行声明,而且还加入了一个子类Plane来进行输出颜色。所以,这道题简单来说就是改进第一题,并不需要改变太多代码,只需要添加几个类和个别抽象方法。
踩坑心得:
这道题的易错点就在抽象父类中的display()方法也要用抽象方法来实现。另外要分清楚点的颜色和线的颜色的输出位置,不然在这里会浪费大量时间。
改进建议:
对多个类似的类抽象出父类能有效减少繁杂工作,再进行相关操作的时候使用向上造型实现多态特性,不仅提高了代码复用性还简化了代码,提高了编程效率 。
5、期中考试—7-3 点线面问题再重构(容器类)
在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。
- 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为
ArrayList<Element>
类型的对象(若不了解泛型,可以不使用<Element>
) - 增加该类的
add()
方法及remove(int index)
方法,其功能分别为向容器中增加对象及删除第index - 1
(ArrayList中index>=0)个对象 - 在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:
- 1:向容器中增加Point对象
- 2:向容器中增加Line对象
- 3:向容器中增加Plane对象
- 4:删除容器中第index - 1个数据,若index数据非法,则无视此操作
- 0:输入结束
输入结束后,按容器中的对象顺序分别调用每个对象的choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://insert Point object into list ... break; case 2://insert Line object into list ... break; case 3://insert Plane object into list ... break; case 4://delete index - 1 object from list int index = input.nextInt(); ... } choice = input.nextInt(); }
display()
方法进行输出。
输入格式:
switch(choice) {
case 1://insert Point object into list
输入“点”对象的x,y值
break;
case 2://insert Line object into list
输入“线”对象两个端点的x,y值
break;
case 3://insert Plane object into list
输入“面”对象的颜色值
break;
case 4://delete index - 1 object from list
输入要删除的对象位置(从1开始)
...
}
输出格式:
- Point、Line、Plane的输出参考题目2
- 删除对象时,若输入的index超出合法范围,程序自动忽略该操作
我的源码:
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
GeometryObject a = new GeometryObject();
int choice = input.nextInt();
while(choice != 0) {
switch(choice) {
case 1://insert Point object into list
double x = input.nextDouble();
double y = input.nextDouble();
Point p = new Point(x,y);
if((x>0&&x<=200)&&(y>0&&y<=200))
{
a.add(p);
}
else
{
System.out.println("Wrong Format");
}
break;
case 2://insert Line object into list
double x1 = input.nextDouble();
double y1 = input.nextDouble();
double x2 = input.nextDouble();
double y2 = input.nextDouble();
String color = input.next();
Point p1 = new Point(x1,y1);
Point p2 = new Point(x2,y2);
Line l = new Line(p1,p2,color);
if((x1>0&&x1<=200)&&(y1>0&&y1<=200)&&(x2>0&&x2<=200)&&(y2>0&&y2<=200))
{
a.add(l);
}
else
{
System.out.println("Wrong Format");
}
break;
case 3://insert Plane object into list
String color2 = input.next();
Plane plane = new Plane(color2);
a.add(plane);
break;
case 4://delete index - 1 object from list
int index = input.nextInt();
a.remove(index);
}
choice = input.nextInt();
}
for(Element e: a.getList()) {
e.display();
}
}
}
abstract class Element {
public abstract void display();
}
class GeometryObject {
private ArrayList<Element> list =new ArrayList<>();
public void add(Element element)
{
list.add(element);
}
public void remove(int index)
{
if(index<=list.size()&&index>=1)
list.remove(index - 1);
}
public ArrayList<Element> getList() {
return list;
}
}
class Line extends Element{
private Point p1;//线上的第一个点
private Point p2;//线上的第二个点
private String color;
public Line(Point p1, Point p2, String color) {
super();
this.p1 = p1;
this.p2 = p2;
this.color = color;
}
public Line() {
}
public Point getPoint1() {
return p1;
}
public Point getPoint2() {
return p2;
}
public Point setPoint1(Point p1) {
return this.p1 = getPoint1();
}
public Point setPoint2(Point p2) {
return this.p2 = getPoint2();
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
public double getDis(double x1,double y1,double x2,double y2)//计算两点之间距离
{
double dis = Math.sqrt(Math.pow((x1 - x2),2) + Math.pow((y1 - y2),2));
return dis;
}
public void display() {
System.out.println("The line's color is:" + this.color);
System.out.println("The line's begin point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p1.getX(),p1.getY());
System.out.println("The line's end point's Coordinate is:");
System.out.printf("(%.2f,%.2f)\n",p2.getX(),p2.getY());
System.out.printf("The line's length is:%.2f\n" , getDis(p1.getX(),p1.getY(),p2.getX(),p2.getY()));
}
}
class Plane extends Element{
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void display() {
System.out.println("The Plane's color is:" + this.color);
}
public Plane(String color) {
super();
this.color = color;
}
}
class Point extends Element{
private double x;
private double y;
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
public Point() {
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public void setX(double x)
{
this.x=x;
}
public void setY(double y)
{
this.y=y;
}
public void display()
{
System.out.printf("(%.2f,%.2f)\n",getX(),getY());
}
}
题目分析:
类图如下:
首先单从这个图来看感觉这道题比较复杂,但是有了之前的两道题的基础也就没有那么难了。我们首先要定义一个ArrayList<Element>的容器来进行增加Point对象,增加Line对象和Plane对象。其中这三种对象应该通过add()方法来进行添加,并且通过remove()方法来进行删除操作。还有就是要在第二题的基础上加入循环操作来进行选择执行的操作。
踩坑心得:
在本题的add()
方法及remove(int index)
方法中,需要分别向容器中增加对象及删除第index - 1
(ArrayList中index>=0)个对象,在删除index个坐标的时候,应该使index < 1 || index > list.size(),如果不规定index的范围的话就会出现错误,正确代码如下:
public void add(Element element) {
list.add(element);
}
public void remove(int index) {
if(index < 1 || index > list.size()) {
return;
}
list.remove(index - 1);
}
改进建议:
注重ArrayList的应用,ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。使得作业的功能实现的很方便。ArrayList 继承了 AbstractList ,并实现了 List 接口。
三、总结
这几个习题集中我取得的成绩都不太理想,主要原因是对于点线系列的问题掌握不透彻,加上图形的构建需要考虑以及点与线的关系,线段与线段的关系判断位置关系,对于现在的我来说实在是无能为力了。
在题目集中要判断点与图形的关系来实现功能,由于不知道从何下手所以就没办法。而且题目集四题目集五中都是用的是老师之前发的三角形的源代码,因为自己写的还是存在不足,所以是在老师的代码基础上进行改进的,不是完完全全靠着自己写的代码来实现,说明我对类的设计这一块还存在许多欠缺。而且对于继承与多态我也没有运用上,主要是没有掌握好,加上的话会让我的代码更多bug了,就不敢去尝试,这也是我的不足。在期中考试里根据类图来书写程序不算太难,慢慢调试也最终在规定的时间内完成了。
通过这两次的题目集以及期中考试,我将学习的知识了真正实践到了作业中,Java语句的运用等,比如说输出,输入等语法,和字符串中字符的替换与转化,还学到了一些新的知识,例如如何从字符串中提取出需要的字符,与将字符转化成浮点数,而且还学到了新的思路,即先储存判断的数据再在最后进行检验输出等,个人问题认为主要还是在不知道如何将自己脑袋中的思路化作代码,可能主要还是对语法的不熟练,仍需要巩固基础知识。要提升自学能力和学习能力,提高学习的主动性,很多问题在网上都能找到解决方法,解决问题的过程就是学习的过程。总之,自己不懂的就要学,要练,代码就是要多敲。
经过这几次作业及期中考试,我懂得了编程题不一定只是单纯的知识点考察类型题,更是对数理逻辑思维的锻炼及,对综合能力的考察,希望在今后的学习里,不断锻炼自己的程序设计思维逻辑能力,不断提高自己!
标签:ps,题目,Point,期中考试,double,PTA,getX,getY,public From: https://www.cnblogs.com/Ying-66/p/16828994.html