加载中...

博客作业

博客作业1

前言:

第一次接触Java,对类的理解和运用都很生涩。最开始甚至是用c的方式Java的外壳写的代码(最开始的作业比较简单)也就糊弄过去了......不过在后面的作业中渐渐得开始对类的理解加深和运用熟练,也对面向对象有了初步的理解。

作业题量相对合理:量大简单,量少困难。

作业的难度从开始的简单(新手村)往后难度递增。

设计与分析:

题目7-2:串口字符解析

RS232是串口常用的通信协议,在异步通信模式下,串口可以一次发送58位数据,收发双方之间没有数据发送时线路维持高电平,相当于接收方持续收到数据“1”(称为空闲位),发送方有数据发送时,会在有效数据(58位,具体位数由通信双方提前设置)前加上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

输入样例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

解题思路:

对输入的二进制数据流分析——分块

1:找到起始位——第一个出现的 ‘0’

2:‘0‘-后面的八位——数据内容(有效数据)

3:’0‘-后面的第九位——奇偶校验位

4:’0‘-后面的第十位——结束位

0-10101010-1-1

先判断是否是数据为空,否则找到起始的’0’之后提取‘0’后面的十位数据。这里先进行结束位的判断因为只要结束位错误就是“validate error”。在进行奇偶位判断如果错误输出,否则输出有效数据(8位),注意一下每个结果前面加“num:”。
以下是代码详情:

import java.util.*;

public class Main {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		String s;
		int sc = 1;
		int len = 0,n=0;		//字符串长度
		Scanner in = new Scanner (System.in);
		s = in.nextLine();
		int lacate = 0;
		int time = 1;
		final int MixLen = 11;
		if(s.length()<MixLen||s.indexOf("0") == -1||(s.indexOf("0")+10>=s.length())) 				//无效信息  null
		{
			System.out.println("null data");
			return ;
		}
		if(s.charAt(0) == '0')									//开头没有1(空闲位)
		{
			int count = 0;
			if(s.charAt(10) != '1')
			{
				System.out.println(time+":validate error");
				time++;
				len = 10;
			}
			else 
			{
				for(int i=1;i<9;i++)
					{
						if(s.charAt(i) == '1')
						{
									count++;
						}
					}
					if((count%2 == 0 && s.charAt(9) == '0')||(count%2 == 1 && s.charAt(9) == '1'))
					{
						System.out.println(time+":parity check error");
						time++;
						len = 10;                                 //更新len
					}
					else 
					{
						System.out.println(time+":"+s.substring(1, 9));
						time++;
						len = 10;                                //更新len
					}
				}	
		}
		
			for(	;len<s.length()-10;	)
			{
					n = s.indexOf("0", len+1);
					//System.out.println("n = "+n);
				if(n != -1)                          // 有效
				{
					if(s.charAt(n+10) != '1')							//结束位不合理,输出
					{
						System.out.println(time+":validate error");
						time++;
						len = n+10;                                     //更新len
					}
					else												//结束位合理
					{
						int count = 0;
						for(int j = n+1;j< n+9;j++)
						{
							if(s.charAt(j) == '1')
							{
								count++;
							}
						}
						if((count%2 == 0 && s.charAt(n+9) == '0')||(count%2 == 1 && s.charAt(n+9) == '1'))
						{
							System.out.println(time+":parity check error");
							time++;
							len = n+10;                                 //更新len
						}
						else 
						{
							System.out.println(time+":"+s.substring(n+1, n+9));
							time++;
							len = n+10;                                //更新len
						}
					}
					
				}
				else
				{
					return ;
				}
			}
			
		}

/*	
	public static int jiou(int n,String s)							//奇偶校验
	{
		int i = n,count = 0;
		for(	;i<n+9;i++)
		{
			if(s.charAt(i) == '1')
			{
				count++;
			}
		}
		return count%2;
	}
}
*/

踩坑心得:

这里博主猪脑子没读清楚题目,以为起始标志是“10”所以刚开始通过不了无空闲位的测试点,后面搞清楚就好了,起始标志改为‘0’就好了。老是乱读题目已经是博主的老毛病了,大家引以为戒!

7-1 点线形系列1-计算两点之间的距离

输入格式:

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

输出格式:

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

输入样例:

整数输入。例如:

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

踩坑心得:

这里就不上传代码了,这题还是比较简单。注意正则表达式就好了,这里给出两个不能匹配的两个例子。

+2,-2.3 0.,-3.2 //错误案例
+2,-2.3 0.0,-3.2

这里“0.”和“0.0”都应该是错误的。

这是博主的正则表达式(单个数值):

"(\\+|\\-)?(0|(0\\.[1-9]{1})|[1-9][0-9]*(\\.\\d+)?|0\\.[0-9]{2,})"

这里关于正则表达式如果大家不懂的可以去自行学习。

