欢迎来到三年代码五年模拟的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
我的首页  

前言:
前三章的知识点:第一章—输入输出格式,学会使用JAVA语言编写程序,了解Scanner输入函数的用法,难度较低
第二章—学会使用字符串,字符串的用法,substring的用法,初步了解正则函数,难度适中
第三章—熟悉类的用法,面对对象,建立多个类,有父类和子类,难度较高
 

第一次大作业

7-2 长度质量计量单位换算(分数 5)
作者 蔡轲
单位 南昌航空大学
长度、质量的计量有多重不同的计算体系,有标准的国际单位制:千克与米,也有各个国家自己的计量方法如:磅、英寸;1磅等于0.45359237千克,1英寸等于0.0254米,请编写程序实现国际单位制与英制之间的换算。

输入格式:
两个浮点数,以空格分隔,第一个是质量(以千克为单位)、第二个是长度(以米为单位)。例如:0.45359237 0.0254。

输出格式:
两个浮点数,以空格分隔,第一个是质量(以磅为单位)、第二个是长度(以英寸为单位)。例如:1.0 1.0。

输入样例:
在这里给出一组输入。例如:

0.45359237 0.0254
1
输出样例:
在这里给出相应的输出。例如:

1.0 1.0
1
我的代码如下:

import java.util.*;
public class Main{
public static void main(String args[]){
Scanner scanner=new Scanner(System.in);
double zl=scanner.nextDouble();
double cd=scanner.nextDouble();

// while(zl=0.45359237)
zl=zl/0.45359237;
// while(cd=0.0254)
cd=cd/0.0254;
System.out.print((float)zl+" "+(float)cd);
}
}


测试结果

 

 圈复杂度测试

 踩坑心得:
第二道题主要是需要注意类型转换,由double类转为float类,在输出语句中直接转换类型即可。出现错误原因是因为最开始是double类,计算之后直接输出,导致精度有误,在查阅资料后了解到可以在输出的时候通过“(类型)元素”的方式直接输出想要的精度

 

第二次大作业

7-2 串口字符解析
分数 40
作者 蔡轲
单位 南昌航空大学

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

输入格式:

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

输出格式:

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

输入样例:

在这里给出一组输入。例如:

1111011101011111111111
 

输出样例:

在这里给出相应的输出。例如:

1:11101011
 

输入样例1:

在这里给出一组输入。例如:

11110111010111111001001101111111011111111101111
 

输出样例1:

在这里给出相应的输出。例如:

1:11101011
2:01001101
3:validate error
 

输入样例2:

输入数据不足11位。例如:

111101
 

输出样例2:

在这里给出相应的输出。例如:

null data
 

输入样例3:

输入数据全1没有起始位。例如:

1111111111111111
 

输出样例3:

在这里给出相应的输出。例如:

null data
 

输入样例4:

输入数据全1没有起始位。例如:

111101110101111111101111111101
 

输出样例4:

在这里给出相应的输出。例如:

1:11101011
2:parity check error
 

输入样例5:

两组数据结束符和奇偶校验均不合格。例如:

111000000000000011100000000000000
 

输出样例5:

在这里给出相应的输出。例如:

1:validate error
2:validate error
 

输入样例6:

两组数据,数据之间无空闲位。例如:

1110000000001100111000001
 

输出样例6:

在这里给出相应的输出。例如:

1:00000000
2:01110000、

我的代码如下:

import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
String sj = scanner.next();
int cd = sj.length();
char ch[] = sj.toCharArray();
int m = 0, n = 1, count = 0;
int val = 0;
int par = 0;
if (cd < 11) {
System.out.println("null"+" "+"data");
return;
}
else {
for (m = 0; m < cd - 10; m++) {
if (sj.charAt(m) == '0') {
System.out.print(n + ":");
n++;
if (ch[m+10] != '0'){
val = 0;
count = 0;
for (int h = m + 1; h < m + 9; h++) {
if (ch[h] == '1') {
count++;
}
}
if (count % 2 == 0) {
if (ch[m+9] == '1') {
par = 0;
}
else {
par = 1;
}
}
else {
if (ch[m+9] == '0')
par = 0;
else
par = 1;
}
}
else {
val = 1;
}
if (val == 0) {
if (par == 0)
System.out.println(sj.substring(m + 1, m + 9));
else
System.out.println("parity "+"check "+"error");
}
else
System.out.println("validate "+"error");
m+=10;
}
}
if(sj.matches("^[1]*$")) {
System.out.printf("null "+"data");
return;
}
}
}
}

 

