大家好,欢迎来到IT知识分享网。
面对对象程序设计————PTA前三次作业总结
PTA大作业一——题目集1
整体总结:
题目集01-09考察的是Java中基础的输入输出、循环结构、数组创建、字符串的使用,用于C语言到Java的过渡。
题目集1 7-6 学号识别
整体思路分析 :
1.本题逻辑十分清晰,无十分严重的踩坑。
2.本题主要要求判断输入学号是否为8位,且学院编号不是01、02、03、20其中之一,属于非法输入。
3.先判断输入字符串前两位是否为要求范围内,在判断此字符串长度是否为8来确实是否为非法输入
核心代码分析:
先截取前3,4位字符,判断学院编号是否正确。
String s=mes.substring(2,4);
if (s.compareTo(s1)!=0&&s.compareTo(s2)!=0&&s.compareTo(s3)!=0&&s.compareTo(s4)!=0)//s1-s4分别对应学院编号
flag=0;
判断学号长度是否为8。
if (mes.length()!=8||flag==0)
System.out.println(“Wrong Format”);
缺陷:
1.在进行学院编号的判断时,采用方法十分笨拙,对于更多的学院编号时无法适用
改进建议:
1.运用循环和数组判断学院编号。
题目集1 7-7
整体思路分析:
1.本题考察三角形类型的判断,主要难点在于各类三角形类型判断的先后逻辑。
2.逻辑上,首先判断输入数据是否合法,再按能否构成三角形——是否为等边三角形——是否为等腰直角三角形——是否为等腰三角形——是否为直角三角形——为一般三角形的顺序判断。
度量分析
圈复杂度分析使用 SourceMonitor 软件
核心代码分析
1.先判断输入数据是否合法
if (a<1||a>200||b<1||b>200||c<1||c>200)
System.out.print(“Wrong Format”);
2.判断能否构成三角形
else if (a+b<=c||a+c<=b||b+c<=a)
System.out.print(“Not a triangle”);
3.判断是否为等边三角形
else if(a==b&&b==c)
System.out.print(“Equilateral triangle”);
4.判断是否为等腰直角三角形
else if ((a==b&&Math.abs(a*a+b*b-c*c)<0.00001)||(a==c&&Math.abs(Math.sqrt(2)*a-b)<0.00001)||(b==c&&Math.abs(Math.sqrt(2)*b-a)<0.00001))
System.out.print(“Isosceles right-angled triangle”);
5.判断是否为等腰三角形
else if (a==b||a==c||b==c)
System.out.print(“Isosceles triangle”);
6.判断是否为直角三角形
else if(a*a+b*b==c*c||a==c&&a*a+c*c==b*b||c*c+b*b==a*a)
System.out.print(“Right-angled triangle”);
7.输出一般三角形
else
System.out.print(“General triangle”);
踩坑点:
1.double的精度问题,double数据相减是否为零需要判断结构是否小于0.00001,否则无法进行准确判断;
2.Math类中的绝对值方法不像C语言中分浮点型和整数,只有abs;
3.逻辑错误,优先判断了是否为等腰三角形,再而判断等腰直角三角形,而导致无法等腰直角三角形的输出为等腰三角形;
改进建议:
if使用的if – else 语句可适当合并,减少语句复杂度
题目集二 7-2
整体总结
此次题目集逻辑难度大幅加强,更需要去理解题目意思,以及对题目中的特殊词汇(例如空闲位,奇偶校验位)的理解和记忆。
整体分析
1.本题考察到对字符串的处理问题,本人主要采用了charAt(i)方法来进行此题对字符串内容的判断;
2.题目分析: (1)空闲位:1;
(2)起始位:0,一串数据开始的标志,从这个0后面的一位数开始,为此串代码的内容;
(3)奇偶校验位:本题采用奇校验位,指使这一串数据以及此校验位中“1”的总数为奇数,即数据中的“1”为奇数时,校验位为0,为偶数时。校验位为1;
(4)结束位:1;
3.数据截取:从输入字符串的首字符开始,判断出现0的位置时,通过长度为8进行数据截取,再截取后面的奇偶校验位和结束位;
度量分析
圈复杂度分析使用 SourceMonitor 软件
核心代码分析:
for (i=0;i<s.length();i++)
{
判断0是否出现
if ((int)s.charAt(i)==48)
{
flag=1;
}
}
判断输入字符串长度是否够一串数据
if(s.length()<11)
{
flag=0;
}
if(flag==0)
System.out.print(“null data”);
else
{
for (i=0;i<s.length();i++)
{
判断0出现时后面的字符是否够一串数据
if ((int)s.charAt(i)==48&&s.length()-i>=10)
{
count=0;
for(j=i;j<=i+8;j++)
{
计算此数据中1出现的次数
if((int)s.charAt(j)==49)
{
count++;
}
}
判断结束位是否正确
if((int)s.charAt(i+10)!=49)
System.out.println(x+”:”+”validate error”);
判断奇校验位是否正确
else if((int)s.charAt(i+9)==count%2+48)
System.out.println(x+”:”+”parity check error”);
else
{
System.out.println(x+”:”+s.substring(i+1,i+9));
}
从此数据后接着找下一串数据
i=i+10;
x++;
}
}
}
踩坑点:
1.奇校验位的理解有误,由于测试样例的校验位基本都为1,导致我误以为奇校验位为1,偶校验位为0;
2.第一次判断时:(int)s.charAt(i)==0有误,0字符转换成int型时的值为48;
改进建议:
1.对题目要求要深刻理解,不能通过样例片面理解。
2.字符转换成整数型时要注意其ASCII值。
PTA大作业三——题目集3
整体总结:
此题目集难度陡然上升,每个题难度都很大,测试样例少并且测试点达到30之多,许多测试点都不能根据题目退出,得自己寻找边界数据测试然后进行修改,耗时很长。
题目集1 7-1 点线形系列1-计算两点之间的距离
整体分析:
1.题目明面上给的要求非常简单,仅要求按 x1,y1(空格)x2,y2 的方式输入两个点的坐标,然后判断其输入是否合法,再求其距离即可,但由于关于是否合法的要求没有完全给出,导致许多测试点都过不去。经过多次尝试,得出一下输入格式:
合法输入:(1)1,1 1,2 (2)+1,1 1,2 (3)1,1 1.0 1
非法输入:(1)++1,1 1,2 (2)+1+,1 1,2 (3)+01,1 1,2 (4).1,1 1,2 (5)1.,1 1,2 (6).,1 1,2 (7)+++,1 1,2 (8)000,1 1,1
点的数量坐标过多:(1)1,1 1,2 1,3
度量分析
圈复杂度分析使用 SourceMonitor
核心代码分析
for (i=0;i<4;i++) { int count=0; for (int j=0;j<a[i].length();j++) {
判断输入的字符串中是否存在除0-9和+,-,.以外的字符,出现则非法 if((a[i].charAt(j)<'0'||a[i].charAt(j)>'9')&&a[i].charAt(j)!='+'&&a[i].charAt(j)!='-'&&a[i].charAt(j)!='.') flag=0;
判断0-9后的数字是否有出现+,-的情况 if(a[i].charAt(j)>='0'&&a[i].charAt(j)<='9') { for(int r=j+1;r<a[i].length();r++) if(a[i].charAt(r)=='+'||a[i].charAt(r)=='-') flag=0; } }
if(a[i].length()>1) { for (int j=0;j<a[i].length();j++) {
判断第一个出现0-9前的+,-,.的数量和是否会超过2,用break语句来跳出循环,避免对小数位进行此判断if(a[i].charAt(j)>='0'&&a[i].charAt(j)<='9') { flag0=1; for (int q=0;q<j;q++) if(a[i].charAt(q)=='+'||a[i].charAt(q)=='-'||a[i].charAt(q)=='.')
count++; if(flag0==1) break; } }
判断第一位为‘.’的情况 int len=a[i].length(); if(a[i].charAt(len-1)=='.') flag=0; }
判断只有一位数,而这一位数不是0-9的情况 else { if(a[i].charAt(0)<'0'||a[i].charAt(0)>'9') flag=0; }
判断出现“.1”的情况 if(count==1&&a[i].charAt(0)=='.') flag=0;
判断出现“+++”类似的情况 if(count>1||count==a[i].length()) flag=0;
判断出现“000”的情况 if(flag==1) if(Double.parseDouble(a[i])==0&&a[i].length()>1) flag=0; }
踩坑心得:
1.“01”,“00”属于非法输入,有点让人意想不到,正常逻辑会把这当成正常输入;
2.在下面这段代码中误以为已经把“.”这种情况考虑进去了,但没意思到这种情况没有0-9的出现,从而不会进入循环中的判断
改进建议:
1.多考虑进入循环的条件。
2.此代码在SourceMonitor中的复杂度为0,个人感觉良好。
题目集 7-2 点线形系列2-线的计算
整体分析
1.本题考察判断输入数据是否合法,以及直线斜率、点重合、点到线的距离、三点共线、两直线平行、交点是否存在以及交点位置等平面问题;
2.此题涉及内容较多,且很多地方用到重复判断,所以采用建立各种方法进行判断, K(计算斜率),coinside(判断点重叠),Correct(判断是否合法输入)
3.判断输入数据是否合法:具体逻辑同7-1,仅稍作改动,所以不作具体分析;
4.计算斜率:斜率存在,直接返还;斜率不存在,返回-1000(存在一定的复杂度,需要通过判断横坐标进一步判断是斜率不存在还是斜率的确为-1000,但由于此题未涉及到大数据考虑,所以有些地方没有完美改动);
5.coinside:通过Double.parseDouble(a[i])方法将传入的字符串转换为整数型,便于判断是否为同一点。
度量分析
6.选项1-4的主函数部分较简略,且无踩坑点,5的逻辑判断较为复杂;
圈复杂度分析使用 SourceMonitor
核心代码分析
斜率计算:
public static double K(String m1,String n1,String m2,String n2) { double k;
将字符串转换为整数进行判断 double x1=Double.parseDouble(m1); double y1=Double.parseDouble(n1); double x2=Double.parseDouble(m2); double y2=Double.parseDouble(n2);
斜率不存在,存在一定bug,需要在Main函数中在进行详细判断 if(x1==x2) k=-1000; else { k=(y2-y1)/(x2-x1); } return k; }
重合点判断:
public static int coinside(int x,String s) { int flag=1,i=0,j=0; String[] a=s.split(" |,");
由于当输入的内容为4个坐标时,我们仅需要判断前面两个点是否重合以及后面两个点是否重合即可,所以要区分x等于4和x不等于4的情况 if(x!=4) {
不等于4时,采用类似选择排序的方法它们两两之间进行比较 for(i=0;i<2*(x-1);i+=2) { double m1=Double.parseDouble(a[i]); double n1=Double.parseDouble(a[i+1]); for (j=i+2;j<2*x-1;j+=2) { double m2=Double.parseDouble(a[j]); double n2=Double.parseDouble(a[j+1]); if(m1==m2&&n1==n2) flag=0; } } } else {
等于4时,直接比较前两位和后两位坐标是否一致 for(i=0;i<5;i+=4) { double m1=Double.parseDouble(a[i]); double n1=Double.parseDouble(a[i+1]); double m2=Double.parseDouble(a[i+2]); double n2=Double.parseDouble(a[i+3]); if(m1==m2&&n1==n2) flag=0; } }
重合返还0,不重合返还1 return flag; }
选项1:斜率计算
if(x1==x2) System.out.println("Slope does not exist"); elsedouble k=(y2-y1)/(x2-x1);
选项2:点到线的距离
int flag0=coinside(3,a[1]); if(flag0==0) System.out.println("points coincide"); else { String[] b=a[1].split(" |,"); double dis=0; double k=K(b[2],b[3],b[4],b[5]); 计算斜率 if (k==-1000) 判断斜率是否不存在(此题目未涉及此处的边缘数据,所以未对斜率为-1000的情况进行判断) dis=Math.abs(x1-x); else { double b0=y1-k*x1; dis=Math.abs(k*x-y+b0)/Math.sqrt(1+k*k); } System.out.print(dis); }
选项3:
if((k1==-1000&&k2==-1000)||k1!=-1000&&k1==k2) 分两条直线全为斜率不存在 以及两条直线斜率均存在且平行两种情况 System.out.println("true"); else System.out.println("false");
选项4:
判断两线是否平行,直接判断两线的斜率是否相等即可
if(k1==k2) System.out.println("true"); else System.out.println("false");
选项5
根据线性代数的知识计算交点坐标
double a1 = y2- y1; double b1 = x1 - x2; double c1 = x1*y2 - x2*y1; double a2 = y4 - y3; double b2 = x3 - x4; double c2 = x3*y4 - x4*y3; double det= a1*b2 - a2*b1; double x0 = (c1*b2 - c2*b1)/det; double y0 = (a1*c2 - a2*c1)/det; if((x0==x1&&y0==y1)||(x0==x2&&y0==y2)||(x0==x3&&y0==y3)||(x0==x4&&y0==y4)) { System.out.println(x0+","+y0+" "+"false"); }
从网上学习的判断交点是否在线段内的函数用法 else if(!java.awt.geom.Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x4, y4)) { if(x1==Math.max(Math.max(x2, x3),Math.max(x2, x4))||x1==Math.min(Math.min(x2, x3),Math.min(x2, x4))) System.out.println(x0+","+y0+" "+"false"); else System.out.println(x0+","+y0+" "+"true"); } else { System.out.println(x0+","+y0+" "+"true");
踩坑点:
1.错误的理解了点重叠在选项4中的应用,错误的认为4个点均不能重复,而导致许多测试点无法通过;
2.第一题的格式是否合法在第二题不完全适用,但由于测试点无法给出具体问题所在,而一直无法发现错误;
改进建议:
由于代码中多次运用Double.parseDouble(a[i])方法,而导致代码复杂度较高,建议将其在代码初始位置就转换完成,而不是每个选项都转换一次。
题目集 7-2 点线形系列3-三角形的计算
整体思路分析:
1.本题考察判断输入数据是否合法,以及三角形形状判断,三角形周长、面积、重心的计算,直线与三角形的交点问题,点与三角形的位置问题;
2.此题涉及内容较多,且很多地方用到重复判断,所以采用建立各种方法进行判断, K(计算斜率),coinside(判断点重叠),Correct(判断是否合法输入),der(判断三角形是否存在),crossX(计算交点横坐标),crossY(计算交点纵坐标),prinf(打印输出)
3.判断输入数据是否合法:具体逻辑同7-1,仅稍作改动,所以不作具体分析;
4.计算斜率:斜率存在,直接返还;斜率不存在,返回-1000(存在一定的复杂度,需要通过判断横坐标进一步判断是斜率不存在还是斜率的确为-1000,但由于此题未涉及到大数据考虑,所以有些地方没有完美改动);
5.coinside:通过Double.parseDouble(a[i])方法将传入的字符串转换为整数型,便于判断是否为同一点。
6.判断三角形是否存在:通过计算三线斜率,若存在斜率相等,即无法构成三角形;
7.交点坐标计算同7-2的选项5,打印输出通过String.valueOf(x)将整数转换成字符串,来进行判断和输出;
度量分析
核心代码分析
1.三角形是否存在:
public static int der(String m1,String n1,String m2,String n2,String m3,String n3) { int flag=1; double k1=K(m1,n1,m2,n2); double k2=K(m1,n1,m3,n3); double k3=K(m2,n2,m3,n3); if((k1==-1000&&k2==-1000)||(k1==-1000&&k3==-1000)||k3==-1000&&k2==-1000||k1!=-1000&&(k1==k2||k1==k3)||(k2!=-1000&&k2==k3)) flag=0; else flag=1; return flag; }
2.打印输出:
public static void prinf(double x) {
将整数转换成字符串 String s = String.valueOf(x); int i=0,dex=-1,count=0; for (i=0;i<s.length();i++) {
分整数型与浮点型两种情况 if(s.charAt(i)=='.') { dex=i; for (int j=i+1;j<s.length();j++) count++; break; } } if(dex==-1)
为整数,直接输出字符串 System.out.print(s); else { if(count<=6)
小数点后位数小于6,直接输出字符串 System.out.print(s); else {
小数点后位数超过6 为,运用printf函数,四舍五入保留6位小数输出 System.out.printf("%.6f",x); } } }
选项4:直线与三角形的交点问题
计算出三角形三边与直线的交点坐标
g[0]=crossX(m1,n1,m2,n2,x[0],y[0],x[1],y[1]); j[0]=crossY(m1,n1,m2,n2,x[0],y[0],x[1],y[1]); g[1]=crossX(m1,n1,m2,n2,x[1],y[1],x[2],y[2]); j[1]=crossY(m1,n1,m2,n2,x[1],y[1],x[2],y[2]); g[2]=crossX(m1,n1,m2,n2,x[0],y[0],x[2],y[2]); j[2]=crossY(m1,n1,m2,n2,x[0],y[0],x[2],y[2]); int cnt=0;
判断交点是否在三角形边上 if(g[0]>=Math.min(x[0], x[1])&&g[0]<=Math.max(x[0],x[1])) { cnt++; f[0]=1; } if(g[1]>=Math.min(x[0], x[2])&&g[1]<=Math.max(x[0],x[2])) { cnt++; f[1]=1; } if(g[2]>=Math.min(x[1], x[2])&&g[2]<=Math.max(x[1],x[2])) { cnt++; f[2]=1; }
判断是否有交点重合 if(g[0]==g[1]&&j[0]==j[1]) { cnt--; f[0]=0; } if(g[0]==g[2]&&j[0]==j[2]) { cnt--; f[0]=0; } if(g[1]==g[2]&&j[1]==j[2]) { cnt--; f[1]=0; }
选项5:点与三角形的位置关系
String m = String.valueOf((x[0]+x[1]+x[2])/3); String n = String.valueOf((y[0]+y[1]+y[2])/3); double x1=Double.parseDouble(m); double y1=Double.parseDouble(n); double k=K(b[0],b[1],m,n); if(k==-1000) flagt=0;double t=y0-k*x0,t1=y[0]-k1*x[0],t2=y[0]-k2*x[0],t3=y[1]-k3*x[1]; if(y0==k1*x0+t1||y0==k2*x0+t2||y0==k3*x0+t3) System.out.print("on the triangle"); else {int cnt=0; if(x0==x1) cnt=2; else { if(x0<x1) for(int l=0;l<3;l++) if(g[l]>x0) cnt++; elsefor(int l=0;l<3;l++) if(g[l]<x0) cnt++; if(g[0]==g[1]&&j[0]==j[1]) cnt--; if(g[0]==g[2]&&j[0]==j[2]) cnt--; if(g[1]==g[2]&&j[1]==j[2]) cnt--; } if(cnt==1) System.out.print("in the triangle"); else System.out.print("outof the triangle"); }
主要逻辑思维:通过找出三角形重心坐标,由于重心一定在三角形内,所以,通过找到改点与重心的连线,与三角形的交点数量(具体放法同选项4),若交点为奇数,则在三角形内,反之,则在三角形外;
踩坑点:
1.忽略了交点重叠,而导致交点数量偏多的情况;
2.有些选项需要考虑斜率不存在的情况,要对此做详细分析,选项4还有6 分为拿到,个人猜测可能便是因为斜率问题;
3.选项4输入面积要拿从大到小的顺序进行输出,一开始忽略了此点,而丢失了很多分;
改进建议:编写一个能完美处理斜率不存在的情况的方法,即能减少代码的复杂度,还能避免相应的bug产生;
总结
1.对于第三次大作业的编写,除了7-1还能静下心来减少代码的复杂度,其他两题只完全执着于过测试点,而忽略了代码的复杂度问题,最终造成了600行代码的“惨烈壮举”,希望以后能引以为戒,追求结果的同时也不能网络质量的好坏,将其养成习惯,持之以恒;
2.这三次作业让我了解到,光靠上课听老师讲,看老师举例子,去理解,是完全不够的,必须需要自己勤加练习,经过这三此作业,我完全从C语言的世界中过渡到了Java的世界,熟悉了Java中大多数基本用法,尽管过程有点艰辛,但收获也十分丰厚;
3.这三次作业唯一的缺陷就是类的建立和使用太少,一是不够熟练,二是类的建立可能会大幅度减少我的代码行数和复杂度;
4.第三次大作业让我意识到,难度较高的代码如果出现错误,很难凭借眼力找出,这时,debug的重要性就显现了,通过debug,大幅度减少了我找bug的时间,所以,掌握每门语言、每种软件的debug技巧十分重要;
5.尽管C语言与Java很多地方都很相似,但任然存在许多细节不一样,不能根据惯有思维来认定一些Java的技巧,否则会出现许多看不到的错误。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29233.html