7-2 点线形系列2-线的计算

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

输入格式:

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

输出格式:

见题目描述。

输入样例1:

选项1,两点重合。例如

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

输出样例:

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

points coincide

输入样例2:

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

1:-2,3 -2,+5

输出样例:

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

Slope does not exist

输入样例3:

选项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

这里给出我写的点的类和线的类:

class Lines
{
	Points D1,D2;
	double A,B,C;
	public Lines(Points p,Points q)
	{
		this.D1 = p;
		this.D2 = q;
		if(p.x!=q.x)
		{
			this.A = this.D2.y-this.D1.y;
			this.B = this.D1.x-this.D2.x;
			this.C = this.D2.x*this.D1.y-this.D1.x*this.D2.y;
		}
		
	}
	public boolean HaveXieLv()						//斜率是否存在
	{
		if(this.D1.x == this.D2.x)
		{
			return false;
		}
		return true;
	}
	public double GetXieLv()					//斜率-A/B
	{
		return -this.A/this.B;
	}
	public double GetPointsToLines(Points p)
	{
		double d = Math.abs(this.A*p.x+this.B*p.y+this.C)/Math.pow(this.A*this.A+this.B*this.B, 0.5);
		return d;
	}
	public boolean LinesToLines(Lines l)
	{
		return(this.A*l.B == this.B*l.A);
	}
	public double GetXCusp(Lines l)
	{
		double x0 = (l.C*this.B-this.C*l.B)/(this.A*l.B-l.A*this.B);
		return x0;
	}
	public double GetYCusp(Lines l)
	{
		double y0 = (this.A*l.C-l.A*this.C)/(this.B*l.A-this.A*l.B);
		return y0;
	}
	public double GetLength()
	{
		return this.D1.PointsToPoints(this.D2);
	}
	public boolean HaveCupsToLines(Lines l)
	{
		return ((!this.HaveXieLv()&&l.HaveXieLv())||(!l.HaveXieLv()&&this.HaveXieLv())||(l.HaveXieLv()&&this.HaveXieLv()&&!this.LinesToLines(l)));
//		return!(this.A*l.B == this.B*l.A);
	}
	public Points GetCupsToLines(Lines l)   //获得两直线的交点(使用时需要确保两直线有交点)
	{
		Points p;
		if(l.HaveXieLv()&&this.HaveXieLv())
		{
			 p = new Points(this.GetXCusp(l),this.GetYCusp(l));
		}
		else
		{
			if(!l.HaveXieLv())
			{
				double x = l.D1.x;
				double y = -(this.A*x+this.C)/this.B;
			    p = new Points(x,y);
			}
			else
			{
				double x = this.D1.x;
				double y = -(l.A*x+l.C)/l.B;
				p = new Points(x,y);
			}
		}
		return p;
	}
	public boolean CuoPiontOnLine(Points p)
	{
		return ((p.x<Math.max(this.D1.x, this.D2.x)&&p.x>Math.min(this.D1.x, this.D2.x))&&(p.y>Math.min(this.D1.y, this.D2.y)&&p.y<Math.max(this.D1.y, this.D2.y)));
	}
}

踩坑心得:

正则表达式的书写正确是成功的开始,保证自己的正则表达式书写正确可以省下很多的时间和精力。

这一题注意下线的类这里还是定义线的时候使用一般式去定义线,这样求平行求交点都会好做一点。这一题我开始用“y=kx+b”定义线结果好多地方都不好求甚至求不出来,建议大家直接用“Ax+By+C=0”,会好做一点!

7-3 点线形系列3-三角形的计算

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

输入格式:

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

输出格式:

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

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

输入样例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

这里给出我写的三角形的类:


class Trianges
{
	Points D1,D2,D3;
	Lines L1,L2,L3;
	double J1,J2,J3;
	public Trianges(Points point1,Points point2,Points point3)
	{
		this.D1 = point1;
		this.D2 = point2;
		this.D3 = point3;
		this.L1 = new Lines(point1,point2);
		this.L2 = new Lines(point2,point3);
		this.L3 = new Lines(point1,point3);
		this.J1 = Math.toDegrees(Math.acos((L2.GetLength()*L2.GetLength()-L1.GetLength()*L1.GetLength()-L3.GetLength()*L3.GetLength())/(-2*L3.GetLength()*L1.GetLength())));
		this.J2 = Math.toDegrees(Math.acos((L3.GetLength()*L3.GetLength()-L1.GetLength()*L1.GetLength()-L2.GetLength()*L2.GetLength())/(-2*L2.GetLength()*L1.GetLength())));
		this.J3 = Math.toDegrees(Math.acos((L1.GetLength()*L1.GetLength()-L2.GetLength()*L2.GetLength()-L3.GetLength()*L3.GetLength())/(-2*L3.GetLength()*L2.GetLength())));
	}
	public boolean IsEquTri()			//是否等边三角形,返回(true/false)
	{
		return (this.L1.GetLength() == this.L2.GetLength()&&this.L2.GetLength() == this.L3.GetLength());
	}
	public boolean IsIsoTri()			//是否等腰三角形,返回(true/false)
	{
		return (this.L1.GetLength() == this.L2.GetLength()||this.L2.GetLength() == this.L3.GetLength()||this.L1.GetLength() == this.L3.GetLength());
	}
	public double GetZhouChang()		//计算三角形周长,返回三角形周长(double)
	{
		return (this.L1.GetLength()+this.L2.GetLength()+this.L3.GetLength());
	}
	public double GetMianJi()			//计算三角形面积,返回三角形面积(double)
	{
		return (this.L1.GetLength()*this.L1.GetPointsToLines(this.D3))/2;
	}
	public Points GetZhongPoint()		//求三角形的重心,返回重心点(Points)
	{
		Points Z = new Points((this.D1.x+this.D2.x+this.D3.x)/3,(this.D1.y+this.D2.y+this.D3.y)/3);
		return Z;
	}
	public boolean IsDunJiao()			//是否是钝角三角形,,返回(true/false)
	{
		double l12 = this.L1.GetLength()*this.L1.GetLength();
		double l22 = this.L2.GetLength()*this.L2.GetLength();
		double l32 = this.L3.GetLength()*this.L3.GetLength();
		return ((l12+l22-l32+1e-6<0)||(l12+l32-l22+1e-6<0)||(l22+l32-l12+1e-6<0));	
	}
	public boolean IsZhiJiao()			//是否是直角三角形,返回(true/false)
	{
		return (Math.abs(J1-90)<=1e-6||Math.abs(J2-90)<=1e-6||Math.abs(J3-90)<=1e-6);
	}
	public boolean IsRuiJiao()			//是否是锐角三角形,返回(true/false)
	{
		return (!(this.IsDunJiao()||this.IsZhiJiao()));
	}
	public boolean LineEquTriangesLine(Lines l)					//线是否与三角形的其中一条边重合
	{
		return ((L1.GetPointsToLines(l.D1)==0&&L1.GetPointsToLines(l.D2)==0)||(L2.GetPointsToLines(l.D1)==0)&&L2.GetPointsToLines(l.D2)==0||(L3.GetPointsToLines(l.D1)==0&&L3.GetPointsToLines(l.D2)==0));
	}
	public boolean LinesPointOnTriPoint(Lines l)				//直线与三角形的交点是否在三角形顶点上
	{
		if(l.D1.PointsEqualPoints(this.D1)||l.D1.PointsEqualPoints(this.D2)||l.D1.PointsEqualPoints(this.D3))
		{
			return true;
		}
		if(l.D2.PointsEqualPoints(this.D1)||l.D2.PointsEqualPoints(this.D2)||l.D2.PointsEqualPoints(this.D3))
		{
			return true;
		}
		return false;
	}
}

踩坑心得:

这个我真的很懂。。。这题有个点我想破头皮没改出来,在高手x总的帮助下总算是截止前改了。这题需要注意精度的问题,用到“==”的时候注意加个误差如“1e-6”。不然遇到测试点数据比较大的时候就会出现错误。比如直角三角形的判定这种,直接“A2+B2-C2==0”的话是错误的,改为“Math.abs(A2+B2-C2)<=1e-6”。虽然我错不在此却是错在同样类型的问题上,改的时候自己真的看不出来。。。这里输出结果小数位有要求,最多不超过6位。少于6位不用处理,多于6位四舍五入到6位输出。

import java.text.DecimalFormat;

这样即可将格式转换:

	DecimalFormat d=new DecimalFormat();
	String style="#.######";
	d.applyPattern(style);
    Double.parseDouble(d.format((Double)num);

改进建议:

1:有些题目的测试点在思路定型的形况下真的靠自己很难改出来(掉坑里出不来了),这些点在题目进行到一定时间的时候希望能有个系统提示,给个大概的方向。。。

2:如果输出结果有什么要求的话能不能明示一下,有一题用Double类型愣是不对,后面才知道Float才对。。。

总结:

这三次作业让我逐步对java、类的运用理解深刻。知道面向对象的可读性高、可扩展性强的优点。对类的使用也大大减轻工作难度,用类将问题分块可以将问题简单化。Java的稳定性和便捷性在一次次作业中被显现出来。

不足:在编写代码处理问题的过程中代码的书写还是逻辑不够清晰,使用过多的判断语句并且语句也比较冗余。对问题的分块化处理不够细致,只是将问题简单划分。导致代码的复杂度比较高,可读性也大大减弱。对细节上的处理不够细致,导致出错也难以发现和改正。

posted @ 2022-10-02 15:15  XIAO羊XIAO恩  阅读(87)  评论(0)    收藏  举报