PTA4~6次作業總結

俞博昊發表於2024-06-09

(1)前言:
不同於大一上的c語言的PTA作業,java的PTA作業越來越貼近生活中的需求,難度也越來越大了,程式碼的設計量和題目考察的知識點也是.最後一次作業沒有給測試樣例,導致有幾個點沒過,不知道錯哪了,測不出來,非常的難受.
這次作業使用了ArryList
先了解下ArryList
ArrayList 類是一個可以動態修改的陣列,與普通陣列的區別就是它是沒有固定大小的限制,我們可以新增或刪除元素。ArrayList 繼承了 AbstractList ,並實現了 List 介面。

1.ArrayList 類位於 java.util 包中,使用前需要引入它,語法格式如下:
程式碼如下(示例):

import java.util.ArrayList; // 引入 ArrayList 類
 
ArrayList<E> objectName =new ArrayList<>();  // 初始化

E: 泛型資料型別,用於設定 objectName 的資料型別,只能為引用資料型別。
objectName: 物件名
ArrayList 中的元素實際上是物件,在以上例項中,陣列列表元素都是字串 String 型別。

如果我們要儲存其他型別,而 只能為引用資料型別,這時我們就需要使用到基本型別的包裝類。

基本型別對應的包裝類表如下:

Java ArrayList 常用方法列表如下:

(2)設計與分析:
這次新加的連續題目集,家庭電路,思路非常的簡單,但是其中的計算有些難搞.(頭大)
題目的設計圖老師給了
設計建議:

1、電路裝置類:描述所有電路裝置的公共特徵。

2、受控裝置類、控制裝置類:對應受控、控制裝置

3、串聯電路類:一條由多個電路裝置構成的串聯電路,也看成是一個獨立的電路裝置

其他類以及類的屬性、方法自行設計。

就照著老師給的照搬了下來,省事嘿嘿.(-)

一開始看到題目說把串聯電路類看成是一個獨立的電路裝置時都懵了,不知道啥意思,後向想了想後面要遍歷串並聯電路才好做,所以要把它看成一個特殊的電路裝置.

輸入:
題目給的樣例是這樣的

