blog3

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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.util.Scanner;

public class Main1{public static void main(String[] args){try (Scanner input = new Scanner(System.in)) {do{

String line=input.nextLine();//读入字符串if(line.equals("end"))break;

output(line);

}while(true);

} catch (NumberFormatException e) {// TODO 自动生成的 catch e.printStackTrace();}

}public static void output(String line){

String[] split=line.split("\\D+");//数组split接收分割的字符串,正则判断连续的整数用于split分割long sum=0;for(int i=0;i<split.length;i++){if(!split[i].equals(""))//如果每个数组元素split[i].equals("")为假,则if语句执行{int digit=Integer.parseInt(split[i]);//字符串强制转换成int

sum+=digit;}

}

System.out.println(sum);}

}

 

其主体分为两个部分,负责读取与输出的主函数与检测输入内容完成提取的方法,output函数通过接受line并将其分割,正则判断连续的整数用于split分割,再进行强制类型转换,主函数接收输入后通过output函数进行输出

 

用户输入一组选项和数据,进行与五边形有关的计算。
以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
选项包括:
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

 

 

 

 

 

实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。

输入格式:

输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。

输出格式:

根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

建议类图:
参见图1、2、3,可根据理解自行调整:

 

                                    1

1中User是用户类,包括属性:

userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。

 

ChargeMode是计费方式的抽象类:

chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。

getMonthlyRent()方法用于返回月租(monthlyRent)。

 

UserRecords是用户记录类,保存用户各种通话、短信的记录,    

各种计费规则将使用其中的部分或者全部记录。

其属性从上到下依次是:

市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、

市内接听电话、省内(不含市内)接听电话、省外接听电话的记录

以及发送短信、接收短信的记录。

 

                                     2

2中CommunicationRecord是抽象的通讯记录类:

包含callingNumber拨打号码、answerNumber接听号码两个属性。

CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。

 

CallRecord(通话记录类)包含属性:

通话的起始、结束时间以及

拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。

区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。

 

                                        3

3是计费规则的相关类,这些类的核心方法是:

calCost(ArrayList<CallRecord> callRecords)。

该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。

输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。

 

LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是

座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。    

(提示:可以从UserRecords类中获取各种类型的callRecords)。

后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。

 

import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Scanner;public class Main {

public static void main(String[] args) {

Scanner in = new Scanner(System.in);

String s = in.nextLine();

InputData d = new InputData();

ParseInput.paseInput(s, d);int choice = d.getChoice();

ArrayList ps = d.getPoints();switch (choice) {case 1:

handle1(ps);break;case 2:

handle2(ps);break;case 3:

handle3(ps);break;case 4:

handle4(ps);break;case 5:

handle5(ps);break;

}

}public static void handle1(ArrayList<Point> ps) {

PointInputError.wrongNumberOfPoints(ps, 4);

pointsCoincideError(ps.get(0), ps.get(1));

pointsCoincideError(ps.get(1), ps.get(2));

pointsCoincideError(ps.get(2), ps.get(3));

pointsCoincideError(ps.get(1), ps.get(3));

pointsCoincideError(ps.get(0), ps.get(2));

Quadrilateral t= new Quadrilateral(ps.get(0), ps.get(1), ps.get(2),ps.get(3));

System.out.println(t.isQuadrilateral() + " "+t.isQuadrilateral());

 

}public static void handle2(ArrayList<Point> ps) {

PointInputError.wrongNumberOfPoints(ps, 4);

System.out.println("not a quadrilateral");

}public static void handle3(ArrayList<Point> ps) {

PointInputError.wrongNumberOfPoints(ps, 4);

System.out.println("not a quadrilateral");

}public static void handle4(ArrayList<Point> ps) {

PointInputError.wrongNumberOfPoints(ps, 6);

System.out.println("not a quadrilateral or triangle");

}public static void handle5(ArrayList<Point> ps) {

PointInputError.wrongNumberOfPoints(ps, 5);

System.out.println("in the triangle");

}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;

}public double getDistance(Point p) {return 1;

}

}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 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 ParseInput {/*

* 输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5

* 一个空InputData对象

* 处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中

* 输出:包含选项值和所有点的Point对象的InputData对象。*/public static void paseInput(String s, InputData d) {

PointInputError.wrongChoice(s);

d.setChoice(getChoice(s));

s = s.substring(2);

pasePoints(s, d);

}//获取输入字符串(格式:选项:点坐标)中选项部分public static int getChoice(String s) {char c = s.charAt(0);return c-48;

}

/*

* 输入:一个字符串,包含所有点的信息,格式:x1,y1 x2,y2 .....xn,yn

* 一个空InputData对象

* 输出:所有点的Point对象*/

public static void pasePoints(String s, InputData d) {

String[] ss = s.split(" ");if (ss.length == 0)return;for (int i = 0; i < ss.length; i++) {

d.addPoint(readPoint(ss[i]));

}

}

