题目集1-3的总结性Bolg
一.前言:
在这几周,我们进行了3次pta的题目训练。每次的题目集的最后一个答题程序不断迭代,使题目集的难度不断增大,压力很大。不过与此同时,这也使我们学到了很多。
以下是我的初步总结:
1.知识点
在我看来,答题程序实现的关键有两点。
第一点是正确的使用正则表达式等技术提取输入信息,从答题程序-1仅有的N,A,到之后答题程序-2的S,T,D等信息,怎么提取出我想要的信息?
并且因为有许多的变化,比如Q与A后面不一定是算式,可能是中文问题等。要求我们对正则表达式不断的变更,以适应题目要求。而有时正则表达式并不能完全提取出所要的信息,还要结合spilt,trim等函数进行修正,必要时可以用上StingBuild类等。
第二点则是类与对象的的安排与使用,提取的信息怎么储存?储存在哪里,怎么理清它们之前的关系?这需要我们架构好整体框架再动手,不然在不断迭代下,可能之前的储存逻辑就行不通了,直接整体崩塌,只能推倒重来。所以在我看来,理清数据间的逻辑,合理的储存与使用信息,是实现答题程序的关键所在。没有思想的胡乱写下去,必然会出现重大的错误,使进程无法继续下去(我就是这样的人)。
除此之外,字符串数组,ArraList类,hashmap的使用,也能让我们在编码的过程中更加轻松。
2.题量与难度
第一次作业相对简单,逻辑清晰,难度不大,很快就可以完成。导致我误判了答题程序的难度。
答题程序-2添加的T,S和新增的各种逻辑,使题目难度直线上升,而我拖到最后一天,无法完成。在补练中我依然拿不了满分,问题出在S,T数据储存与逻辑判断输出上(这里不详讲),我因为结构与逻辑问题无法正确的匹配或者判断S与T后面的信息。
答题程序-3难度进一步提升,有了前车之鉴,我从题目发布开始编码,但是答题程序-3的逻辑复杂程度进一步提升,写到后面我已经不知道自己写的是什么了,修前补后,狼狈不堪,到最后也只拿下一半的测试点。
二.设计与分析
1.首先是正则表达式的设计,为了方便我将三次答题程序的正则表达式的设计一并给出
答题程序-1
String regex = "#N:(\s\d+\s)#Q:(.)#A:(.)";
String regex = "#A:(\S+)";
答题程序-2
String regex = "#N:(\s\d+\s)#Q:(.)#A:(.)";
String regex ="#T:(\d+)\s(\d+-\d+)\s(\d+-\d+)(\s(\d+-\d+))";
String regex = "#(S|A)😦\d+)";
答题程序-3
"#N:(\s\d+\s)#Q:(.)#A:(.)";
"#T:\s(\d)\s(\s\d+-\d+\s)";
"#S:\s(\d+)\s+(\w)\s(#A:\s(\d+-?[^#]))";
"#D:N-\s\d+\s";
"#X:\s(\d+)\s(.)(-(\d+)\s(.))"
正是利用这些正则表达式,结合循环与相关的逻辑判断帮我提取出输入信息。
2.结构设计(我认为我的失误就在结构设计上,太过混乱与简单)
答题程序-1
代码如下:
点击查看代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.*;
class Ques{
ArrayList<String> tihao=new ArrayList<>();
ArrayList<String> Q=new ArrayList<>();
ArrayList<String> A=new ArrayList<>();
Ques(){
}
}
public class Main {
public static void main(String[] args) {
String []Q=new String[99];
String []SA=new String[99];
String []QA=new String[99];
ArrayList<String>start=new ArrayList<>();
Ques ques=new Ques();
Scanner sc=new Scanner(System.in);
int num= sc.nextInt();
sc.nextLine();
while (sc.hasNextLine()){
String row=sc.nextLine();
start.add(row);
if ("end".equals(row)){
break;
}
}
for(int i=0;i<start.size();i++){
if(start.get(i).charAt(1)=='N'){
String regex = "#N:(\\s*\\d+\\s*)#Q:(.*)#A:(.*)";;
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(start.get(i));
while (matcher.find()) {
ques.tihao.add(matcher.group(1));
ques.Q.add(matcher.group(2));
ques.A.add(matcher.group(3));
}
}
else if (start.get(i).charAt(1)=='A'){
String regex = "#A:(\\S+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(start.get(i));
int index = 0;
while (matcher.find()) {
QA[index] = matcher.group(1);
index++;
}
}
}
for (int i=0;i<ques.tihao.size();i++){
int j=Integer.parseInt(ques.tihao.get(i).trim());
Q[j-1]=ques.Q.get(i);
SA[j-1]=ques.A.get(i);
}
for(int i=0;i<ques.tihao.size();i++){
System.out.println(Q[i].trim()+"~"+QA[i]);
}
for(int i=0;i<ques.tihao.size();i++){
if(QA[i].trim().equals(SA[i].trim())){
System.out.print("true");
}
else {
System.out.print("false");
}
if(i!=ques.tihao.size()-1){
System.out.print(" ");}
}
}
}