错误点:

在运行每个样例之后均无误,但是测试之后发现非数字也能使用

 

 问题原因在于没有规定只能使用数字,加入正则表达式后,输出无误

 

 圈复杂度结果:

 判断条件太大,全部聚集到一个类里面导致的

踩坑心得:

PTA的机制问题,使用正则函数会规避掉很多格式错误,不使用正则函数,用自己的方式进行判断会漏掉一些条件,导致一些格式错误。

第三次大作业

7-1 点线形系列1-计算两点之间的距离
分数 10
作者 蔡轲
单位 南昌航空大学

输入连个点的坐标,计算两点之间的距离

输入格式:

4个double类型的实数,两个点的x,y坐标,依次是x1、y1、x2、y2,两个点的坐标之间以空格分隔,每个点的x,y坐标以英文“,”分隔。例如:0,0 1,1或0.1,-0.3 +3.5,15.6。
若输入格式非法,输出"Wrong Format"。
若输入格式合法但坐标点的数量超过两个,输出“wrong number of points”。

输出格式:

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

输入样例:

整数输入。例如:

0,0 1,1
 

输出样例:

在这里给出相应的输出。例如:

1.4142135623730951
 

输入样例1:

带符号double类型实数输入。例如:

+2,-2.3 0.9,-3.2
 

输出样例1:

在这里给出相应的输出。例如:

1.42126704035519
 

输入样例2:

格式非法。例如:

++2,-2.3 0.9,-3.2
 

输出样例2:

在这里给出相应的输出。例如:

Wrong Format
 

输入样例3:

点的数量超过两个。例如:

+2,-2.3 0.9,-3.2 +2,-2.3
 

输出样例3:

在这里给出相应的输出。例如:

wrong number of points

 

错误点:

没有用正则表达式导致格式出现错误,但是加上之后只是加了三分,还有一分的问题一直没有找到

 

 

我的代码如下:

import java.util.*;
class ZFC{
double x;
double y;
}
public class Main{
public static void main(String []args){
Scanner scanner = new Scanner(System.in);
String zb = scanner.nextLine();
int count=0;
int cd=zb.length();
char []ch=zb.toCharArray();
String y[]=zb.split(" |,|:");
for(int i=0;i<y.length;i++)
{
if(!y[i].matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")){
//判断格式是否合法,不合法则结束
System.out.print("Wrong Format");
return;
}
}

for(int i=0;i<cd;i++)
{
if(ch[i]==',') {
count++;
}

}
if(count==0){
System.out.println("Wrong Format");
return;
}
double en=0;
int t1=0;
int t2=0;
int t3=0;
int t4=0;
String[] stl = zb.split(" ",count);
String[] a = stl[0].split(",",2);
String[] b= stl[1].split(",",2);
String c=a[0];
String d=a[1];
String e=b[0];
String f=b[1];
char []r=c.toCharArray();
char []r1=d.toCharArray();
for(int g=0;g<c.length();g++){
if(r[g]>='0'&&r[g]<='9'||r[g]=='.')
break;
else
t1++;
}

for(int h=0;h<d.length();h++){
if((r1[h]>='0'&&r1[h]<='9')||r1[h]=='.')
break;
else
t2++;
}

for(int m=0;m<e.length();m++){
if((!e.matches("^[0-9]*$"))||e.charAt(m)=='.')
break;
else
t3++;
}
for(int n=0;n<f.length();n++){
if((!f.matches("^[0-9]*$"))||f.charAt(n)=='.')
break;
else
t4++;
}
if(t4>1||t1>1||t3>1||t2>1){
System.out.print("Wrong Format");
return;
}
else if(count!=2) {
System.out.println("wrong number of points");
System.exit(0);
}
else if(e.contains(" ")||f.contains(" ")||c.contains(" ")||d.contains(" ")){
System.out.println("Wrong Format");
return;
}
else{
double x1=Double.parseDouble(c);
double y1=Double.parseDouble(d);
double x2=Double.parseDouble(e);
double y2=Double.parseDouble(f);
ZFC q=new ZFC();
q.x=(x1-x2)*(x1-x2);
q.y=(y1-y2)*(y1-y2);
en = Math.sqrt(q.x+q.y);
System.out.println(en);
}
}
}