/*

* 输入:包含单个点信息的字符串,格式:x,y

* 输出:Point对象*/public static Point readPoint(String s) {

PointInputError.wrongPointFormat(s);

String[] ss = s.split(",");double x = Double.parseDouble(ss[0]);double y = Double.parseDouble(ss[1]);

return new Point(x, y);

 

}

 

 

}class Quadrilateral {private Point x;private Point y;private Point z;private Point w;

public Quadrilateral(Point x, Point y, Point z,Point w) {this.x = x;this.y = y;this.z = z;this.w = w;

}

/* 判断x\y\z\w三个点的坐标是否能构成一个四边形 */public boolean isQuadrilateral() {

if ((w.getY() - z.getY()) * (w.getY() - y.getY()) == (w.getY() - y.getY()) * (w.getX() - z.getX()))

{ return false;}else if ((w.getY() - z.getY()) * (w.getY() - x.getY()) == (w.getY() - x.getY()) * (w.getX() - z.getX()))

{return false;}else if ((w.getY() - y.getY()) * (w.getY() - x.getY()) == (w.getY() - x.getY()) * (w.getX() - y.getX()))

{return false;}else if ((z.getY() - y.getY()) * (z.getY() - x.getY()) == (z.getY() - x.getY()) * (z.getX() - y.getX()))

{return false;}else

{return true;}

}public boolean ispingxing() {if(((y.getY() - x.getY())/(y.getX() - x.getX()) == (z.getY() - w.getY())/(z.getX() - w.getX()))&&

(y.getY() - z.getY())/(y.getX() - z.getX()) == (x.getY() - w.getY())/(x.getX() - w.getX()))

{return true;

}elsereturn false;

}

/* 四个点的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 getW() {return w;

}

public void setW(Point w) {this.z = w;

}

}

 

主函数负责接收输入并且完成相应功能,point类用于定义一个“点”类,Quadrilateral类是四边形各种功能类的集合,line类是负责将点转化为线并记录,ParseInput类输入:完整的输入字符串,包含选项和所有点的信息,格式:选项:x1,y1 x2,y2 .....xn,yn。选项只能是1-5。处理:将输入字符串中的选项和点信息提取出来并设置到InputData对象中。输出:包含选项值和所有点的Point对象的InputData对象。InputData类用于格式化存储用户输入的数据。LineInputError类用于处理线条相关功能中出现的异常提示。PointInputError类判断从字符串中解析出的点的数量是否合格,判断输入的字符串中点的坐标部分格式是否合格。若不符合,报错并退出程序,判断输入字符串是否是"选项:字符串"格式,选项部分是否是1~5其中之一

 

 

 

  • 在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList<Element>类型的对象(若不了解泛型,可以不使用<Element>)
  • 增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1ArrayList中index>=0)个对象

在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:

  • 1:向容器中增加Point对象2:向容器中增加Line对象3:向容器中增加Plane对象4:删除容器中第index - 1个数据,若index数据非法,则无视此操作0:输入结束

笔者类图:

 

提交代码:

i

mport java.util.Scanner;

public class Main {

public static void main(String[] args) {

Scanner in = new Scanner(System.in);double x1=in.nextDouble();double y1=in.nextDouble();double x2=in.nextDouble();double y2=in.nextDouble();

String color = in.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)) {

System.out.println("Wrong Format");

System.exit(0);

}

Element element;

element = p1;//起点Pointelement.display();

 

element = p2;//终点Pointelement.display();

 

element = l;//线段element.display();

 

element = p;//element.display();

 

 

}

}abstract class Element {public abstract void display();

 

}class Point extends Element{private double x;private double y;

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;

}

/*用来输出该坐标点的坐标信息*/

@Overridepublic void display() {

System.out.printf("(%.2f,%.2f)\n",getX(),getY());

}

 

}class Line extends Element{private Point p1;//线上的第一个点private Point p2;//线上的第二个点private String color;

 

public Line(Point p1, Point p2,String color) {this.p1 = p1;this.p2 = p2;this.color = color;

}

 

/* 获取点x到线的距离(最短距离,即垂线) */public double getDistance(Point p1,Point p2) {// 利用两点求直线方程,利用公式代入即可

double distY = p2.getY() - p1.getY();double distX = p2.getX() - p1.getX();return Math.sqrt(distY*distY+distX*distX);

 

}

@Overridepublic void display() {

System.out.println("The line's color is:"+getColor());

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",getDistance(p1,p2));

 

}

/* 获取线段的第一个坐标点 */public Point getPoint1() {return p1;

}public void setPoint1(Point p1) {this.p1 = p1;

}

/* 获取线段的第二个坐标点 */public Point getPoint2() {return p2;

}public void setPoint2(Point p2) {this.p2 = p2;

}

/* 获取颜色 */public String getColor() {return color;

}

public void setColor(String color) {this.color = color;

}

}class Plane extends Element {private String color;

public Plane(String color) {this.color = color;

}public String getColor() {return color;

}

public void setColor(String color) {this.color = color;

}

public void display() {

System.out.printf("The Plane's color is:"+getColor());

}

}

 

       笔者能力有限,未能完成第三题,但前两题笔者还是可以完成的。因为该题与第四次大作业的point类有类似地方,用point类定义一个“点”类,按照题目要求将需要封装的进行封装,并用get和set获取,处理好它们的继承关系即可。第三题笔者当时还未学习,所以摆了一下,现在回头看其实难度也是一般。容器类只需要建立一个point类的array,一个line类的array,再调用其add,remove等,就可以将该题完成。希望以后不会出现这种情况,可以将题目完成。

 

posted @ 2022-06-11 23:02  Rain_and_shine_cat  阅读(135)  评论(0)    收藏  举报