PTA大作业博客一

前言:

在上 面对对象程序设计课程 前我还没有接触过java,做第一次大作业前只能匆匆略看了一部分java语法,所以即便第一次大作业很简单也花费了不少时间。到了第二次大作业,基本语法掌握的差不多了,但是大部分内置方法我还不知道,没有直接调用,为此走了不少弯路。第三次大作业难度骤然升级,对于无人帮助的纯小白很难全部完成。到了这一步我才将类与方法的概念与语法弄得差不多明白。

PTA第一次大作业

设计与分析:

作为初学者,同时题目过于简单,我采用的是C语言面向过程的写法,无法体现出Java面向对象的特性。If else,switch case,while,foex循环等与C语言几乎无异。

采坑心得:

用到输入时要先import java.util.Scanner;

如Scanner in=new Scanner(System.in);a=in.nextInt();要注意大小写。

equalsIgnoreCase() 方法用于将字符串与指定的对象比较,不考虑大小写。

charAt(i)从字符串中取字符

改进建议:

PTA第二次大作业

7-2 串口字符解析

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

设计与分析:

先用字符串长度和正则表达式判断输入是否合法,若合法则进行下一步判断。

设置两个布尔类型变量作为判断旗帜

用for循环+多个if依次进行判断

最后由两个旗帜的真假选择输出结果

IMG_256

采坑心得:

正则表达式需要多加练习

正则表达式只能用来判断字符串

equals与==比较的堆中的内存地址不同,其比较的是对象的值

改进建议:

在第一次判断时只用if不用else,if为null data,则return,可以少一层复杂度。本体使用了大量if,for,复杂度很大,不是一个好办法。将部分内容放到方法里引用可以减少复杂度。

PTA第三次大作业

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

设计与分析:

设计point类,里面有坐标x,y,到另一个point的距离

使用构造函数为x,y赋值

JAVA中split函数基本用法,将字符串按照指定字符串进行分割

输入字符串s

将s按照空格切分后放入字符串数组point

将point按照,切分后放入字符串数组num,则num中分别存了一个坐标的x和y,

对两个值进行判断格式

如果point长度不为2,则点数量不对

采用parseDouble()将数字类型的String字符串转换为浮点数传入点

IMG_256

import java.util.Scanner;

public class Main {

double x,y;

double distance(Main a){

return (Math.sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y)));

}

Main(double a,double b){

this.x=a;

this.y=b;

}

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

String s=input.nextLine();

String []num;

String []point = s.split(" ");//将s按照空格切分后放入point

for(int i=0;i<point.length;i++) {

num = point[i].split(",");//将point按照,切分后放入num

for(int j=0;j<num.length;j++) {

if(!num[j].matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")) {

System.out.print("Wrong Format1");

return;

}

}

}

if(point.length!=2) {

System.out.print("wrong number of points");

return;

}

num = point[0].split(",");

double a = Double.parseDouble(num[0]);/*数字类型的String字符串转换为浮点数通常采用parseDouble()和valueOf()方法*/

double b = Double.parseDouble(num[1]);/*Double.parseDouble(java.lang.String)的参数只能是String*/

num = point[1].split(",");

double c = Double.valueOf(num[0]);/*Double.valueOf()的参数类型可以是浮点型或者是字符串均可*/

double d = Double.valueOf(num[1]);

if(a==c&&b==d){

System.out.print("Wrong Format2");

return;

}

Main p1=new Main(a,b);

Main p2=new Main(c,d);

System.out.println(p1.distance(p2));

}

}

采坑心得:

Java中的 split 函数是用于按指定字符(串)或正则去分割某个字符串,结果以字符串数组形式返回。

一个参数:代表根据什么来分(这个必须位于字符串里面)

两个参数:第一个代表根据什么来分割,第二个代表分成几份,分完之后后面的不在继续分

如果想根据多个字符来分,用 | 隔开。

数字类型的String字符串转换为浮点数通常采用parseDouble()和valueOf()方法

Double.parseDouble(java.lang.String)的参数只能是String

Double.valueOf()的参数类型可以是浮点型或者是字符串

改进建议:

将代码封装,更加工整简洁。

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",

设计与分析:

设计了点point与线line两个类,由于第三题所需类相同,统一在第三题分析。

采坑心得:

s.charAt(0) < '1' || s.charAt(0) > '5' || s.charAt(1) != ':'