圈复杂度结果:

 

 判断条件太大,全部聚集到一个类里面导致的

踩坑心得:PTA的机制问题,使用正则函数会规避掉很多格式错误,不使用正则函数,用自己的方式进行判断会漏掉一些条件,导致一些格式错误。

7-2 点线形系列2-线的计算
分数 42
作者 蔡轲
单位 南昌航空大学

用户输入一组选项和数据,进行与直线有关的计算。选项包括:
1:输入两点坐标,计算斜率,若线条垂直于X轴,输出"Slope does not exist"。
2:输入三个点坐标,输出第一个点与另外两点连线的垂直距离。
3:输入三个点坐标,判断三个点是否在一条线上,输出true或者false。
4:输入四个点坐标,判断前两个点所构成的直线与后两点构成的直线是否平行,输出true或者false.
5:输入四个点坐标,计算输出前两个点所构成的直线与后两点构成的直线的交点坐标,x、y坐标之间以英文分隔",",并输出交叉点是否在两条线段之内(不含四个端点)的判断结果(true/false),判断结果与坐标之间以一个英文空格分隔。若两条线平行,没有交叉点,则输出"is parallel lines,have no intersection point"。

输入格式:

基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。
例如:1:0,0 1,1
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
不论哪个选项,如果格式、点数量都符合要求,但构成任一条线的两个点坐标重合,输出"points coincide",

输出格式:

见题目描述。

输入样例1:

选项1,两点重合。例如:

1:-2,+5 -2,+5
 

输出样例:

在这里给出相应的输出。例如:

points coincide
 

输入样例2:

选项1,斜率无穷大的线。例如:

1:-2,3 -2,+5
 

输出样例:

在这里给出相应的输出。例如:

Slope does not exist
 

输入样例3:

选项1,斜率无穷大。例如:

1:-2,3 -2,+5
 

输出样例:

在这里给出相应的输出。例如:

Slope does not exist
 

输入样例4:

选项1,符合格式输入,带符号/不带符号数混合。例如:

1:-2.5,3 -2,+5.3
 

输出样例:

在这里给出相应的输出。例如:

4.6
 

输入样例5:

选项2,计算第一个点到另外两点连线的垂直距离。例如:

2:0,1 1,0 2,0
 

输出样例:

在这里给出相应的输出。例如:

1.0
 

输入样例6:

选项3,判断三个点是否在一条线上。例如:

3:0,1 2,2 5,3
 

输出样例:

在这里给出相应的输出。例如:

false
 

输入样例7:

选项4,判断两条线是否平行。例如:

4:0,1 0,2 2,1 3,0 
 

输出样例:

在这里给出相应的输出。例如:

false
 

输入样例8:

选项5,判断两条线的交点。例如:

5:0,0 -1,-1 0,2 3,-1
 

输出样例:

在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:

1.0,1.0 true
 

输入样例9:

选项5,判断两条线的交点。但两条线平行例如:

5:0,0 -1,-1 2,3 3,4
 

输出样例:

在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:

is parallel lines,have no intersection point

错误点:

没有用正则表达式导致格式出现错误,但是加上之后只是加了格式问题,输出有误的地方代码逻辑没有问题,没找到改的地方。

结果如下:

我的代码如下:

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String st ="";
st =scanner.nextLine();
int k=0,count=0;
String []st1=st.split("\\:|\\,|\\ ");
double []st2=new double [st1.length];
for(int i=0;i<st1.length;i++) {
st2[i]=Double.parseDouble(st1[i]);
k++;
}
int num=st.length();
char arg[]=st.toCharArray();
for(int i=0;i<num;i++){
if(arg[i]==','){
count++;
}
}
for(int i=0;i<st1.length;i++)
{
if(!st1[i].matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")){
//判断格式是否合法,不合法则结束
System.out.print("Wrong Format");
return;
}
}