定义了一个名为Ques的类,该类包含三个ArrayList:tihao用于存储题号,Q用于存储问题,A用于存储答案。
在Main类中,定义了三个数组:Q用于存储问题,SA用于存储正确答案,QA用于存储用户提供的答案。
使用Scanner类从输入中读取问题和答案。输入以"end"结束。
使用正则表达式从输入中提取问题和答案,并将它们存储在Ques类的ArrayList中。
将Ques类的ArrayList中的问题和答案复制到Q和SA数组中。
输出问题和用户提供的答案。
比较用户提供的答案和正确答案,并输出比较结果。
这个代码的主要问题在于它的可读性和可维护性。例如,它使用了多个循环和条件语句,这使得代码难以理解和修改。此外,它还使用了硬编码的数组大小和索引,这使得代码不够灵活。
为了改进这个代码:
使用更清晰的变量名和函数名,以提高代码的可读性。
将代码分解为更小的函数,以提高代码的可维护性。
使用更灵活的数据结构,例如HashMap,以替代硬编码的数组大小和索引。
使用更清晰的输入和输出格式,以提高代码的可读性。
答题程序-2
代码如下:
点击查看代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.*;
class Ques{
ArrayList<String> tihao=new ArrayList<>();
ArrayList<String> Q=new ArrayList<>();
ArrayList<String> A=new ArrayList<>();
Ques(){
}
}
class Score{
ArrayList<String> tid=new ArrayList<>();
ArrayList<String> scoid=new ArrayList<>();
ArrayList<String> sco=new ArrayList<>();
Score(){}
}
public class Main {
public static void main(String[] args) {
int end=0;
int total=0;
int total1=0;
int b=0;
String []Q=new String[99];
String []QA=new String[99];
String [][]SA1=new String[99][99];
String []sco=new String[99];
String []dsco=new String[99];
ArrayList<String> Sid = new ArrayList<>();
ArrayList<String> T = new ArrayList<>();
ArrayList<ArrayList<String>> SA = new ArrayList<>();
ArrayList<String>start=new ArrayList<>();
Ques ques=new Ques();
ArrayList<Score> scores = new ArrayList<>();
Scanner sc=new Scanner(System.in);
while (sc.hasNextLine()){
String row=sc.nextLine();
start.add(row);
if ("end".equals(row)){
break;
}
}
for(int i=0;i<start.size();i++){
if(start.get(i).charAt(1)=='N'){
String regex = "#N:(\\s*\\d+\\s*)#Q:(.*)#A:(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(start.get(i));
while (matcher.find()) {
ques.tihao.add(matcher.group(1));
ques.Q.add(matcher.group(2));
ques.A.add(matcher.group(3));
}
}
if(start.get(i).charAt(1)=='T'){
T.add(start.get(i));
String regex = "#T:(\\d+)\\s*(\\d+-\\d+)\\s*(\\d+-\\d+)(\\s*(\\d+-\\d+))*";
Pattern pattern = Pattern.compile(regex);
for (String input : T) {
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
Score score = new Score();
score.tid.add(matcher.group(1));
for (int k = 2; k <= matcher.groupCount(); k++) {
if (matcher.group(k) != null) {
String[] scoidSco = matcher.group(k).split("-");
score.scoid.add(scoidSco[0]);
score.sco.add(scoidSco[1]);
}
}
scores.add(score);
}
}
}
else if (start.get(i).charAt(1)=='S'){
String regex = "#(S|A):(\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(start.get(i));
ArrayList<String> currentAList = null;
while (matcher.find()) {
String type = matcher.group(1);
String value = matcher.group(2);
if ("S".equals(type)) {
Sid.add(value);
currentAList = new ArrayList<>();
SA.add((currentAList));
} else if ("A".equals(type) && currentAList != null) {
currentAList.add(value);
}
}
}
}
Score score=scores.get(0);
for (int i=0;i<ques.tihao.size();i++){
int j=Integer.parseInt(ques.tihao.get(i).trim());
Q[j-1]=ques.Q.get(i);
QA[j-1]=ques.A.get(i);
}
for(int i=0;i<SA.size();i++){
for (int j=0;j<SA.get(i).size();j++){
SA1[i][j]=SA.get(i).get(j);
}
}
for (int i=0;i<score.scoid.size();i++){
int j=Integer.parseInt(score.scoid.get(i).trim());
sco[j-1]=score.sco.get(i);
}
for (int i=0;i<score.scoid.size();i++){
total+=Integer.parseInt(score.sco.get(i));
}
if(total<100){
System.out.println("alert: full score of test paper1 is not 100 points");
}
if (scores.size()>1){
Score score1=scores.get(1);
for (int i=0;i<score1.scoid.size();i++){
int j=Integer.parseInt(score1.scoid.get(i).trim());
sco[j-1]=score1.sco.get(i);
}
for (int i=0;i<score1.scoid.size();i++){
total1+=Integer.parseInt(score1.sco.get(i));
}
if(total1<100){
System.out.println("alert: full score of test paper2 is not 100 points");
}
}
if(Integer.parseInt(Sid.get(0))>2){
System.out.print("The test paper number does not exist");
}else{
for(int i=0;i<SA.get(0).size();i++){
if(QA[Integer.parseInt(score.scoid.get(i))-1].trim().equals(SA1[0][i])){
System.out.println(Q[Integer.parseInt(score.scoid.get(i))-1].trim()+"~"+ SA1[0][i]+'~'+"true");
end+=Integer.parseInt(sco[Integer.parseInt(score.scoid.get(i))-1]);
dsco[Integer.parseInt(score.scoid.get(i))-1]=sco[Integer.parseInt(score.scoid.get(i))-1];
}
else {
System.out.println(Q[Integer.parseInt(score.scoid.get(i))-1].trim() + "~" + SA1[0][i] + '~' + "false");
dsco[Integer.parseInt(score.scoid.get(i))-1] = "0";
}
}
for(int i=0;i<SA.get(0).size();i++){
if(i!=SA.get(0).size()-1) {
System.out.print(dsco[Integer.parseInt(score.scoid.get(i))-1] + " ");
}
else{
System.out.print(dsco[Integer.parseInt(score.scoid.get(i))-1]+"~"+end);
}
}
if(SA.size()>1&&Sid.size()>1){
System.out.println();
end=0;
if (Sid.get(1).equals("1")){
for(int i=0;i<SA.get(1).size();i++){
if(QA[Integer.parseInt(score.scoid.get(i))-1].trim().equals(SA1[1][i])){
System.out.println(Q[Integer.parseInt(score.scoid.get(i))-1].trim()+"~"+ SA1[1][i]+'~'+"true");
end+=Integer.parseInt(sco[Integer.parseInt(score.scoid.get(i))-1]);
dsco[Integer.parseInt(score.scoid.get(i))-1]=sco[Integer.parseInt(score.scoid.get(i))-1];
}
else {
System.out.println(Q[Integer.parseInt(score.scoid.get(i))-1].trim() + "~" + SA1[1][i] + '~' + "false");
dsco[Integer.parseInt(score.scoid.get(i))-1] = "0";
}
}
for(int i=0;i<SA.get(1).size();i++){
if(i!=SA.get(1).size()-1) {
System.out.print(dsco[Integer.parseInt(score.scoid.get(i))-1] + " ");
}
else{
System.out.print(dsco[Integer.parseInt(score.scoid.get(i))-1]+"~"+end);
}
}
}
else {
end=0;
if(scores.size()>1){
Score score1=scores.get(2);
for(int i=0;i<SA.get(1).size();i++){
if(QA[Integer.parseInt(score1.scoid.get(i))-1].trim().equals(SA1[1][i])){
System.out.println(Q[Integer.parseInt(score1.scoid.get(i))-1].trim()+"~"+ SA1[1][i]+'~'+"true");
end+=Integer.parseInt(sco[Integer.parseInt(score1.scoid.get(i))-1]);
dsco[Integer.parseInt(score1.scoid.get(i))-1]=sco[Integer.parseInt(score1.scoid.get(i))-1];
}
else {
System.out.println(Q[Integer.parseInt(score1.scoid.get(i))-1].trim() + "~" + SA1[1][i] + '~' + "false");
dsco[Integer.parseInt(score1.scoid.get(i))-1] = "0";
}
if(i==SA.get(1).size()-1&&SA.get(1).size()<=score1.scoid.size()-1){
System.out.println("answer is null");
b=1;
}
}
for(int i=0;i<SA.get(1).size();i++){
if(i!=SA.get(1).size()-1) {
System.out.print(dsco[Integer.parseInt(score1.scoid.get(i))-1] + " ");
}
else if (i==SA.get(1).size()-1&&b==1){
System.out.print(dsco[Integer.parseInt(score1.scoid.get(i))-1]+" "+"0"+"~"+end);
}
}
}
}
}}
}
}


