第4-6次大作業BLOG

23201503-张婧發表於2024-06-09

目錄
  • 前言
  • 第四次大作業blog
    • 設計與分析
    • 踩坑心得
    • 改進建議
    • 總結
  • 第五次大作業
    • 設計與分析
    • 踩坑心得
    • 改進建議
    • 總結
  • 第六次大作業
    • 設計與分析
    • 踩坑心得
    • 改進建議

前言

第四次作業考察了我們list和map的使用,以及對正規表示式的掌握情況,類的設計與方法的使用,第五次作業和第六次作業是電路模擬,需要一定的物理電學知識。總體來說第四次和第六次作業較難,第五次作業相對容易。題量:第四次和第五次題量適中,第六次作業題量較少。

第四次大作業blog

設計與分析

第四次大作業在上一次的基礎上增加了多選題和填空題,本次作業需要儲存的資訊很多,我用了很多個map和list才完成儲存,新增了兩個map分別用於儲存多選題和填空題的題目,答案仍然存在原來的lsit中。由於每種題目所存的map不同,所以在本次作業中新增了一個屬性用於判斷題目的型別,使用了map.containsKey()方法判斷每個map中是否含有某個key。
本次作業還使用了繼承,新增的多選題和填空題和原來的題目所包含的屬性基本相同,所以可以直接繼承。多選題的多個答案用split方法以空格分開存到陣列裡,然後再分別遍歷答案陣列和標準答案陣列,判斷他們的內容與長度,便可判斷是正確、錯誤還是部分正確。
填空題則是使用matches方法判斷答案與標準答案是否有相同元素,如果沒有則可以直接判斷錯誤、,如果有相同元素再使用equals方法判斷兩個字串是否相同,若相同則全部正確,否則部分正確。

踩坑心得

在繼承的使用過程中不太熟悉,經常出現問題。

改進建議

1、類的劃分:目前程式碼中有很多類,但是它們的劃分並不清晰。
2、程式碼的冗餘:有些程式碼是重複的,可以考慮抽象出來成為公共的方法。
3、異常處理:在輸入解析和資料處理過程中,應該加入異常處理機制,以防止非法輸入或資料處理過程中的錯誤。

總結

本次作業難度相當大,我花了幾乎所以的時間來寫這道題,幸好最後寫出來了,之前的努力也都沒白費。透過這次作業我深刻了解了繼承的用法以及繼承帶來的好處。透過繼承,子類可以繼承父類的屬性和方法,使得程式碼的編寫變得更加簡潔和高效。
1、程式碼複用:繼承允許子類使用父類的程式碼,而不是每次都從頭開始編寫相同的程式碼。這增加了程式碼的複用性,減少了程式碼冗餘,使得程式更加簡潔和易於維護。
2、抽象和擴充套件:繼承有助於實現抽象和擴充套件功能。透過繼承,可以抽取出父類中的共性,形成子類,子類可以在此基礎上增加新的功能或對已有功能進行擴充套件。
3、提高程式碼的可重用性:子類可以繼承和擴充套件父類的方法和屬性,使得程式碼具有較高的可重用性,這有助於減少程式碼量,提高程式碼的執行效率。
4、降低程式碼的耦合度:透過繼承,可以讓程式碼的耦合度降低,提高程式碼的靈活性和可維護性。子類透過繼承父類,可以將父類的方法和屬性組合起來,形成自己的方法,這樣減少了程式碼之間的耦合關係,使得程式碼更易於理解和維護。

第五次大作業

設計與分析