for(int i=0;i<num;i++) {
if((arg[i]=='+'&&arg[i+1]=='+')||(arg[i]==','&&arg[i+1]==' ')||(arg[i]=='-'&&arg[i+1]=='-')||(arg[i]=='+'&&arg[i+1]=='-')) {
System.out.println("Wrong Format");
return;
}
}
/*
for(int j=0;j<num;j++){
if((arg[j]==' '&&arg[j+1]=='.')||(arg[j]==','&&arg[j+1]==',')||(arg[j]=='.'&&arg[j+1]==' ')||(arg[j]=='+'&&arg[j+1]==',')){
System.out.println("Wrong Format");
return;}
}
*/
int s1=0;
int s2=0;
int s3=0;
int e=0;
for(int x = 0;x<st.length();x++)
{

if(st.charAt(x) == ',')
s1++;
else if(st.charAt(x)==':')
s2++;
else if(st.charAt(x)<=9)
s3++;
}

if(s2!=1||s3%2!=0||st.charAt(0)>'5')
{
System.out.print("Wrong Format");
return;
}/*
for(int i=0;i<num;i++)
{
if((arg[i]=='.'&&arg[i+1]==' '))
{
System.out.println("Wrong Format");
return;
}
}
if(count!=2){
System.out.println("Wrong Format");
return;
}
if(arg[1]!=':'||arg[0]>'5') {
System.out.println("Wrong Format");
return;
}
for(int j=0;j<num;j++){
if((arg[j]==':'&&arg[j+1]=='.')||(arg[j]==':'&&arg[j+1]==',')||(arg[j]=='.'&&arg[j+1]==' ')||(arg[j]==' '&&arg[j+1]==' ')){
System.out.println("Wrong Format");
return;}
}
*/
if(arg[0]=='1'&&k!=5) {
System.out.println("wrong number of points");
return;
}
if(arg[0]=='2'&&k!=7) {
System.out.println("wrong number of points");
return;
}
if(arg[0]=='3'&&k!=7) {
System.out.println("wrong number of points");
return;
}
if(arg[0]=='4'&&k!=9) {
System.out.println("wrong number of points");
return;
}
if(arg[0]=='5'&&k!=9) {
System.out.println("wrong number of points");
return;
}
if(st2[1]==st2[3]&&st2[2]==st2[4])
{
System.out.println("points coincide");
return;
}
if(st2[0]==1) {
ca(st2[1],st2[2],st2[3],st2[4]);
}
if(st2[0]==2) {
cdhj(st2[1],st2[2],st2[3],st2[4],st2[5],st2[6]);
}
if(st2[0]==3) {
juel(st2[1],st2[2],st2[3],st2[4],st2[5],st2[6]);
}
if(st2[0]==4) {
jpgh(st2[1],st2[2],st2[3],st2[4],st2[5],st2[6],st2[7],st2[8]);
}
if(st2[0]==5) {
jud(st2[1],st2[2],st2[3],st2[4],st2[5],st2[6],st2[7],st2[8]);
}
}

public static void ca(double x1,double y1,double x2,double y2) {
double k =(y1-y2)/(x1-x2);
if(x1==x2) {
if (y1 == y2)
System.out.println("points coincide");
else
System.out.println("Slope does not exist");
}
else
System.out.println(k);
}
public static void cdhj(double x1,double y1,double x2,double y2,double x3,double y3) {
double d;
d=Math.abs((y3-y2)*x1+(x2-x3)*y1+x3*y2-y3*x2)/Math.sqrt(Math.pow(y3-y2, 2)+Math.pow(x3-x2, 2));
if(x2==x3&&y2==y3){
System.out.println("points coincide");
return;
}
System.out.println(d);
}
public static void juel(double x1,double y1,double x2,double y2,double x3,double y3) {
if(x2==x3&&y2==y3){
System.out.println("points coincide");
return;
}
if((x1==x2&&x2==x3)||y1==y2&&y2==y3) {
System.out.println("true");}
else if((y1-y2)/(x1-x2)==(y2-y3)/(x2-x3)) {
System.out.println("true");}
else
System.out.println("false");
}
public static void jpgh(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) {
if(x1==x2&&y1==y2){
System.out.println("points coincide");
return;
}
if(x3==x4&&y3==y4){
System.out.println("points coincide");
return;
}
if((y1-y2)/(x1-x2)==(y3-y4)/(x3-x4)) {
System.out.println("true");}
else
System.out.println("false");
}
public static void jud(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) {
if((y1-y2)/(x1-x2)==(y3-y4)/(x3-x4)) {
System.out.println("is parallel lines,have no intersection point");
return;
}
else
{
double r1=y2-y1;
double h1=x2-x1;
double c1=x1*y2-x2*y1;
double r2=y4-y3;
double h2=x4-x3;
double c2=x3*y4-x4*y3;
double d=r1*h2-r2*h1;
double f=(h2*c1-h1*c2)/d;
double f1=(r2*c1-r1*c2)/d;
System.out.print(f+ "," + f1);
if(f>= x1 &&f <= x2&&f >= x3&&f <= x4&&f >= y1 && f<= y2 &&f >= y3&&f<= y4)
{
System.out.print(" true");
}
else
System.out.print(" false");
}
}
}

