第一次大作业blog
前言
知识点:
1.类与对象:三次大作业中最离不开的就是对类和对象的应用,这体现了java面向对象的特点,类的定义,对象的创建都是大作业中最基本的操作但是必要的操作。
2.字符串与数组的应用:本次大作业中对于输入信息的处理最基本的处理方式就是字符数组,字符数组用于存储char类型的数据,可以对输入的信息进行访问,声明和初始化,字符串之间的对比以及转换操作。
3.正则表达式:对输入信息的处理方法中正则表达式无疑比其他处理方式更加方便和系统,它可以完美地匹配特定字符和截取特定字符串,将正则表达式与字符串转换相结合可以在大作业中发挥出很大的根本性作用。
题量:这三次大作业的题量对于初学java的我而言是介于合适到较多之间的,整体题量适中,不存在题目拿零分和总体不及格的现象。
难度:三次大作业中除了共有的答题判定程序题之外的题目于我而言都可以完成,存在一点点卡壳现象也很快可以通过查询资料进行完成。答题判定程序的难度有那么一点点高,虽然我的得分只有一次达到了优秀水准,其他都是60-70分之间,但都不是题目难度的问题,而是我对java语法的不熟练和对题目的理解上的问题。
设计与分析
第一次作业第三题:
第一次作业较后两次更为简单,对于类的定义和调用涉及的较为简单,只定义了一个tm题目类和test答卷类,第一次大作业就单纯设定两个个类然后进行普通的调用处理。这次作业中我对所有的字符串处理的方式都是用字符数组,将字符串转换为字符数组然后循环判定,再将获得的新的字符数组转换为字符串存储到对象中,最后进行输出。
字符数组处理方式:使用toCharArray()转换为字符数组;使用String xxx = new String( char xxx【】 )将字符数组转换为字符串
第二次大作业最后一题:
类图:
第二次作业中的类的调用也没有很复杂,在第一次的基础上进行扩展,将分数存储到paper中,只是类更多,要存储的信息也更多。这次作业中我对字符串的处理方式有正则表达式和字符数组,但主要还是字符数组,因为我对正则表达式还不熟练。在对字符串进行处理的过程中我进行了输出判定,只要读到#S就进行答案判断和总分判定处理。
字符串处理方式:同第一次
第三次大作业最后一题:
类图:
第三次作业我没有在第二次作业的基础上进行修改,而是重新设置字符串判定逻辑,将所有判定方式都改为了正则表达式匹配,类方面比前两次作业都要分工更加精细,新增了markjudge类进行存储试卷的总分,mark类进行试卷题目的分数存储,del类则存储删除题号信息的存储,Student类进行存储学生信息,以及此次取消了test类的使用,修改了答案判定逻辑。信息处理输出也放在了处理完所有信息后再进行输出。
字符串处理方式:
String a=”xxx”;
pattern = Pattern.compile(a);
matcher = pattern.matcher(message);
其中使用(?<>)来进行字符串中特定字段的提取
这三次作业我都没有使用ArrayList进行信息的存储,因为不熟练其运用,所以采用了更为熟悉的类数组。总的来说代码逻辑在一次次的完善,第三次完全重写,因为使用了正则表达式逻辑表现地比前两次更好。
踩坑心得
第一次大作业最后一题:
出现过的问题:
1.使用==进行字符串之间的判断。
第一次写的时候写了类似下面的代码:
String end=”end”;
String message=input.nextLine();
If ( end == message )
{
break;
}
在测试用例时一直报错,主要还一时半会找不出问题,最后想到c语言是用strcmp()来进行判断就想到了java也是要用特定方式判断。
最后改成了:
String message=input.nextLine();
String end="end";
if( message.equals(end) )
break;
2.在进行多余空格测试点的调试时,一直对字符数组中连续空格数的数量进行判断,最后还是一直出现有多余空格的输出,甚至出现非零返回。
最后经过查询资料才得知有java有特定的方法去除字符串两边的空格。
也就是trim()
如下:
System.out.println(tmlist[i].Q.trim()+"~"+tests[i].A);
第二次大作业最后一题:
出现过的问题:
1.因为使用的是类数组,所以有时候在使用for循环进行类数组的数据处理时会出现类是null的问题
如修改前代码
if ( a[j]'#'&&a[j+1]'N' )
{
j=j+1;
fNum=a[j+2]-'0';
for(int p=0;p<length;p++)
{
if(a[ p ]'#'&&a[p + 1]'Q')
{
int fl=0;
for(int k= p+3;k < length ;k++)
{
if(a[k] == ' ')
break;
fl = fl+1;
}
char[] fQ=new char[fl];
for( int k=p+3,l=0;;k++,l++ )
{
if(a[k]' ')
break;
fQ[l]=a[k];
}
ftmQ = new String (fQ );
}
if( a[p]'#'&&a[p+1]=='A' )
{
int fl=0;
for (int k=p+3;k<length;k++ )
{
fl=fl+1;
}
char[] fA=new char[fl];
for(int k=p+3,l=0;k < length;k++,l++)
{
fA[l]=a[k];
}
ftmA=new String(fA);
}
}
//前面是获取字符串中的题号,题目和答案,下面是问题代码
tms[tmn].Num = fNum;
tms[tmn].A = ftmA;
tms[tmn].Q = ftmQ;
tmn=tmn+1;
break;
}
会出现error:tms[i] is null的报错,这个问题卡了我一段时间,最后发现只要类没有定义属性的话就相当于一个null类,直接使用=设置属性会报错,最后改一下改成:
tms[tmn]=new tm(fNum,ftmA,ftmQ);
2.因为我的输出逻辑是在匹配到#S字符串时直接进行分数非100的判定输出,源代码:
if(a[j]'#'&&a[j+1]'S')
{
t2=0;
int tpaper=a[j+3]-'0';
papernum[t1]=tpaper;
t1=t1+1;
j=j+1;
for(int k=j;k<length;k++)
{
if(a[k]'#'&&a[k+1]'A')
{
k=k+3;
int tl=0;
for(int l=k;l<length;l++)
{
if(a[l]' ')
break;
tl=tl+1;
}
char[] c1=new char[tl];
for(int l=k,p=0;l<length;l++,p++)
{
if(a[l]' ')
break;
c1[p]=a[l];
}
String c2=new String(c1);
tests[t2]=new test(tpaper,c2);
t2=t2+1;
}
}
tpn=tpn+1;
if(tpaper>=tpn)
System.out.println("The test paper number does not exist");
else
{
for(int k=0;k<10;k++)
{
for(int l=0;l<10;l++)
{
if(tms[l]!=null)
{
if(tms[l].npapers[tpaper].Num[k])
{
if(tests[l]!=null)
{
if(tms[l].sA.equals(tests[l].A))
System.out.println(tms[l].Q.trim()+""+tests[l].A.trim()+""+judge1);
else
System.out.println(tms[l].Q+""+tests[l].A+""+judge2);
}
else
System.out.println("answer is null");
}
}
}
}
int totalmark=0;
for(int k=0;k<10;k++)
{
for(int l=0;l<10;l++)
{
if(tms[l]!=null)
{
if(tms[l].npapers[tpaper].Num[k])
{
if(tests[l]!=null)
{
if(tms[l].sA.equals(tests[l].A))
{System.out.print(tms[l].mark);totalmark=totalmark+tms[l].mark;}
else
System.out.print("0");
if(papers[tpaper].Num[k+1]!=0&&tests[l+1]!=null)
System.out.print(" ");
}
}
}
}
}
System.out.print("~"+totalmark+"\n");
}
break;
}
导致存在两张非100分试卷时出现非100分提示不是连续输出,如输入
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#T:2 2-5 1-3 3-2
#S:2 #A:5 #A:4
#end
正确输出:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=~ 5 ~true
2+2=~ 2 2~false
7 0~7
2+2=~ 5 ~false
1+1=~ 4 ~false
answer is null
0 0 0~0
而我的输出:
alert: full score of test paper1 is not 100 points
3+2=5true
2+2=22false
7 0~7
alert: full score of test paper2 is not 100 points
2+2=5false
1+1=4false
answer is null
0 0 0~0
这个问题在第三次大作业中得到了解决,也就是将输出判定结构全都存储在字符串数组中最后统一输出。
第二次的作业剩下的都是一些小问题,比如循环嵌套时将
for(int j=0; j<t ;j++ )j写成i导致一直出现死循环和错误输出,还一直以为是逻辑出问题,看了一遍又一遍最后发现就是j写成了I,所以写循环函数时真的要细心。
第三次大作业最后一题:
出现过的错误:
1.在使用正则表达式匹配字符串时因为是做了两次连续匹配,但是将匹配成功的判定值设置写在了第一次匹配成功里,导致出现错误输入是还是进行了正常输出结果以及非零返回,如源码:
String mkj1 = " #T:(?
String mkj2 = "(?
pattern = Pattern.compile(mkj1);
matcher = pattern.matcher(message);
if(matcher.find())
{
int t4=0;
int t1=Integer.parseInt(matcher.group("num"));
if(papers[t1]==null)
{
papers[t1]=new paper(t1);
}
marks[t1]=new mark(t1);
pattern = Pattern.compile(mkj2);
matcher = pattern.matcher(message);
while(matcher.find())
{
int t2=Integer.parseInt(matcher.group("num1"));
int t3=Integer.parseInt(matcher.group("num2"));
for(int j=0;j<10;j++)
{
marks[t1].setmark(t2,t3,t2);
}
papers[t1].setNum(t4, t2);
t4=t4+1;
// flag=1;
// tflag=1;
// ttflag=1;
//移动至此处
}
flag=1;//
tflag=1;//错误部分
ttflag=1;//
}
这样会出现只要匹配到了#T就判定为正确输出,比如输入字符串为#T:1 1-90 -90时会进行正确输入判定,而非题目要求的wrong format:#T:1 1-90 -90输出。只要将错误部分移动至二次判定语句中即可解决问题。
2.在信息进行乱序输入判定时我的代码测试输入信息:
#N:3 #Q:3+2= #A:5
#N:2 #Q:2+2= #A:4
#T:1 3-7 2-6
#S:1 #A:5 #A:22
#N:1 #Q:1+1= #A:2
#T:2 2-5 1-3 3-2
#S:2 #A:5 #A:4
end
时输出:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
answer is null
answer is null
answer is null
answer is null
answer is null
null not found
null not found
而正确答案要输出:
alert: full score of test paper1 is not 100 points
alert: full score of test paper2 is not 100 points
3+2=5true
2+2=22false
7 0~7
2+2=5false
1+1=4false
answer is null
0 0 0~0
这个问题在blog上传之前还没解决。
感觉应该是逻辑问题。
第三次作业存在许多我还没解决的小问题,如答案为空字符时的输出以及空白卷输出(没搞懂怎么个空白卷0-0).
改进建议
我对我自己的代码的改正有许多点:
1.学一下怎么用ArrayList去搞动态类数组,不然以后题目量超过1定义时设定的值时会出现超定义问题,这对于一个完整的程序是致命的。
如我的代码:
paper[] papers=new paper[11];
tm[] tms=new tm[10];
mark[] marks=new mark[11];
test[] tests=new test[10];
如果不是测试点没做大量题目测试我也就不会及格了。
2.这三次大作业中我的类基本上只有属性定义的基本方法,没有其他在获取信息时的方法,也就是没有做到老师说的面向对象编程的理念,有点习惯于c语言的面向过程的编程理念,这个问题解决后代码的繁杂程度应该也会下降。
我的朴素的类定义:
class tm{
int n;
String Q;
String sA;
public tm(int fn,String fsA,String fQ)
{
n=fn;
sA=fsA;
Q=fQ;
}
}
就完全没有方法。。。
3.改进正则表达式的判定逻辑,感觉那个叫答案为空白字符的测试点就是因为匹配逻辑没有弄完全就搞不出来正确答案。
这个建议主要还是对于第三次大作业最后一题而言,前面两题都没有使用正则表达式或者是主要使用字符串数组处理。
总结
这三次题目集我做的并不是很好,处于及格水平,我感觉java的语法复杂度比c语言复杂太多太多了。类与对象是个很系统性的东西,没有c语言的语法那种随意性。这三次题目集让我对类与对象的概念更加清晰了,但这不是最大的收获,最大的收获是学会了好多好多关于字符串处理的方法和逻辑,学会了使用正则表达式去快速准确地匹配字符串。学会的东西还是不多,本来题目集要用Arraylist还有其他东西的,但我就没用,原因很简单,还没学会。。。这是一个很大的问题,我得赶紧研究研究这些语法然后试着将这三次大作业的代码进行改进。
对课堂的建议:
感觉三次题目集的小题目用到的语法和大题目差的有点多,我觉得应该有关联一点,这样在做大题目之前我们可以先熟悉熟悉将要用到的语法。
还有就是实验课的实验内容挺有意思的,感觉学到了很多电脑的使用知识,比如cmd命令行啥的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~