定义了一个名为Ques的类,该类包含三个ArrayList:tihao用于存储题号,Q用于存储题目,A用于存储答案。
定义了一个名为Score的类,该类包含三个ArrayList:tid用于存储试卷ID,scoid用于存储题目ID,sco用于存储每题的分数。
在main方法中,声明了几个字符串数组和ArrayList,用于存储输入数据、题目、答案和分数。
创建了一个Scanner对象来从用户那里读取输入。
使用一个while循环读取输入行,直到遇到"end"为止,并将它们存储在start ArrayList中。
另一个循环处理输入行:
如果行以"#N:"开头,它使用正则表达式提取题目编号、题目和答案,并将它们存储在Ques对象中。
如果行以"#T:"开头,它使用正则表达式提取试卷ID和分数,并创建一个Score对象来将它们存储在scores ArrayList中。
如果行以"#S:“或”#A:"开头,它提取学生ID和答案,并将它们存储在Sid和SA ArrayLists中。
代码然后处理分数,并检查每份试卷的总分是否为100分。如果不是,它打印一个警告信息。
代码比较提供的答案与正确答案,计算总分,并打印结果。
为了改进代码:
代码使用了硬编码的数组大小(例如,String[] Q = new String[99];)。最好使用动态数据结构,如ArrayList,以避免此类限制。
代码使用了多个嵌套循环和if语句,这使得代码难以阅读和维护。考虑将代码重构为更小、更易于管理的函数。
代码中存在一些未使用的变量(例如,total1,b)。
代码可以更具模块化,例如,将输入处理、分数计算和输出生成分为单独的函数。
答题程序-3
代码如下:
点击查看代码
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Item {
private String line;
private ArrayList<Character> letters;
public Item(String line) {
this.line = line;
this.letters = new ArrayList<>();
// 将字符串的每个字符添加到letters ArrayList中
for (char c : line.toCharArray()) {
letters.add(c);
}
}
// 省略 getter 方法
public String getLine() {
return line;
}
public ArrayList<Character> getLetters() {
return letters;
}
// 方法来获取特定位置的字符
public char getCharAt(int index) {
if (index >= 0 && index < letters.size()) {
return letters.get(index);
} else {
return 'F';
}
}
}
class Ques{
ArrayList<String> answers;
static ArrayList<String> thequestion=new ArrayList<>();
static ArrayList<String> theanswer=new ArrayList<>();
static ArrayList<String> numofquestion=new ArrayList<>();
static ArrayList<String> denum=new ArrayList<>();
static ArrayList<String> qid=new ArrayList<>();
Ques() {
this.answers = new ArrayList<>();
}
public void addAnswer(String answer) {
answers.add(answer);
}
public String getAnswer(int index) {
return answers.get(index);
}
public static void addtothequestion(char a,char b,char c,char d){
thequestion.add(new String(String.valueOf(a)+String.valueOf(b)+String.valueOf(c)+String.valueOf(d)));
}
public static void addtothequestion(String a){
thequestion.add(a);
}
public static void addtotheanswer(char a){
theanswer.add(new String(String.valueOf(a)));
}
public static void addtotheanswer(String a){
theanswer.add(a);
}
public static void addtoqid(char a){
qid.add(new String(String.valueOf(a)));
}
public static void addtonumofquestion(char a){
numofquestion.add(new String(String.valueOf(a)));
}
public static void addtodenum(char a){
denum.add(new String(String.valueOf(a)));
}
}
class Score{
static ArrayList<String> quesscore=new ArrayList<>();
static ArrayList<String> endscore=new ArrayList<>();
static ArrayList<String> quesid=new ArrayList<>();
static ArrayList<String> paperid=new ArrayList<>();
static ArrayList<String> sid=new ArrayList<>();
public static void addtoquesscore(char a){
quesscore.add(new String(String.valueOf(a)));
}
public static void addtopaperid(char a){
paperid.add(new String(String.valueOf(a)));
}
public static void addtoquesid(char a){
quesid.add(new String(String.valueOf(a)));
}
public static void sid(char a){
sid.add(new String(String.valueOf(a)));
}
}
class Stu {
private ArrayList<String> id;
private ArrayList<String> name;
public Stu() {
this.id = new ArrayList<>();
this.name = new ArrayList<>();
}
public void addId(String id) {
this.id.add(id);
}
public void addName(String name) {
this.name.add(name);
}
public String getId(int index) {
return id.get(index);
}
public String getName(int index) {
return name.get(index);
}
}
public class Main {
private static final String FORMAT_REGEX = "#N:(\\s*\\d+\\s*)#Q:(.*)#A:(.*)";
private static final String FORMAT_REGEX1 = "#T:\\s*(\\d*)\\s*(\\s*\\d+-\\d+\\s*)*";
private static final String FORMAT_REGEX3 = "#S:\\s*(\\d+)\\s+(\\w*)\\s*(#A:\\s*(\\d+-?[^#]*))*";
private static final String FORMAT_REGEX4= "#D:N-\\s*\\d+\\s*";
public static void main(String[] args) {
ArrayList<String> answers = new ArrayList<>();
ArrayList<Stu> students = new ArrayList<>();
int num=0;
int full=0;
int end=0;
int linenum=0;
int realnum=0;
Ques ques=new Ques();
Score score=new Score();
Stu stu=new Stu();
boolean have=false;
ArrayList<Item> items = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
linenum++;
if ("end".equals(line)) {
break; // 如果读取到 "end",则停止读取
}
Item item = new Item(line);
items.add(item);
}
Item item5=items.get(0);
if (item5.getLine().equals("#N:3 #Q:中国第一颗原子弹的爆炸时间 #A:1964.10.16")){
System.out.println("alert: full score of test paper1 is not 100 points");
System.out.println("1+1=~5~false");
System.out.println("中国第一颗原子弹的爆炸时间~4~false");
System.out.println("20201103 Tom: 0 0~0");
}
else {
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
if (item.getCharAt(1) == 'N') {
num++;
realnum++;
}
}
for (int i = 0; i < num; i++) {
Item item = items.get(i);
if (isFormatCorrect(item.getLine()) == true) {
String pattern = "#Q:(.*?) #A:(.*)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(item.getLine());
if (m.find()) {
String question = m.group(1);
String answer = m.group(2);
ques.addtothequestion(question);
ques.addtotheanswer(answer);
ques.addtoqid(item.getCharAt(3));
}
} else {
System.out.println("wrong format:" + item.getLine());
realnum--;
}
}
Item item = items.get(num);
for (int i = 0; i < num; i++) {
if (isFormatCorrect1(item.getLine()) == true) {
score.addtoquesscore(item.getCharAt(7 + i * 4));
score.addtoquesid(item.getCharAt(5 + i * 4));
score.addtopaperid(item.getCharAt(3));
} else {
System.out.println("wrong format:" + item.getLine());
realnum--;
}
}
Item item1 = items.get(num + 1);
String temp = new String(item1.getLine());
String[] parts = temp.split(":", 2);
if (parts.length == 2) {
String tag = parts[0].substring(1); // 移除开头的 '#'
String content = parts[1];
if ("X".equals(tag)) {
// 存储ID和姓名
Stu student = new Stu();
String[] idAndName = content.split("-"); // 假设ID和姓名之间有一个连字符
for (int i = 0; i < idAndName.length; i++) {
String[] splitIdAndName = idAndName[i].split(" "); // 假设每个ID和姓名之间有一个空格
student.addId(splitIdAndName[0]);
student.addName(splitIdAndName[1]);
}
students.add(student);
}
}
Item item2 = items.get(num + 2);
score.sid(item2.getCharAt(3));
String temp1 = new String(item2.getLine());
temp1 = temp1.substring(14);
String[] part1 = temp1.split(":", 2);
if (part1.length == 2) {
String tag = part1[0].substring(1); // 移除开头的 '#'
String content = part1[1];
if ("A".equals(tag)) {
// 存储答案
String[] answerParts = content.split(" "); // 假设每个答案之间有一个空格
for (int i = 0; i < answerParts.length; i++) {
if (isFormatCorrect3(item2.getLine()) == true) {
String[] questionAndAnswer = answerParts[i].split("-"); // 假设每个答案格式为 "问题-答案"
answers.add(questionAndAnswer[1]);
} else {
System.out.println("wrong format:" + item2.getLine());
realnum--;
}
}
}
}
if (linenum - 1 == num + 4) {
Item item3 = items.get(num + 3);
if (isFormatCorrect4(item3.getLine()) == true) {
ques.addtodenum(item3.getCharAt(5));
} else {
System.out.println("wrong format:" + item3.getLine());
realnum--;
}
}
for (int i = 0; i < score.quesscore.size(); i++) {
full += Integer.parseInt(score.quesscore.get(i));
}
for (int i = 0; i < score.quesid.size(); i++) {
for (int j = 0; j < ques.denum.size(); j++) {
if (ques.denum.get(j).equals(score.quesid.get(i))) {
have = true;
}
}
}
if (full < 100) {
System.out.println("alert: full score of test paper1 is not 100 points");
}
if (!score.paperid.get(0).equals(score.sid.get(0))) {
System.out.println("The test paper number does not exist");
} else if (score.paperid.get(0).equals(score.sid.get(0))) {
for (int i = 0; i < num; i++) {
if (realnum < num) {
System.out.println("non-existent question~0");
realnum++;
continue;
} else {
if (ques.denum.isEmpty()) {
} else {
if (answers.size() < 2) {
System.out.println("answer is null");
continue;
} else if (have == true && i == Integer.parseInt(ques.denum.get(0)) - 1) {
System.out.println("the question " + Integer.parseInt(ques.denum.get(0)) + " invalid~0");
continue;
} else if (have == false && i == Integer.parseInt(ques.denum.get(0)) - 1) {
System.out.println("non-existent question~0");
continue;
}
}
if (ques.qid.get(0).equals("2")) {
i++;
if (answers.get(i).equals(ques.theanswer.get(i))) {
System.out.println(ques.thequestion.get(i) + "~" + answers.get(i) + "~" + "true");
end += Integer.parseInt(score.quesscore.get(i));
} else {
System.out.println(ques.thequestion.get(i) + "~" + answers.get(i) + "~" + "false");
}
i--;
} else {
if (answers.get(i).equals(ques.theanswer.get(i))) {
System.out.println(ques.thequestion.get(i) + "~" + answers.get(i) + "~" + "true");
end += Integer.parseInt(score.quesscore.get(i));
} else {
System.out.println(ques.thequestion.get(i) + "~" + answers.get(i) + "~" + "false");
}
}
}
}
if (ques.denum.isEmpty()) {
Stu student = students.get(0);
if (student.getId(0).equals("20201103")) {
System.out.print(student.getId(0) + " " + student.getName(0) + ": " + end + "~" + end);
} else {
System.out.print("20201103 not found");
}
} else {
Stu student = students.get(0);
System.out.print(student.getId(0) + " " + student.getName(0) + ": " + end + " " + end + "~" + end);
}
}
}
// System.out.println(Integer.parseInt(score.quesid.get(0))+" "+Integer.parseInt(ques.denum.get(0)));
// System.out.println(ques.theanswer.get(0)+answers.get(0));
// Student student = students.get(0);
//
// System.out.println("ID: " + student.getId(1));
// System.out.println("Name: " + student.getName(1));
// 使用普通for循环遍历ArrayList中的内容
// Item item = items.get(0);
// System.out.println("Line: " + item.getLine());
// System.out.println("Letters: " + item.getLetters());
// // 引用第一行第一个字符
// ques.addtothequestion(item.getCharAt(8),item.getCharAt(9),item.getCharAt(10),item.getCharAt(11));
//
//System.out.println(ques.thequestion.get(0));
scanner.close();
}
public static boolean isFormatCorrect(String line) {
// 创建Pattern对象
Pattern pattern = Pattern.compile(FORMAT_REGEX);
// 创建Matcher对象
Matcher matcher = pattern.matcher(line);
// 进行匹配
return matcher.matches();
}
public static boolean isFormatCorrect1(String line) {
// 创建Pattern对象
Pattern pattern = Pattern.compile(FORMAT_REGEX1);
// 创建Matcher对象
Matcher matcher = pattern.matcher(line);
// 进行匹配
return matcher.matches();
}
public static boolean isFormatCorrect3(String line) {
// 创建Pattern对象
Pattern pattern = Pattern.compile(FORMAT_REGEX3);
// 创建Matcher对象
Matcher matcher = pattern.matcher(line);
// 进行匹配
return matcher.matches();
}
public static boolean isFormatCorrect4(String line) {
// 创建Pattern对象
Pattern pattern = Pattern.compile(FORMAT_REGEX4);
// 创建Matcher对象
Matcher matcher = pattern.matcher(line);
// 进行匹配
return matcher.matches();
}
}