圈复杂度:

 

 判断条件太大,大部分聚集到一个类里面导致的

踩坑心得:

类的使用,可以大大减少主类的复杂度,会使得代码更加清晰,判断条件堆积在一个类里面会导致圈复杂度大大增加。

7-3 点线形系列3-三角形的计算
分数 48
作者 蔡轲
单位 南昌航空大学

用户输入一组选项和数据,进行与三角形有关的计算。选项包括:
1:输入三个点坐标,判断是否是等腰三角形、等边三角形,判断结果输出true/false,两个结果之间以一个英文空格符分隔。
2:输入三个点坐标,输出周长、面积、重心坐标,三个参数之间以一个英文空格分隔,坐标之间以英文","分隔。
3:输入三个点坐标,输出是钝角、直角还是锐角三角形,依次输出三个判断结果(true/false),以一个英文空格分隔,
4:输入五个点坐标,输出前两个点所在的直线与三个点所构成的三角形相交的交点数量,如果交点有两个,则按面积大小依次输出三角形被直线分割成两部分的面积。若直线与三角形一条线重合,输出"The point is on the edge of the triangle"
5:输入四个点坐标,输出第一个是否在后三个点所构成的三角形的内部(输出in the triangle/outof triangle)。
必须使用射线法,原理:由第一个点往任一方向做一射线,射线与三角形的边的交点(不含点本身)数量如果为1,则在三角形内部。如果交点有两个或0个,则在三角形之外。若点在三角形的某条边上,输出"on the triangle"

输入格式:

基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

输出格式:

基本输出格式见每种选项的描述。
异常情况输出:
如果不符合基本格式,输出"Wrong Format"。
如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
如果输入的三个点无法构成三角形,输出"data error"。
注意:输出的数据若小数点后超过6位,只保留小数点后6位,多余部分采用四舍五入规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333333,1.0按格式输出为1.0

选项4中所输入线的两个点坐标重合,输出"points coincide",

输入样例1:

选项4,定义线的两点重合。例如:

4:1,0 1,0 0,0 2,0 4,0
 

输出样例:

在这里给出相应的输出。例如:

points coincide
 

输入样例2:

选项4,构成三角形的三个点在一条线上,无法构成三角形。例如:

4:1,0 0,2 0,0 0,0 4,0
 

输出样例:

在这里给出相应的输出。例如:

data error
 

输入样例3:

选项1,判断等腰、等边三角形。例如:

1:-2,0 2,0 0,4
 

输出样例:

两个判断结果。例如:

true false
 

输入样例4:

选项2,输出边长、面积、重心坐标。例如:

2:0,0 3,0 0,1
 

输出样例:

在这里给出相应的输出。例如:

7.162278 1.5 1.0,0.333333
 

输入样例5:

选项3,钝角、直角、锐角的判断。例如:

3:0,1 1,0 2,0
 

输出样例:

在这里给出相应的输出。例如:

true false false
 

输入样例6:

选项4,直线与三角形交点的数量等于2,输出数量值以及三角形被分割的两部分面积。例如:

4:1,0 0,2 0,0 0,2 4,0
 

输出样例:

在这里给出相应的输出。例如:

2 1.0 3.0
 

输入样例7:

选项4,直线与三角形交点的数量少于两个,只输出数量值。例如:

4:-1,0 1,2 0,1 0,-1 2,0
 

输出样例:

在这里给出相应的输出。例如:

1
 

输入样例8:

选项5,用射线法判断点是否在三角形内部。例如:

5:0.5,0.5 0,0 0,2 4,0
 

输出样例:

在这里给出相应的输出,交点坐标之间以英文","分隔,判断结果与坐标之间以一个英文空格分隔。例如:

in the triangle
 

输入样例9:

选项5,用射线法判断点是否在三角形内部。例如:

5:0,0 -1,-1 2,3 3,4
 

输出样例:

在这里给出相应的输出。例如:

outof the triangle

 

错误点:

没有用正则表达式导致格式出现错误,最开始创建的类多,函数多导致出现指针错误,采用了父类和子类的方式来进行修改。

 

 

 修改后运行每个例子没有问题但是还是没有满分
我的代码如下:

import java.util.*;


class P{
public double n, m;

public P(){
this.n = 0;
this.m = 0;
}
public P(double a,double b){
this.n = a;
this.m = b;
}

public void print(){ //打印
System.out.print(this.n+this.m);
}


//判断两点是否相同
public boolean isSameTo(P a){
return (this.n == a.n)&&(this.m == a.m);
}
//两点距离
public double distan(P an){
double m=Math.pow(this.n-an.n,2);
double m1=Math.pow(this.m-an.m,2);
return Math.sqrt( m+ m1);
}

//两点斜率
public double Sl(P an){
if(this.n == an.n)
return 2^48;
return ((this.m - an.m)) / ((this.n - an.n));
}

//点到直线的垂直距离
public double diss(Line l){
return Math.abs(l.a*this.n+l.b*this.m+l.c) / Math.sqrt(Math.pow(l.a,2)+Math.pow(l.b,2));
}

//三点在同一条直线上
public boolean inLine(P a1,P a2){
Line l = new Line(a1,a2);
return this.diss(l)==0;
}

}


class Line extends P {
public P st, ed;
public double a,b,c;

public Line(P a,P b){
this.st = a;
this.ed = b;
this.a = (-(a.m-b.m));
this.b = (a.n-b.n);
this.c = (-this.a*this.st.n-this.b*this.st.m);
}


//判断是否平行

public boolean isCraw(Line ano){
if(this.b==0 || ano.b==0){
return (this.b == 0 && ano.b == 0);
}
return ((this.a / this.b) == (ano.a / ano.b));
}


//判断是否重合(平行+c值相等)
public boolean isSameTo(Line another){
return this.isCraw(another) && (this.c==another.c);
}

//求两条直线交点(求交点的一个公式,无非就是联立两方程之后求解)
public P getInter(Line another){
//特判平行的情况,返回null值
if(this.isCraw(another)){
return null;
}
P result = new P();
result.m = (another.a*this.c-this.a*another.c) / (this.a*another.b-another.a*this.b);
result.n = (this.b*another.c-another.b*this.c) / (this.a*another.b-another.a*this.b);
return result;
}

//判断某点是否在线段之内(不包括端点)
public boolean inLineSe(P pj){
//其实还需要p.inline(this)判断一下点是否在直线之上,偷个懒,但是也能过题
if(!this.inLine(pj)) return false;
if(pj.n == this.st.n && pj.m == this.st.m) {
return false;
}
if(pj.n == this.ed.n && pj.m == this.ed.m) {
return false;
}
double result = pj.distan(this.st) + pj.distan(this.ed) - this.length();
//
return (Math.abs(result) < 0.000001);
}

//判断点是否在线段之内(包括端点)
public boolean inLineSegmen(P pd){
if(!this.inLine(pd)) {
return false;
}
double result = pd.distan(this.st) + pd.distan(this.ed) - this.length();
return (Math.abs(result) < 0.000001);
}
public void print(){
System.out.printf("%fX + %fY + %f = 0\n",this.a,this.b,this.c);
}


public double length(){
return this.st.distan(this.ed);
}
//某点在直线之上
public boolean inLine(P p){
return Math.abs(this.a*p.n + this.b*p.m + this.c) <0.000001;
}


}