第一次的電路模擬程式,我寫了一個父類,這個是所有的電路元件,包括串並聯的父類然後燈泡類和風扇類繼承這個父類,具體的燈泡和風扇繼承上面所寫的燈泡類和風扇類。但是我第一次作業沒有寫串聯類,將在第二次作業中補上。
第五次大作業我分為三步,首先是對輸入的讀取和儲存,然後判斷各個軟體包括開關,調速器,燈泡和風扇的狀態,最後是計算他們分別的電壓並且輸出結果。輸入的讀取我還是跟上次的大作業一樣,用正規表示式來匹配輸入的字串,然後再用多型的方法建立了一個宣告型別為最大父類,實際型別為他們本身的類的物件,並且將這個物件存入hashmap中。後面的開關和調速器的輸入我先匹配他們是什麼型別,然後再判斷map裡面有沒有這個物件如果有的話,開關就相對應的加一個檔位或者減一個檔位,調速器就讀取它們的檔位並且存起來。輸入完成後從map裡面迴圈找分別找到開關,分檔調速器和連續調速器,獲取他們的檔位求出相對應的電壓。在每個子類中寫出根據題目要求計算出對應電壓所對應的亮度和轉速的方法。排序輸出的話,在父類中分別將kflbrd對應為543210。父類中重寫compare to將每一個元件進行排序。然後從Map 物件中獲取所有的值,然後把這些值轉換成一個 Cir 型別的列表。這個列表將包含 Map 中所有值的 Cir 物件。假設 Cir 是一個自定義的類或者一個列舉型別。最後按照順序輸出。
在寫這道題目的過程中,我沒有考慮到最後輸出要按照題目所給的要求排序後再輸出,所以在這個問題上我沒有考慮周全,最後出了錯誤。並且在儲存輸入資訊時,沒有首先想到用hashmap來儲存,走了很多彎路。

踩坑心得

1、開始沒有設計總的父類,在後續的過程中思路混亂,程式碼複雜,後來老師發了類圖,設計了總的父類,相對來說能夠簡化程式碼,並且提高程式碼的可複用性。
2、沒有仔細閱讀題目,沒注意到要排序輸出,因此在後面總是有測試點過不了。

改進建議

1、新增一個串聯類,以便在後續的迭代中可以直接使用,不需要重新設計串聯與並聯類。
2、將電壓的計算放在每個類中的方法裡,簡化main方法,提高程式碼的可複用性。

總結

本次作業是第一次迭代,題目難度不算很大,我在分析題目輸入方面有待提高。

第六次大作業

設計與分析

第六次大作業在上一次作業的基礎上加入了並聯電路。所以在這次作業中我分別寫了串聯類和並類繼承父類。是作業的輸入也相較於上次作業發生了比較大的變化。上次作業是一條串聯分多行輸入,而這次作業是一條串聯一行輸入。因此這次作業的正規表示式與上次有所不同。不過我也還是按照上次的方法先對每個中括號中的元素用空格分隔開存入陣列中,然後再判斷他們的型別。這樣輸入一條串聯時就要用到迴圈。並聯電路中是兩條串聯電路,在並聯類中寫了一個串聯類的array list,儲存並聯中的每條串聯,包括他們的名字和串聯電路中的元件。輸入時,我根據串聯電路的最後來判斷是並聯中的子串聯還是整個電路的總串聯。電路中的資訊輸入完成之後,我也是按照與上一次作業一樣的方法來判斷電路中的開關和調速器的檔位,並將他們的檔位記錄下來。這次作業比上次多作業還多了一個電路元件落地扇,落地扇的資訊與吊扇一樣,輸出中也將每一種電器元件按照數字的方法來將它們排序輸出。不過這次作業中的計算電壓和電阻對我來說是一個難點。計算電壓的過程中,我將每一個電路元件每一條串聯電路和並聯電路中的串聯電路中的原件單獨計算他們的電壓。這種方法顯得非常地複雜冗餘,在以後的作業中我將會把電壓的計算寫在串聯和並聯類的中的一個方法裡,然後直接在main方法中呼叫這些方法,這樣能極大的簡化程式碼的複雜程度。

踩坑心得

1、開始時沒有仔細分析題目,跟第五次一樣直接用map儲存資料,後來發現本次作業相較於上次作業新增了很多內容,無法直接用map儲存,因此經過仔細的分析和與同學的討論,使用map與list共同儲存,解決了之前碰到的問題。
2、第六次大作業的輸入也與上次作業有所區別,本次作業的串聯是一行輸入,而上次是分多行輸入,因此本次作業的輸入不能與上次相同,而我剛開始與上次相同,因此總是非零返回。並且在這次作業的正規表示式匹配過程中也遇到了困難。
3、在輸入過程中map元素的新增放錯了位置,導致後來出現了一些問題。

改進建議

計算電壓的部分過於複雜,並且出現錯誤時很難發現

