一.前言:
在這幾周,我們進行了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’ 的邏輯。
考慮為所有類提供適當的文件,以便於理解每個類和方法的用途。
三.踩坑心得
在參加P他的題目訓練過程中,我深刻體會到了程式設計學習的艱辛與挑戰。以下是我在這段時間的踩坑心得:
1.正規表示式的重要性:
起初,我過於依賴正規表示式來提取輸入資訊,但忽略了其侷限性。在實際應用中,正規表示式並不能解決所有問題,尤其是在處理中文問題時。因此,我們需要靈活運用各種Java函式,如split、trim等,甚至可以使用StringBuilder類來最佳化程式碼。
2.資料儲存與邏輯判斷:
答題程式的難點在於如何合理地儲存和處理提取出的資訊。我在設計資料結構時,沒有充分考慮資料之間的關係,導致在程式迭代過程中出現了結構上的問題。因此,在開始編碼之前,我們需要理清資料間的邏輯關係,並選擇合適的儲存方式。
3.題量與難度:
隨著答題程式難度的增加,我逐漸意識到自己的不足。在答題程式-2中,我因為結構與邏輯問題無法正確匹配或判斷S與T後面的資訊,導致無法拿到滿分。答題程式-3的難度進一步增加,使我陷入了困境。因此,我們需要在平時的學習中不斷積累,提高自己的程式設計能力,以便更好地應對挑戰。
4.程式設計習慣的培養:
良好的程式設計習慣對於提高編碼效率和質量至關重要。在答題過程中,我經常因為缺乏良好的程式設計習慣而陷入困境。因此,我們需要養成良好的程式設計習慣,如編寫註釋、遵循程式碼規範等,以提高自己的程式設計能力。
5.團隊協作與交流:
在答題過程中,我深刻體會到了團隊協作的重要性。透過與同學的交流和討論,我們可以相互學習,取長補短。同時,團隊協作也有助於我們更好地應對難題,提高程式設計能力。
總之,在P他的題目訓練過程中,我學到了很多程式設計知識和技巧,也認識到了自己的不足。在今後的學習和工作中,我會繼續努力,不斷提高自己的程式設計能力,以應對更大的挑戰。
四.改進建議
其實在之前已經給出了建議,但這裡彙總一下,更加清晰。
以下是整體改進的建議:
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’ 的邏輯。
考慮為所有類提供適當的文件,以便於理解每個類和方法的用途。
五.總結
透過參加P他的題目訓練,我深刻體會到了程式設計學習的艱辛與挑戰。在這幾次訓練中,我不僅掌握了正規表示式、字串處理、類與物件等基礎知識,還學會了如何合理地儲存和處理資料,以及如何編寫清晰、高效的程式碼。
在答題過程中,我遇到了很多困難,如正規表示式的侷限性、資料儲存與邏輯判斷的複雜性等。這些困難使我意識到自己在程式設計方面的不足,也促使我不斷學習和進步。
此外,我還認識到良好的程式設計習慣對提高編碼效率和質量的重要性。在今後的學習中,我會繼續努力,養成良好的程式設計習慣,如編寫註釋、遵循程式碼規範等,以提高自己的程式設計能力。
透過參加P他的題目訓練,我不僅學到了很多程式設計知識和技巧,還鍛鍊了自己的解決問題的能力和團隊協作能力。這次經歷讓我更加堅定了學習程式設計的決心,也讓我明白了只有不斷努力和積累,才能在程式設計領域取得更好的成績。在今後的學習中,我會繼續努力,不斷提高自己的程式設計能力,以應對更大的挑戰。