class Tri extends P {
public P a1,b1,c1;
public Line ab,ac,bc;
//析构函数
public Tri(P a, P b, P c){
this.a1 = a;
this.b1 = b;
this.c1 = c;
this.ab = new Line(a,b);
this.ac = new Line(a,c);
this.bc = new Line(b,c);
}

public void print(){
this.a1.print();
this.b1.print();
this.c1.print();
}

//判断是否为等腰三角形(任意两边相等,浮点数最好慎用 == )
public boolean isIsoscelesTriangle(){
return this.ab.length() == this.ac.length() ||
this.ac.length() == this.bc.length()||
this.ab.length() == this.bc.length() ;
}
//判断是否为等边三角形(三边相等)
public boolean isEquilateralTriangle(){
return this.ab.length() == this.ac.length() &&
this.ac.length() == this.bc.length();
}
//求三角形的边长(三边长度求和)
public double sideLength(){
return this.ab.length() + this.ac.length() + this.bc.length();
}
//求三角形面积(海伦公式)
public double area(){
double p = this.sideLength() / 2;
return Math.sqrt(p*(p-this.ab.length())*(p-this.ac.length())*(p-this.bc.length()));
}
//求三角形的重心(重心公式)
public P focusPoint(){
P re = new P();
re.n = (this.a1.n + this.b1.n + this.c1.n) / 3;
re.m = (this.a1.m + this.b1.m + this.c1.m) / 3;
return re;
}
//求三角形类型,(锐角0,直角1,钝角2)
// A2 + B2 (<=>) C2
public int type(){
double[] num = new double[3];
num[0] = this.ab.length();num[1] = this.ac.length();num[2] = this.bc.length();
Arrays.sort(num);
double tmp = Math.pow(num[0],2) + Math.pow(num[1],2) - Math.pow(num[2],2);
if(Math.abs(tmp) < 0.0000001) return 1;
if(tmp < 0) return 2;
return 0;
}
// 判断某点是否在三角形之内,(0内,1边,2外);
//面积公式判断
public int isContain(P p){
Tri t1 = new Tri(this.a1,this.b1,p);
Tri t2 = new Tri(this.b1,this.c1,p);
Tri t3 = new Tri(this.c1,this.a1,p);
double s = this.area() - t1.area() - t2.area() - t3.area();
if(Math.abs(t1.area()) < 0.000001 || Math.abs(t2.area()) < 0.000001 || Math.abs(t3.area()) < 0.000001)
return 1;
if(Math.abs(s) < 0.000001) return 0;
return 2;
}
}

 

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();

//判断输入格式是否正确
String[] y = s.split(" |,|:");
for (int i = 0; i < y.length; i++) {
if (!y[i].matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")) {
//判断格式是否合法,不合法则结束
System.out.print("Wrong Format");
return;
}
}

//取出cmd,将串转化为浮点型

int cmd = s.charAt(0) - '0';
s = s.substring(2).trim();
String[] tmp = s.split(" |,");
double[] till = new double[30];
int cnt = 0;
for (String a : tmp) {
if (!ck(a)) {
System.out.println("Wrong Format");
return;
}
till[cnt++] = Double.parseDouble(a);
}

//将浮点型转化为坐标点型
P[] po = new P[10];
for (int i = 0; i < cnt; i += 2) {
po[i / 2] = new P(till[i], till[i + 1]);
}

//特判(坐标点数量非法)
if (cmd == 1 || cmd == 2 || cmd == 3) {
if (cnt != 6) {
System.out.println("wrong number of points");
return;
}
Tri t = new Tri(po[0], po[1], po[2]);
if (t.area() == 0) {
System.out.println("data error");
return;
}
}
if (cmd == 4) {
if (cnt != 10) {
System.out.println("wrong number of points");
return;
}
Tri t = new Tri(po[2], po[3], po[4]);
if (po[0].isSameTo(po[1])) {
System.out.println("points coincide");
return;
}
if (t.area() == 0) {
System.out.println("data error");
return;
}
}
if (cmd == 5) {
if (cnt != 8) {
System.out.println("wrong number of points");
return;
}
Tri t = new Tri(po[1], po[2], po[3]);
if (t.area() <= 0.00001) {
System.out.println("data error");
return;
}
}