用charAt提取单个字符进行比较,equals和matchs都是用来比较字符串的。

this.指的是访问类中的成员变量,用来区分成员变量和局部变量

改进建议:

我的主函数是在line类下进行的,由于pta主函数只能命名为Main,所以我直接把line类线给命名为Main。应该设Main类在其中写主函数然后最下方加上line类

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",

设计与分析:

类line中包含两点a,b。两点构成的直线的斜率,一个布尔类型变量判断是否重合。还有两个方法,分别计算点到本直线的距离,与另外一条直线是否平行。在构造函数中传入两点,同时通过计算为类中进行赋值。

类三角形有三点Point a,b,c,和重心zhongxin;

用double类型表示长度 ab,bc,ca;周长zhouchang,面积mianji;

boolean类型判断真假 ssanjiao是三角形,isdengbian等边,isdengyao等腰,dunjiao钝角,zhijiao直角,ruijiao锐角;

主函数与第一第二题大体一致,将s按照空格切分后放入字符串数组point

将point按照,切分后放入字符串数组num,则num中分别存了一个坐标的x和y,

对两个值进行判断格式,不过有了更多选项与判断

我采用前两个字符串是否为1到5加上“:”先来判断格式是否正确再判断其他格式

Point[] poi= new Point[point.length];创建一个点类型的数组,长度为点的数量。用来存每个点的坐标。

Line类

class Line {

Point a, b;

double xielv;

double B;

boolean chonghe;

Line(Point a, Point b) {

this.a = a;

this.b = b;

if (this.a.x == this.b.x && this.a.y == this.b.y)

//System.out.println("points coincide");

this.chonghe=true;

else if ((this.a.x - this.b.x) == 0)

System.out.println("Slope does not exist");

else {

this.xielv = (a.y - b.y) / (a.x - b.x);

B = a.y - this.xielv * a.x;

}

}

IMG_256

类Main

import java.util.Scanner;

public class Main {

public static double jszdj(double s)

{

String str=String.valueOf(s);

String substring = str.substring(str.indexOf(".") + 1);

int str_len;

if(substring.length()>6) {

str_len=6;

}

else {

str_len=substring.length();

}

String formats="%."+str_len+"f";

String out=String.format(formats,s);

double res=Double.parseDouble(out);

return res;

}

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

String s = input.nextLine();

String s2 = s.substring(2);

// System.out.println(s2);

if (s.charAt(0) < '1' || s.charAt(0) > '5' || s.charAt(1) != ':') {/*如果前两个字符不是1到5加:*/

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

return;

}

String[] num;

String[] point = s2.split(" ");//将s按照空格切分后放入point

//for (int i = 0; i < point.length; i++)

//System.out.println(point[i]);

Point[] poi = new Point[point.length];

//System.out.print(point.length);

for (int i = 0; i < point.length; i++) {

num = point[i].split(",");//将point按照,切分后放入num

for (int j = 0; j < num.length; j++)

if (!num[j].matches("^[+-]?(0|(0\\.\\d+)?|[1-9][0-9]*(\\.\\d+)?)$")) {

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

return;

}

double a = Double.parseDouble(num[0]);

double b = Double.parseDouble(num[1]);

// System.out.println(a+" + "+b);

Point p = new Point();

p.x=a;

p.y=b;

poi[i] = p;

//System.out.println(i + " " + poi[i].x+" "+poi[i].y);

}

switch(s.charAt(0)){

case '1': {

if(point.length!=3) {

System.out.print("wrong number of points3");

return;

}

Sanjiao tra=new Sanjiao(poi[0],poi[1],poi[2]);

if(tra.issanjiao) {

if (tra.isdengyao)

System.out.print("true ");

else System.out.print("false ");

if (tra.isdengbian)

System.out.print("true");

else System.out.print("false");

}

else System.out.print("data error");

break;

}

case '2':{

if(point.length!=3) {

System.out.print("wrong number of points3");

return;

}

Sanjiao tra=new Sanjiao(poi[0],poi[1],poi[2]);

if(tra.issanjiao) {

System.out.print(jszdj(tra.zhouchang)+" "+jszdj(tra.mianji)+" "+jszdj(tra.zhongxin.x)+","+jszdj(tra.zhongxin.y));

}

else System.out.print("data error");

break;

}

case '3':{

if(point.length!=3) {

System.out.print("wrong number of points3");

return;

}

Sanjiao tra=new Sanjiao(poi[0],poi[1],poi[2]);

if(tra.issanjiao) {

if (tra.dunjiao)

System.out.print("true ");

else System.out.print("false ");

if (tra.zhijiao)

System.out.print("true ");

else System.out.print("false ");

if (tra.ruijiao)

System.out.print("true");

else System.out.print("false");

}

else System.out.print("data error");

break;

}

case '4':{

if(point.length!=5) {

System.out.print("wrong number of points");

return;

}

//System.out.println(poi[0].x+poi[0].y);

Line l1=new Line(poi[0],poi[1]);

if(l1.chonghe)

{

System.out.println("points coincide");

return;

}

Sanjiao tra=new Sanjiao(poi[2],poi[3],poi[4]);

if(!tra.issanjiao)

{

System.out.println("data error");

return;

}

break;

}

case '5':{

if(point.length!=4) {

System.out.print("wrong number of points");

return;

}

Sanjiao sanj=new Sanjiao(poi[1],poi[2],poi[3]);

if(!sanj.issanjiao)

System.out.println("data error");

break;

}

}

}

}