點選檢視程式碼
for (int i1 = 0; i1 < vcc.getList().size(); i1++) {
            if(vcc.getList().get(i1).getName().startsWith("M")) {
                for(int i2 = 0;i2<((Parallel)vcc.getList().get(i1)).getList().size();i2++) {
                    if(((Parallel)vcc.getList().get(i1)).getList().get(i2).state){
                        for(int i3 = 0;i3<((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().size();i3++) {
                            if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("D")) {
                                double U1 = vcc.getList().get(i1).dz/dz2*U;
                                ((D)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(U1*((D)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).dz/((Parallel)vcc.getList().get(i1)).getList().get(i2).dz);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("A")) {
                                double U1 = vcc.getList().get(i1).dz/dz2*U;
                                ((A)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(U1*((A)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).dz/((Parallel)vcc.getList().get(i1)).getList().get(i2).dz);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("B")) {
                                double U1 = vcc.getList().get(i1).dz/dz2*U;
                                ((B)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(U1*((B)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).dz/((Parallel)vcc.getList().get(i1)).getList().get(i2).dz);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("R")) {
                                double U1 = vcc.getList().get(i1).dz/dz2*U;
                                ((R)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(U1*((R)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).dz/((Parallel)vcc.getList().get(i1)).getList().get(i2).dz);
                            }else {
                                
                            }
                        }
                    }
                    else{
                        for(int i3 = 0;i3<((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().size();i3++) {
                            if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("D")) {
                                ((D)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(0);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("A")) {
                                ((A)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(0);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("B")) {
                                ((B)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(0);
                            }else if(((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3).getName().startsWith("R")) {
                                ((R)((Parallel)vcc.getList().get(i1)).getList().get(i2).getList().get(i3)).cul(0);
                            }else {
                                
                            }
                        }
                    }
                }
            }else if (vcc.getList().get(i1).getName().startsWith("D")) {
                double U1 = vcc.getList().get(i1).dz / dz2 * U;
                ((D) (vcc.getList().get(i1))).cul(U1);
            } else if (vcc.getList().get(i1).getName().startsWith("A")) {
                double U1 = vcc.getList().get(i1).dz / dz2 * U;
                ((A) (vcc.getList().get(i1))).cul(U1);
            } else if (vcc.getList().get(i1).getName().startsWith("R")) {
                double U1 = vcc.getList().get(i1).dz / dz2 * U;
                ((R) (vcc.getList().get(i1))).cul(U1);
            } else if (vcc.getList().get(i1).getName().startsWith("B")) {
                double U1 = vcc.getList().get(i1).dz / dz2 * U;
                ((B) (vcc.getList().get(i1))).cul(U1);
            }else{
            }
所以我將這段又長又臭的程式碼寫成了方法放在類,直接在main方法中呼叫即可。 在串聯類中計算電壓的方法:
點選檢視程式碼
public void culU(double U){
        double U1;
        for(int i = 0;i<list.size();i++){
            if(list.get(i) instanceof A){
                U1 = (A)list.get(i).dz/dz*U;
                ((A)list.get(i)).cul(U1);
            }else if(list.get(i) instanceof B){
                U1 = (B)list.get(i).dz/dz*U;
                ((B)list.get(i)).cul(U1);
            }else if(list.get(i) instanceof R){
                U1 = (R)list.get(i).dz/dz*U;
                ((R)list.get(i)).cul(U1);
            }else if(list.get(i) instanceof D){
                U1 = (D)list.get(i).dz/dz*U;
                ((D)list.get(i)).cul(U1);
            }else if(list.get(i) instanceof Series){
                U1 = (Series)list.get(i).dz/dz*U;
                ((Series)list.get(i)).culU(U1);
            }else if(list.get(i) instanceof Parallel){
                U1 = (Parallel)list.get(i).dz/dz*U;
                ((Parallel)list.get(i)).culU(U1);
            }
        }
}
並聯電路中計算電壓的方法:
點選檢視程式碼
public void culU(double U){
        for(int i = 0;i<list.size();i++){
            ((Series)list.get(i)).culU(double U);
        }
    }
Main方法中呼叫方法計算電壓: vcc.culU(U1); 這樣寫不僅簡便易懂,還不容易出錯,程式碼的可複用性極強。 ##總結 這次大作業難度挺大,我花了好長時間才寫完,期間還找人幫忙改了bug。 但是透過這次大作業我也學到了很多東西,明白了方法的好處,程式碼的可複用性的重要性。![](https://img2024.cnblogs.com/blog/3432660/202406/3432660-20240609142947147-989243710.png) 1788073502.png)