這讓我想起了上次大作業的答題的輸入,所以我選擇了透過正規表示式來獲取輸入資訊

                String regStr = "(([\\w])[\\d])\\-1";
                String regStr1="(T[\\d])";
                String regStr2 = "(([\\w])[\\d])\\-IN";
                Pattern pattern = Pattern.compile(regStr);
                Pattern pattern1 = Pattern.compile(regStr1);
                Pattern pattern2 = Pattern.compile(regStr2);
                Matcher matcher = pattern.matcher(str);
                Matcher matcher1 = pattern1.matcher(str);
                Matcher matcher2 = pattern2.matcher(str);
                if(matcher1.find()){
                    seriesCircuits1.setName(matcher1.group());

獲取完資訊後,我才用ArryList將一個個資料儲存

 while (matcher.find()){
                    if (matcher.group(2).compareTo("K") == 0) {
                        K k = new K();
                        k.setName(matcher.group(1));
                        equipment1.add(k);
                        equipment.add(k);
                    }
                    if (matcher.group(2).compareTo("F") == 0) {
                        F f = new F();
                        f.setName(matcher.group(1));
                        equipment1.add(f);
                        equipment.add(f);
                    }
                    if (matcher.group(2).compareTo("L") == 0) {
                        L l = new L();
                        l.setName(matcher.group(1));
                        equipment1.add(l);
                        equipment.add(l);
                    }
                    if (matcher.group(2).compareTo("B") == 0) {
                        B b = new B();
                        b.setName(matcher.group(1));
                        b.setResistance(10);
                        equipment1.add(b);
                        equipment.add(b);
                    }
                    if (matcher.group(2).compareTo("R") == 0) {
                        R r = new R();
                        r.setName(matcher.group(1));
                        r.setResistance(5);
                        equipment1.add(r);
                        equipment.add(r);
                    }
                    if (matcher.group(2).compareTo("D") == 0) {
                        D d = new D();
                        d.setName(matcher.group(1));
                        d.setResistance(20);
                        equipment1.add(d);
                        equipment.add(d);
                    }
                    if (matcher.group(2).compareTo("A") == 0) {
                        A a = new A();
                        a.setName(matcher.group(1));
                        a.setResistance(20);
                        equipment1.add(a);
                        equipment.add(a);
                    }
                    if(matcher2.find()){
                        M m = new M();
                        m.setName(matcher2.group(1));
                        equipment1.add(m);
                    }
                    str = str.substring(matcher.end());
                    matcher = pattern.matcher(str);

                }

搞完這個就要準備計算了,因為要求在最後再來處理精度的問題,
使用前面的資料傳遞使用的都是Double型別;
所有的計算都透過各自的類的方法進行,讓主函式里的程式碼看起來更加簡潔
這裡用到了多型,例如:
計算電阻時,因為串聯電路和並聯電路電阻的計算方法不一樣,但都需要計算他們的電阻,所以在他們的父類中定義了求電阻的方法,再在串聯電路和並聯電路中重寫方法,實習不同方式的求電阻,即實現了多型.


最後輸出是要對所有電器進行排序:

 public int compareTo(Equipment o) {
        String[] str={"K","F","L","B","R","D","A"};
        for(int i=0;i<str.length;i++)
        {
            if(this.getName().startsWith(str[i])){
                for(int j=0;j<str.length;j++)
                {
                    if(o.getName().startsWith(str[j])) {
                        if (i < j)
                            return -1;
                        else if (i == j)
                            return this.getName().charAt(1)-o.getName().charAt(1);
                        else
                            return 0;
                    }
                }
            }
        }
        return 0;
    }

使得電器按照一定順序輸出.

這道題的思路如圖:

(3)採坑心得:這次作業第一次提交發現資料對不上,檢查都發現是在傳遞資料時就把資料搞成整數了,後面的部分直接被丟棄了,導致後續計算出了問題.
後面又發現再有多個開關時,電路的開關有問題,當一個開關開,一個開關閉時,電路竟然是通電的,被自己整笑了當時.後面改進的電路閉合判斷的程式碼;

public boolean isLink(){
        link=true;
        for (Equipment equipment1 : equipments) {
            if (equipment1.getName().charAt(0) == 'K') {
                K k1 = (K) equipment1;
                if (k1.isOn_off()) {
                    link = false;
                }
            }
        }
        return link;
    }

在第一次作業時,我是透過關注輸入電壓輸出電壓的方式去計算整個電路,第一次作業沒考慮電阻,我是直接遍歷這個電路,從頭開始一個個傳遞電壓.

int size = equipment.size();
        for (int i = 0; i < size-1; i++) {
            Equipment equipment1=equipment.get(i);
            if(equipment1.getName().charAt(0)=='K'){
                K k1=(K)equipment1;
                equipment.get(i+1).setInput(k1.getOutput());
            }
            if(equipment1.getName().charAt(0)=='F'){
                F f1=(F)equipment1;
                equipment.get(i+1).setInput(f1.getOutput());
            }
            if(equipment1.getName().charAt(0)=='L'){
                L l1=(L)equipment1;
                equipment.get(i+1).setInput(l1.getOutput());
            }
            if(equipment1.getName().charAt(0)=='B'){
                B b1=(B)equipment1;
                equipment.get(i+1).setInput(b1.getOutput());
            }
            if(equipment1.getName().charAt(0)=='R'){
                R r1=(R)equipment1;
                equipment.get(i+1).setInput(r1.getOutput());
            }
            if(equipment1.getName().charAt(0)=='D'){
                D d1=(D)equipment1;
                equipment.get(i+1).setInput(d1.getOutput());
            }
        }

到第二次作業時要考慮電阻了,發現第一次的方法做不了,就改成求電流先,再去計算每個電路裝置說佔電壓.
(4)改進建議:計算方面要多搞幾個樣例測試,進一步提高程式碼的簡潔性,複用性,整個設計結構要最佳化,使得下次作業時也能用上現在的結構,不用再去大改.
正規表示式那塊可以剔除點,匹配一部分即可,但需要多次匹配.

(5)總結:
這次作業讓我越來越熟練的使用正規表示式去獲取資訊,認識了正則的效率問題.認識到實際工程中程式對各種不同狀況做出的反應都應該符合使用者需求。還有在資料傳遞中的資料完整性問題,在這種對資料準確度要求高的情景下,要儘可能的儲存傳遞完整的資料,不要"缺斤少兩".最後,最最重要的就是加強了物件導向的思維。

相關文章