IMG_256

Point类(点)

class Point{

double x;

double y;

void getx(double a){

this.x=a;

}

void gety(double b){

this.y=b;

}

double distance(Point a){

return Math.sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));

}

}

IMG_256

Sanjiao类(三角形)

class Sanjiao {

Point a,b,c,zhongxin;

double ab,bc,ca;

boolean issanjiao,isdengbian,isdengyao,dunjiao,zhijiao,ruijiao;

double zhouchang,mianji;

Sanjiao(Point a,Point b,Point c){

this.a=a;

this.b=b;

this.c=c;

this.ab=a.distance(b);

this.bc=b.distance(c);

this.ca=c.distance(a);

if(ab+bc>ca&&ab+ca>bc&&bc+ca>ab){//是否组成三角形

this.issanjiao=true;

if(ab==bc&&bc==ca)//判断等边

this.isdengbian=true;

if(ab==bc||bc==ca)

this.isdengyao=true;

else if((ab*ab+bc*bc-ca*ca<0.0001)||(ab*ab+ca*ca-bc*bc<0.00001)||(bc*bc+ca*ca-ab*ab<0.0001))//是否有直角

this.zhijiao=true;

else if(ab*ab+bc*bc<ca*ca)

this.dunjiao=true;

else if(ab*ab+bc*bc>ca*ca)

this.ruijiao=true;

this.zhouchang=ab+bc+ca;

this.mianji=Math.sqrt( ((this.ab+this.bc+this.ca)/2.0)*(((this.ab+this.bc+this.ca)/2.0)-this.ab)*(((this.ab+this.bc+this.ca)/2.0)-this.bc)*(((this.ab+this.bc+this.ca)/2.0)-this.ca));

this.zhongxin = new Point();

this.zhongxin.x= (this.a.x+this.b.x+this.c.x)/3.0;

this.zhongxin.y= (this.a.y+this.b.y+this.c.y)/3.0;

}

}

}

IMG_256

采坑心得:

在三角形类中,以下无法进行赋值

IMG_256

需在前面加上 this.zhongxin = new Point();将重心new一个点才能有存储空间。

非法格式有很多种,花了很长时间但是有很多都不能通过全部的测试点,还是思考欠缺。

规则进到最低位。小数点后若不足6位,按原始位数显示,不必补齐

改进建议:

类中的对象都没有用private类型,导致不安全,易被修改。应该在类中使用方法进行赋值。

圈复杂度算是很高,要多考虑用函数的方式。

本题尚有很多要求没有完成,需要继续完善。

总结:

  第二次作业与第三次作业跨度太大,对于新手极不友好,需要多加自学,还是因为自己下的功夫不够多。在学霸同学的指导下才了解到各种内置方法函数。自身知识积累不足,

不知道可以调用方法导致走了很多弯路。通过第三次大作业,我对类与方法逐渐认知清晰了,同时要多写方法,尽量将步骤拆分开,降低圈复杂度,提升代码质量。

正则表达式在排除冗余代码块的方面所具有的巨大作用,但是设计上比较复杂,条件多了容易写乱,需要多加练习。

由于没有提前准备学习Java,很抱歉在规定时间内没有完成任务要求。

 

posted @ 2022-10-02 20:47  johntake  阅读(90)  评论(0)    收藏  举报