//题目要求
switch (cmd) {
case 1:
if (cmd == 1) {
Tri t = new Tri(po[0], po[1], po[2]);
System.out.printf("%s %s\n", t.isIsoscelesTriangle(), t.isEquilateralTriangle());
}
case 2:
if (cmd == 2) {
Tri t = new Tri(po[0], po[1], po[2]);
System.out.printf("%s %s %s,%s\n", cnm(t.sideLength()), cnm(t.area()), cnm(t.focusPoint().n), cnm(t.focusPoint().m));
}
case 3:
if (cmd == 3) {
Tri t = new Tri(po[0], po[1], po[2]);
System.out.printf("%s %s %s", t.type() == 2, t.type() == 1, t.type() == 0);
}
case 4:
if (cmd == 4) {
Line l = new Line(po[0], po[1]);
Tri t = new Tri(po[2], po[3], po[4]);
//与任意一条边重合
if (l.isSameTo(t.ab) || l.isSameTo(t.ac) || l.isSameTo(t.bc)) {
System.out.println("The point is on the edge of the triangle");
return;
}
//与三条边的交点(值可能为null,即平行)
P p_ab = l.getInter(t.ab);
P p_ac = l.getInter(t.ac);
P p_bc = l.getInter(t.bc);

//三交点是否位于边之内
boolean p_ab_in = false, p_ac_in = false, p_bc_in = false;
if (p_ab != null) p_ab_in = t.ab.inLineSe(p_ab);
if (p_ac != null) p_ac_in = t.ac.inLineSe(p_ac);
if (p_bc != null) p_bc_in = t.bc.inLineSe(p_bc);


//任一角在直线之上(特判三角形的角)
if (l.inLine(t.a1)) {
//与另一条边无交点或者交点在边之外
if (p_bc == null || !t.bc.inLineSegmen(p_bc)) {
System.out.println("1");
} else {
pr_ans(t, t.a1, t.b1, p_bc);
}
return;
}
if (l.inLine(t.b1)) {
if (p_ac == null || !t.ac.inLineSegmen(p_ac)) {
System.out.println("1");
} else {
pr_ans(t, t.a1, t.b1, p_ac);
}
return;
}
if (l.inLine(t.c1)) {
if (p_ab == null || !t.ab.inLineSegmen(p_ab)) {
System.out.printf("1");
} else {
pr_ans(t, t.a1, t.c1, p_ab);
}
return;
}

//两个交点
if (p_ab_in && p_bc_in) {
pr_ans(t, t.b1, p_ab, p_bc);
return;
}
if (p_ab_in && p_ac_in) {
pr_ans(t, t.a1, p_ab, p_ac);
return;
}
if (p_bc_in && p_ac_in) {
pr_ans(t, t.c1, p_bc, p_ac);
return;
}
//无交点
System.out.printf("0");
}

case 5:
if (cmd == 5) {
Tri t = new Tri(po[1], po[2], po[3]);
int vio = t.isContain(po[0]);
if (vio == 0) {
System.out.print("in the triangle");
System.out.println("");
return;
}
if (vio == 1) {
System.out.println("on the triangle");
System.out.println("");
return;
}
if (vio == 2) {
System.out.println("outof the triangle");
System.out.println("");
return;
}
}
}
}
public static boolean ck(String std){
// System.out.println("debug"+str);
return std.matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$");
}
public static void pr_ans(Tri t, P a,P b,P c){
Tri tmp_t =new Tri(a,b,c);
double[] ansgh = new double[2];
ansgh[0] = tmp_t.area();
ansgh[1] = t.area() - tmp_t.area();
Arrays.sort(ansgh);
System.out.printf("2 %s %s\n",cnm(ansgh[0]),cnm(ansgh[1]));
System.out.print("");
}

public static String cnm(double a){
String result = String.format("%.6f",a);
result = result.replaceAll("0+?$", "");
if(result.charAt(result.length()-1) == '.') {
result+='0';
}
return result;
}
}

我的结果截屏:

 

 圈复杂度结果:

 

 设置了多个类,类里面有很多判定条件,导致圈复杂度较高。

 

踩坑心得:

类的使用,可以大大减少主类的复杂度,会使得代码更加清晰,判断条件堆积在一个类里面会导致圈复杂度大大增加。

 

 

建议:

PTA 的测试点建议不要卡太死,会减少代码的灵活性,使得只有少数代码能通过。建议设置测试点的时候减少与题干的矛盾,导致代码检测时出现一些不必要的测试点错误!万分感谢!敬礼!

总体总结:

通过这三次大作业掌握了Scanner,字符串,数组的用法,学习了一部分正则表达式,个人认为正则表达式不太能很好的运用,不是很会使用,日后会多努力尝试。整体而言,前两次作业较为基础,第三次作业比较难,主要可能和数学理解有关,代码逻辑没有太大问题

 



posted on 2022-09-29 12:41  三年代码五年模拟  阅读(166)  评论(0编辑  收藏  举报