博客作业
博客作业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的稳定性和便捷性在一次次作业中被显现出来。
不足:在编写代码处理问题的过程中代码的书写还是逻辑不够清晰,使用过多的判断语句并且语句也比较冗余。对问题的分块化处理不够细致,只是将问题简单划分。导致代码的复杂度比较高,可读性也大大减弱。对细节上的处理不够细致,导致出错也难以发现和改正。

浙公网安备 33010602011771号