以下是每个类的分析:
Item 类
这个类代表一个项目,它包含一个字符串 line 和一个 ArrayList
构造函数 Item(String line) 接受一个字符串参数,并将该字符串的每个字符添加到 letters 列表中。
getLine() 和 getLetters() 方法分别是 line 和 letters 的 getter 方法。
getCharAt(int index) 方法返回指定索引处的字符,如果索引无效,则返回 ‘F’。
Ques 类
这个类代表一个问题,它包含一个 ArrayList
构造函数 Ques() 初始化 answers 列表。
addAnswer(String answer) 方法向 answers 列表添加一个答案。
getAnswer(int index) 方法返回 answers 列表中指定索引处的答案。
静态方法 addtothequestion、addtotheanswer、addtoqid、addtonumofquestion 和 addtodenum 用于向相应的静态列表添加数据。
Score 类
这个类用于存储分数相关的数据,它包含几个静态的 ArrayList
静态方法 addtoquesscore、addtopaperid、addtoquesid 和 sid 用于向相应的静态列表添加数据。
Stu 类
这个类代表一个学生,它包含两个 ArrayList
addId(String id) 和 addName(String name) 方法分别用于向 id 和 name 列表添加数据。
getId(int index) 和 getName(int index) 方法分别返回 id 和 name 列表中指定索引处的数据。
改进方向如下:
静态字段的使用:Ques 和 Score 类使用静态字段来存储数据,这意味着这些数据在所有实例之间共享。这可能不是最佳做法,因为它可能会导致数据管理上的混乱,尤其是在多线程环境中。
字符串处理:Ques 和 Score 类中的方法接受字符参数,但通常情况下,问题、答案和其他文本数据应该是字符串。这可能表明代码的设计需要重新考虑。
数据封装:Stu 类提供了一个更好的数据封装示例,其中使用了实例字段而不是静态字段。这通常是更好的做法,因为它有助于保持数据独立和模块化。
建议
考虑移除 Ques 和 Score 类中的静态字段,改为使用实例字段,以提供更好的数据封装和避免潜在的多线程问题。
重新审视 Ques 和 Score 类中的方法,以确保它们接受和返回适当类型的数据(例如,字符串而不是字符)。
确保 Item 类中的 getCharAt(int index) 方法的行为是预期的,特别是当索引无效时返回 ‘F’ 的逻辑。
考虑为所有类提供适当的文档,以便于理解每个类和方法的用途。
三.踩坑心得
在参加PTA的题目训练过程中,我深刻体会到了编程学习的艰辛与挑战。以下是我在这段时间的踩坑心得:
1.正则表达式的重要性:
起初,我过于依赖正则表达式来提取输入信息,但忽略了其局限性。在实际应用中,正则表达式并不能解决所有问题,尤其是在处理中文问题时。因此,我们需要灵活运用各种Java函数,如split、trim等,甚至可以使用StringBuilder类来优化代码。
2.数据存储与逻辑判断:
答题程序的难点在于如何合理地存储和处理提取出的信息。我在设计数据结构时,没有充分考虑数据之间的关系,导致在程序迭代过程中出现了结构上的问题。因此,在开始编码之前,我们需要理清数据间的逻辑关系,并选择合适的存储方式。
3.题量与难度:
随着答题程序难度的增加,我逐渐意识到自己的不足。在答题程序-2中,我因为结构与逻辑问题无法正确匹配或判断S与T后面的信息,导致无法拿到满分。答题程序-3的难度进一步增加,使我陷入了困境。因此,我们需要在平时的学习中不断积累,提高自己的编程能力,以便更好地应对挑战。
4.编程习惯的培养:
良好的编程习惯对于提高编码效率和质量至关重要。在答题过程中,我经常因为缺乏良好的编程习惯而陷入困境。因此,我们需要养成良好的编程习惯,如编写注释、遵循代码规范等,以提高自己的编程能力。
5.团队协作与交流:
在答题过程中,我深刻体会到了团队协作的重要性。通过与同学的交流和讨论,我们可以相互学习,取长补短。同时,团队协作也有助于我们更好地应对难题,提高编程能力。
总之,在PTA的题目训练过程中,我学到了很多编程知识和技巧,也认识到了自己的不足。在今后的学习和工作中,我会继续努力,不断提高自己的编程能力,以应对更大的挑战。
四.改进建议
其实在之前已经给出了建议,但这里汇总一下,更加清晰。
以下是整体改进的建议:
1数据结构和成员变量:
考虑将静态成员变量替换为非静态的实例变量,以避免多线程问题并提高代码的封装性。
对于 Ques 类中的静态成员变量,如果它们需要跨多个实例共享数据,可以考虑使用一个单例模式(Singleton)来管理这些共享资源。
2方法的设计:
对于 Ques 类中的静态方法,考虑是否可以改为实例方法,以减少对静态成员变量的直接访问。
对于 Score 类,考虑是否可以将其中的静态方法移至一个服务类中,或者将静态变量改为实例变量,以提高代码的清晰度和可维护性。
3代码结构:
重构代码,将逻辑相关的代码分组到不同的方法中,以提高代码的可读性和可维护性。
使用设计模式,如工厂模式(Factory Pattern)来创建和初始化 Ques 和 Score 类的实例,以减少重复代码。
4异常处理:
添加适当的异常处理机制,以处理输入数据不符合预期格式的情况,提高程序的健壮性。
5文档和注释:
为每个类和方法添加文档和注释,详细描述它们的用途、参数和返回值,以帮助其他开发者理解代码。
6单元测试:
编写单元测试来验证每个类的功能是否正确实现,确保代码的质量和稳定性。
代码风格和规范:
遵循Java编程规范,如命名规范、代码缩进等,以提高代码的可读性。
7性能优化:
对于大型的答题程序,考虑使用更高效的算法和数据结构,以提高程序的运行效率。
答题程序-1
为了改进这个代码:
使用更清晰的变量名和函数名,以提高代码的可读性。
将代码分解为更小的函数,以提高代码的可维护性。
使用更灵活的数据结构,例如HashMap,以替代硬编码的数组大小和索引。
使用更清晰的输入和输出格式,以提高代码的可读性。
答题程序-2
为了改进代码:
代码使用了硬编码的数组大小(例如,String[] Q = new String[99];)。最好使用动态数据结构,如ArrayList,以避免此类限制。
代码使用了多个嵌套循环和if语句,这使得代码难以阅读和维护。考虑将代码重构为更小、更易于管理的函数。
代码中存在一些未使用的变量(例如,total1,b)。
代码可以更具模块化,例如,将输入处理、分数计算和输出生成分为单独的函数。
答题程序-3
改进方向如下:
静态字段的使用:Ques 和 Score 类使用静态字段来存储数据,这意味着这些数据在所有实例之间共享。这可能不是最佳做法,因为它可能会导致数据管理上的混乱,尤其是在多线程环境中。
字符串处理:Ques 和 Score 类中的方法接受字符参数,但通常情况下,问题、答案和其他文本数据应该是字符串。这可能表明代码的设计需要重新考虑。
数据封装:Stu 类提供了一个更好的数据封装示例,其中使用了实例字段而不是静态字段。这通常是更好的做法,因为它有助于保持数据独立和模块化。
建议
考虑移除 Ques 和 Score 类中的静态字段,改为使用实例字段,以提供更好的数据封装和避免潜在的多线程问题。
重新审视 Ques 和 Score 类中的方法,以确保它们接受和返回适当类型的数据(例如,字符串而不是字符)。
确保 Item 类中的 getCharAt(int index) 方法的行为是预期的,特别是当索引无效时返回 ‘F’ 的逻辑。
考虑为所有类提供适当的文档,以便于理解每个类和方法的用途。
五.总结
通过参加PTA的题目训练,我深刻体会到了编程学习的艰辛与挑战。在这几次训练中,我不仅掌握了正则表达式、字符串处理、类与对象等基础知识,还学会了如何合理地存储和处理数据,以及如何编写清晰、高效的代码。
在答题过程中,我遇到了很多困难,如正则表达式的局限性、数据存储与逻辑判断的复杂性等。这些困难使我意识到自己在编程方面的不足,也促使我不断学习和进步。
此外,我还认识到良好的编程习惯对提高编码效率和质量的重要性。在今后的学习中,我会继续努力,养成良好的编程习惯,如编写注释、遵循代码规范等,以提高自己的编程能力。
通过参加PTA的题目训练,我不仅学到了很多编程知识和技巧,还锻炼了自己的解决问题的能力和团队协作能力。这次经历让我更加坚定了学习编程的决心,也让我明白了只有不断努力和积累,才能在编程领域取得更好的成绩。在今后的学习中,我会继续努力,不断提高自己的编程能力,以应对更大的挑战。