1. 程式人生 > 其它 >java題目集四,實驗二,期中考試題目總結

java題目集四,實驗二,期中考試題目總結

前言

  在pta題目集4中,共有三題,第一題和第三題都相對容易,難度較低,考察的是使用正則表示式和設計一個類,根據題目含義以及使用split語句和一些java基本語法語句,能夠完成這兩個題目。第二題主要考察演算法,當然也需要使用正則表示式否則語句複雜度會很大,第二題的演算法對我而言還是具有挑戰性,雖然前面題目集三有過類似演算法,但其中還是有所不同,使用多個演算法不斷嘗試使用,但仍然有bug,而測試點是層層遞進的,導致數個測試點無法通過。

  在實驗二中,主要涉及的是類和類方法的構造,以及資料隱藏後的處理,難度低。需要根據所給程式碼來補充完善農夫過河的程式碼,實現其功能,然後再對farmer,wolf,sheep,cabbage進行資料封裝的改進,將屬性隱藏。增加Boat(船)類,設計船類的相應方法,並修改main方法中相關的程式碼,改進農夫帶東西過河的功能,解決之前程式碼中存在的農夫帶東西過河的判斷問題。為wolf,sheep 兩個類新增帶Stirng name引數的建構函式得出相應輸出結果。題目理解起來不難,根據題目要求可一步一步實現,完成相應輸出。

  在期中考試題目中,一共有三道題目,三題層層遞進的關係,每題在前一題的基礎上有所增加或修改,但整體難度不難,根據題目所給類圖和題意分析即可完成。第一題考察的是類設計方面的知識,難度低,只需要根據題目給出的類圖以及題意,按部就班的,使用Java類設計的方法和語法語句,一步步寫下去就能夠完成。第二題考察的是繼承與多型方面的知識,難度較低,只需建立父類抽象類,加入抽象方法,形成繼承關係,要注意抽象方法不能賦空。第三題考察的是容器類方面的知識,建立一個容器存入Element類物件,根據類圖和題意,建立相應方法能夠完成該題目,要注意remove方法刪除的位置是下標位置。

設計與分析

  題目集四:

 7-2 點線形系列4-凸四邊形的計算(70分)

使用者輸入一組選項和資料,進行與四邊形有關的計算。
以下四邊形頂點的座標要求按順序依次輸入,連續輸入的兩個頂點是相鄰頂點,第一個和最後一個輸入的頂點相鄰。
選項包括:
1:輸入四個點座標,判斷是否是四邊形、平行四邊形,判斷結果輸出true/false,結果之間以一個英文空格符分隔。
2:輸入四個點座標,判斷是否是菱形、矩形、正方形,判斷結果輸出true/false,結果之間以一個英文空格符分隔。 若四個點座標無法構成四邊形,輸出"not a quadrilateral"
3:輸入四個點座標,判斷是凹四邊形(false)還是凸四邊形(true),輸出四邊形周長、面積,結果之間以一個英文空格符分隔。 若四個點座標無法構成四邊形,輸出"not a quadrilateral"
4:輸入六個點座標,前兩個點構成一條直線,後四個點構成一個四邊形或三角形,輸出直線與四邊形(也可能是三角形)相交的交點數量。如果交點有兩個,再按面積從小到大輸出四邊形(或三角形)被直線分割成兩部分的面積(不換行)。若直線與四邊形或三角形的一條邊線重合,輸出"The line is coincide with one of the lines"。若後四個點不符合四邊形或三角形的輸入,輸出"not a quadrilateral or triangle"。
後四個點構成三角形的情況:假設三角形一條邊上兩個端點分別是x、y,邊線中間有一點z,另一頂點s:
1)符合要求的輸入:頂點重複或者z與xy都相鄰,如x x y s、x z y s、x y x s、s x y y。此時去除冗餘點,保留一個x、一個y。
2) 不符合要求的輸入:z 不與xy都相鄰,如z x y s、x z s y、x s z y
5:輸入五個點座標,輸出第一個是否在後四個點所構成的四邊形(限定為凸四邊形,不考慮凹四邊形)或三角形(判定方法見選項4)的內部(若是四邊形輸出in the quadrilateral/outof the quadrilateral,若是三角形輸出in the triangle/outof the triangle)。如果點在多邊形的某條邊上,輸出"on the triangle或者on the quadrilateral"。若後四個點不符合四邊形或三角形,輸出"not a quadrilateral or triangle"。

 輸入格式:

基本格式:選項+":"+座標x+","+座標y+" "+座標x+","+座標y。點的x、y座標之間以英文","分隔,點與點之間以一個英文空格分隔。

 輸出格式:

基本輸出格式見每種選項的描述。
異常情況輸出:
如果不符合基本格式,輸出"Wrong Format"。
如果符合基本格式,但輸入點的數量不符合要求,輸出"wrong number of points"。
注意:輸出的資料若小數點後超過3位,只保留小數點後3位,多餘部分採用四捨五入規則進到最低位。小數點後若不足3位,按原始位數顯示,不必補齊。例如:1/3的結果按格式輸出為 0.333,1.0按格式輸出為1.0

選項1、2、3中,若四邊形四個點中有重合點,輸出"points coincide"。
選項4中,若前兩個輸入線的點重合,輸出"points coincide"。

 度量分析:

   這題考察演算法,題目含義清楚,建立了點、線兩個類,剛開始使用正則表示式判斷輸入格式是否正確,再通過switch語句選擇對應選項,然後構造相應的方法完成題目所給測試點,但是計算的演算法思路不清晰,四邊形判斷方法的演算法有誤,無法正確判斷所有是否能構成四邊形的情況,於是數個與四邊形判斷有關的測試點無法通過,其他測試點均能夠通過。

主要程式碼分析:

boolean b=a.matches("^[1-5]{1}\\:(((\\-|\\+)?([1-9]\\d*|0)(\\.\\d+)?)\\,((\\-|\\+)?([1-9]\\d*|0)(\\.\\d+)?)){1}((\\s(((\\-|\\+)?([1-9]\\d*|0)(\\.\\d+)?)\\,((\\-|\\+)?([1-9]\\d*|0)(\\.\\d+)?)))*(\\s)?)");

程式碼思路:為了避免程式碼的複雜性,因此學習了正則表示式用來方便的判斷輸入格式的正確性,如果正確則輸出true否則false,剛開始沒對輸入點的個數判斷正確,導致一個測試點無法通過,經過改良,該正則表示式能夠很好正確的判斷出輸入格式是否正確。

public void test5(Point a,Point b,Point c,Point d,Point e) {
        if(!sibianxing(b,c,d,e)&&!sanjiaoxing(b,c,d,e)) {
            System.out.println("not a quadrilateral or triangle");
        }
        else {
            if(sibianxing(b,c,d,e)) {
                if((panduan(a,b,c)&&pan(b,a,c))||(panduan(a,c,d)&&pan(c,a,d))||(panduan(a,d,e)&&pan(d,a,e))||(panduan(a,e,b)&&pan(e,a,b))) {
                    System.out.println("on the quadrilateral");
                }
                else {
                    if(tusibian(a,b,c,d,e)) {
                        System.out.println("in the quadrilateral");
                    }
                    else
                        System.out.println("outof the quadrilateral");
                }
            }
            if(sanjiaoxing(b,c,d,e)) {
                if((panduan(a,b,c)&&pan(b,a,c))||(panduan(a,c,d)&&pan(c,a,d))||(panduan(a,d,e)&&pan(d,a,e))||(panduan(a,e,b)&&pan(e,a,b))) {
                    System.out.println("on the triangle");
                }
                else {
                    if(find(b,c)||panduan(b,c,d)) {
                        double s1,s2,s3,S;
                        double x1=jisuan(b,d);
                        s1=dd(a,b,d)*x1/2;
                        double x2=jisuan(b,e);
                        s2=dd(a,b,e)*x2/2;
                        double x3=jisuan(d,e);
                        s3=dd(a,d,e)*x3/2;
                        double xx=jisuan(d,e);
                        S=dd(b,d,e)*xx/2;
                        if(Math.abs(s1+s2+s3-S)<0.00001) {
                            System.out.println("in the triangle");
                        }
                        else {
                            System.out.println("outof the triangle");
                        }
                    }
                    if(find(b,d)||find(c,d)||panduan(c,d,e)) {
                        double s1,s2,s3,S;
                        double x1=jisuan(b,c);
                        s1=dd(a,b,c)*x1/2;
                        double x2=jisuan(b,e);
                        s2=dd(a,b,e)*x2/2;
                        double x3=jisuan(c,e);
                        s3=dd(a,c,e)*x3/2;
                        double xx=jisuan(c,e);
                        S=dd(b,c,e)*xx/2;
                        if(Math.abs(s1+s2+s3-S)<0.00001) {
                            System.out.println("in the triangle");
                        }
                        else {
                            System.out.println("outof the triangle");
                        }
                    }
                    if(find(b,e)||find(c,e)||find(d,e)||panduan(d,e,b)) {
                        double s1,s2,s3,S;
                        double x1=jisuan(b,c);
                        s1=dd(a,b,c)*x1/2;
                        double x2=jisuan(b,d);
                        s2=dd(a,b,d)*x2/2;
                        double x3=jisuan(c,d);
                        s3=dd(a,c,d)*x3/2;
                        double xx=jisuan(c,d);
                        S=dd(b,c,d)*xx/2;
                        if(Math.abs(s1+s2+s3-S)<0.00001) {
                            System.out.println("in the triangle");
                        }
                        else {
                            System.out.println("outof the triangle");
                        }
                    }
                    if(panduan(e,b,c)) {
                        double s1,s2,s3,S;
                        double x1=jisuan(c,d);
                        s1=dd(a,c,d)*x1/2;
                        double x2=jisuan(c,e);
                        s2=dd(a,c,e)*x2/2;
                        double x3=jisuan(d,e);
                        s3=dd(a,d,e)*x3/2;
                        double xx=jisuan(d,e);
                        S=dd(c,d,e)*xx/2;
                        if(Math.abs(s1+s2+s3-S)<0.00001) {
                            System.out.println("in the triangle");
                        }
                        else {
                            System.out.println("outof the triangle");
                        }
                    }
                }
            }
        }
    }

程式碼思路:該選項五使用了許多if-else語句用於判斷,先判斷是否能形成四邊形或三角形,再根據輸入點的位置和形式,分多種情況討論,判斷點在三角形或四邊形的內部或外部。因為四邊形的判斷演算法有誤,所以部分四邊形相關的測試點無法通過,其他對應測試點輸出。

優缺點:

  優點:

1.使用了正則表示式來判斷輸入格式的正確性,吸取了前幾個題目集的教訓,能夠使得程式碼變得更加清晰,降低了程式碼的複雜度。

2.對題目給的選項五要求考慮周全,涉及多種情況,防止遺漏可能的測試點,讓輸出結果精準正確。

  缺點:

1.對正則表示式的使用不是非常熟練,還需要多加練習與理解,格式判斷時使用需要注意格式不得遺漏或增加。

2.使用了許多if-else語句,雖然考慮周全能夠概括所有測試點,但是會使程式碼的可讀性降低。

實驗二題目:

  實驗二(1):

  農夫過河問題:一個農夫帶著一匹狼、一隻羊、一顆白菜要過河,河上只有一條船能夠渡河,而且農夫每次最多隻能帶一個動物或物品過河。當農夫不在的時候狼會吃羊,羊會吃白菜。

  請以程式碼為基礎,將程式程式碼補充完整,實現農夫過河遊戲功能:由使用者選擇角色過河,系統自動判斷遊戲的勝負:當出現有生物被吃掉的時候,遊戲失敗,所有角色都到了河的另一邊,遊戲成功。

  遊戲輸出示例:

  ==================Please choose operation============

    ==========1:Cross the river alone===========

    ==========2:Cross the river with wolf=========

    ==========3:Cross the river with sheep============

    ==========4:Cross the river with cabbage==========

    ==========0:Quit===============

  ===================================================

  Input the number(0~4):

  2

  Farmer has Cross  :true

  Wolf is alive  :true   Wolf has Cross  :true

  Sheep is alive :true   Sheep has Cross :false

  Cabbage is alive:false   Cabbage has Cross:false

  game over: you lose !

 度量分析:

 實驗二(2):

 農夫過河問題:將之前的程式碼進行如下改進:

(1)對farmer,wolf,sheep,cabbage進行資料封裝的改進,將屬性隱藏。

(2)增加Boat(船)類,設計船類的相應方法,並修改main方法中相關的程式碼,改進農夫帶東西過河的功能,解決之前程式碼中存在的農夫帶東西過河的判斷問題。

(3)為wolf,sheep 兩個類新增帶Stirng name引數的建構函式,當建立wolf,sheep物件時,假設輸入了name引數,程式分別輸出:

        啊嗚~~~我 *name* 狼又回來了

        咩咩,我是可愛的小羊*name*

       當wolf,sheep物件使用showStatus()方法輸出狀態時,輸出內容要帶上name的資訊,如:

    Sheep *name* is alive :true   Sheep *name* has Cross : false

 度量分析:

 主要程式碼分析:

class Wolf{
    private String name;
    private boolean hasCross=false;
    private boolean isAlive=true;
    Wolf(String name){
        this.name = name;
        System.out.println("啊嗚~~~我 *"+name+"* 狼又回來了");
    }
    Wolf() {
        
    }
    public void crossRiver() {
        if(isHasCross()==false) {
            this.setHasCross(true);
        }
        else {
            this.setHasCross(false);
        }
    }
    public void showStatus() {
        System.out.println("Wolf is alive :"+isAlive+"   Wolf has Cross :"+isHasCross());
    }
    public void showStatus(String name) {
        System.out.println("Wolf *"+name+"* is alive :"+isAlive+"   Wolf *"+name+"* has Cross :"+isHasCross());
    }
    public void eatSheep(Sheep sheep,Farmer farmer) {
        if(sheep.isHasCross()==isHasCross()&&isHasCross()!=farmer.isHasCross()) {
            sheep.setAlive(false);
        }
    }
    public boolean isHasCross() {
        return hasCross;
    }
    public void setHasCross(boolean hasCross) {
        this.hasCross = hasCross;
    }
}

程式碼思路:實驗二(1),根據題目給出的程式碼和遊戲規則,對應的完善相關區域。實驗二(2),根據實驗要求,對farmer,wolf,sheep,cabbage進行資料封裝的改進,將屬性隱藏。使用private對資料隱藏。隱藏完後,資料不能夠直接在其他類中呼叫了,需要新增返回該變數值的方法用來獲得該變數的值。建立一個船類,在類中建立一個判斷農夫與攜帶的物品是否在同一邊的方法,並將農夫與該物品過河的方法也放入其中。為wolf,sheep 兩個類新增帶Stirng name引數的建構函式,同時對建立物件的函式放入名字,對展示狀態的showstatus方法也新增帶String name引數的函式。從而完成題目要求。

優缺點:

優點:1.在對變數隱藏後,能夠很好的設計set、get方法來獲取變數,並且能夠根據題目完成對應的輸出要求。

2.設計的類簡潔明瞭,結構清晰,程式碼複雜度低,程式碼可讀性強。

3.對資料封裝的改進,將屬性隱藏,提高程式碼安全性,修復了判定攜帶物品時是否在同一邊。

缺點:1.該題使用了大量重複型別的方法,是否可用繼承與多型的形式,提高程式碼複用性。

期中考試題目集:

  7-1 點與線(類設計)(20分)

  • 設計一個類表示平面直角座標系上的點Point,私有屬性分別為橫座標x與縱座標y,資料型別均為實型數,除構造方法以及屬性的getter與setter方法外,定義一個用於顯示資訊的方法display(),用來輸出該座標點的座標資訊,格式如下:(x,y),數值保留兩位小數。為簡化題目,其中,座標點的取值範圍設定為(0,200]。若輸入有誤,系統則直接輸出Wrong Format

  • 設計一個類表示平面直角座標系上的線Line,私有屬性除了標識線段兩端的點point1、point2外,還有一個字串型別的color,用於表示該線段的顏色,同樣,除構造方法以及屬性的getter與setter方法外,定義一個用於計算該線段長度的方法getDistance(),還有一個用於顯示資訊的方法display(),用來輸出線段的相關資訊,輸出格式如下:

      ```
          The line's color is:顏色值
          The line's begin point's Coordinate is:
          (x1,y1)
          The line's end point's Coordinate is:
          (x2,y2)
          The line's length is:長度值
      ```
    
     

    其中,所有數值均保留兩位小數,建議可用String.format("%.2f", data)方法。

      設計類圖如下圖所示。
    
     

** 題目要求:在主方法中定義一條線段物件,從鍵盤輸入該線段的起點座標與終點座標以及顏色,然後呼叫該線段的display()方法進行輸出。**

  • 以下情況為無效作業
    • 無法執行
    • 設計不符合所給類圖要求
    • 未通過任何測試點測試
    • 判定為抄襲

輸入格式:

分別輸入線段的起點橫座標、縱座標、終點的橫座標、縱座標以及顏色,中間可用一個或多個空格、tab或者回車分隔。

輸出格式:

The line's color is:顏色值
The line's begin point's Coordinate is:
(x1,y1)
The line's end point's Coordinate is:
(x2,y2)
The line's length is:長度值

軟體畫的圖與所給圖有偏差,說明程式碼與題目要求的有所偏差,還需改進。

度量分析:

 該題目是根據題意和所給類圖,設計相應的類和類方法,整體難度低,只需按部就班寫下去,設計point類和Line類,Main類呼叫Point類和Line類,Line類呼叫Point類,再根據輸入、輸出樣例,使用Point類和Line類的display方法得出對應輸出,解答該題目。

主要程式碼分析:

class Line {
    private Point point1;
    private Point point2;
    private String color;
    Line() {
        
    }
    Line(Point p1,Point p2,String color) {
        setPoint1(p1);
        setPoint2(p2);
        setColor(color);
    }
    public Point getPoint1() {
        return point1;
    }
    public void setPoint1(Point point1) {
        this.point1=point1;
    }
    public Point getPoint2() {
        return point2;
    }
    public void setPoint2(Point point2) {
        this.point2=point2;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color=color;
    }
    public double getDistance() {
        return Math.sqrt(Math.pow(point1.getX()-point2.getX(), 2)+Math.pow(point1.getY()-point2.getY(), 2));
    }
    public void display() {
        System.out.println("The line's color is:"+getColor());
        System.out.println("The line's begin point's Coordinate is:");
        point1.display();
        System.out.println("The line's end point's Coordinate is:");
        point2.display();
        System.out.println("The line's length is:"+String.format("%.2f", getDistance()));
    }
}

程式碼思路:Line類能夠呼叫Point類,將兩個Point類和color放於Line類構造方法中,getDistance方法計算出兩個點的距離,display方法呼叫getcolor方法、getDistance方法以及Point1、Point2的display方法,最後Main類呼叫Line類的display方法,得出輸出樣例對應的輸出結果。

優缺點:

優點:1.很好的根據題目題意,使用String.format方法,構造出相應正確的類方法,並且能夠完成輸出樣例所給要求。

2.設計的類簡潔明瞭,結構清晰,程式碼複雜度低,程式碼可讀性強。

缺點:1.所畫類圖與題目所給類圖有所偏差,程式碼還需改進。

7-2 點線面問題重構(繼承與多型)(40分)

在“點與線(類設計)”題目基礎上,對題目的類設計進行重構,以實現繼承與多型的技術性需求。

  • 對題目中的點Point類和線Line類進行進一步抽象,定義一個兩個類的共同父類Element(抽象類),將display()方法在該方法中進行宣告(抽象方法),將Point類和Line類作為該類的子類。
  • 再定義一個Element類的子類面Plane,該類只有一個私有屬性顏色color,除了構造方法和屬性的getter、setter方法外,display()方法用於輸出面的顏色,輸出格式如下:The Plane's color is:顏色
  • 在主方法內,定義兩個Point(線段的起點和終點)物件、一個Line物件和一個Plane物件,依次從鍵盤輸入兩個Point物件的起點、終點座標和顏色值(Line物件和Plane物件顏色相同),然後定義一個Element類的引用,分別使用該引用呼叫以上四個物件的display()方法,從而實現多型特性。示例程式碼如下:
          element = p1;//起點Point
          element.display();
          
          element = p2;//終點Point
          element.display();
          
          element = line;//線段
          element.display();
          
          element = plane;//面
          element.display();
    
      類結構如下圖所示。

其中,所有數值均保留兩位小數,建議可用String.format("%.2f", data)方法。

  • 以下情況為無效作業
    • 無法執行
    • 設計不符合所給類圖要求
    • 未通過任何測試點測試
    • 判定為抄襲

輸入格式:

分別輸入線段的起點橫座標、縱座標、終點的橫座標、縱座標以及顏色,中間可用一個或多個空格、tab或者回車分隔。

輸出格式:

(x1,y1)

(x2,y2)

The line's color is:顏色值

The line's begin point's Coordinate is:

(x1,y1)

The line's end point's Coordinate is:

(x2,y2)

The line's length is:長度值

The Plane's color is:顏色值

度量分析:

 該題在前一題的基礎上新增Plane類,然後新增Element父類(抽象類),將這三個Point類、Line類、Plane類作為Element類的子類,構造Plane類的對應類圖的變數和方法,再通過Main類建立兩個point類物件、一個Line類物件、一個Plane類物件,定義一個Element類的引用,分別使用該引用呼叫以上四個物件的display()方法,輸出對應結果。

主要程式碼分析:

public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        double x1=in.nextDouble();
        double y1=in.nextDouble();
        double x2=in.nextDouble();
        double y2=in.nextDouble();
        String color=in.next();
        if(x1>200||x1<=0||y1>200||y1<=0||x2>200||x2<=0||y2>200||y2<=0){
            System.out.println("Wrong Format");
        }
        else{
            Point p1=new Point(x1,y1);
            Point p2=new Point(x2,y2);
            Line line=new Line(p1,p2,color);
            Plane plane=new Plane(color);
            Element element;
            element = p1;//起點Point
            element.display();
            
            element = p2;//終點Point
            element.display();
            
            element = line;//線段
            element.display();
            
            element = plane;//
            element.display();

            in.close();
        }
    }
}
abstract class Element {
    public abstract void display();
}

程式碼思路:通過獲取鍵盤輸入,構造相應的Point類物件、Plane類物件、Line類物件,將這些物件賦於element類物件,通過element類物件呼叫各個物件的display方法。且注意抽象類的定義和抽象方法的定義時需要使用abstract,而且抽象方法display()不能賦空,需要寫成public abstract void display();

優缺點:

優點:

1.能夠明顯簡潔直觀的呼叫每一個類物件,父類能夠使用呼叫子類物件。

2.通過子類繼承父類,增加了程式碼的複用性。

3.降低了某些方法的複雜性,避免程式碼重複,提高可重用性。

缺點:

1.破壞封裝,子類與父類之間緊密耦合,子類依賴於父類的實現,子類缺乏獨立性。
2.支援擴充套件,但是往往以增強系統結構的複雜度為代價。
3.不支援動態繼承。在執行時,子類無法選擇不同的父類。

7-3 點線面問題再重構(容器類)分數40

在“點與線(繼承與多型)”題目基礎上,對題目的類設計進行重構,增加容器類儲存點、線、面對象,並對該容器進行相應增、刪、遍歷操作。

  • 在原有類設計的基礎上,增加一個GeometryObject容器類,其屬性為ArrayList<Element>型別的物件(若不瞭解泛型,可以不使用<Element>
  • 增加該類的add()方法及remove(int index)方法,其功能分別為向容器中增加物件及刪除第index - 1(ArrayList中index>=0)個物件
  • 在主方法中,使用者迴圈輸入要進行的操作(choice∈[0,4]),其含義如下:
    • 1:向容器中增加Point物件
    • 2:向容器中增加Line物件
    • 3:向容器中增加Plane物件
    • 4:刪除容器中第index - 1個數據,若index資料非法,則無視此操作
    • 0:輸入結束
    示例程式碼如下:
       choice = input.nextInt();
        while(choice != 0) {
            switch(choice) {
            case 1://insert Point object into list 
              ...
                break;
            case 2://insert Line object into list
                ...
                break;
            case 3://insert Plane object into list
                ...
                break;
            case 4://delete index - 1 object from list
                int index = input.nextInt();
                ...
            }
            choice = input.nextInt();
        }
    
      輸入結束後,按容器中的物件順序分別呼叫每個物件的display()方法進行輸出。
    類圖如下所示:
  • 以下情況為無效作業
    • 無法執行
    • 設計不符合所給類圖要求
    • 未通過任何測試點測試
    • 判定為抄襲

輸入格式:

switch(choice) {
            case 1://insert Point object into list 
              輸入“點”物件的x,y值
                break;
            case 2://insert Line object into list
                輸入“線”物件兩個端點的x,y值
                break;
            case 3://insert Plane object into list
                輸入“面”物件的顏色值
                break;
            case 4://delete index - 1 object from list
                輸入要刪除的物件位置(從1開始)
                ...
            }
 

輸出格式:

  • Point、Line、Plane的輸出參考題目2
  • 刪除物件時,若輸入的index超出合法範圍,程式自動忽略該操作

 度量分析:

 這題根據前兩題“點與線(類設計)”和“點與線(繼承與多型)”題目基礎上,並且提供了類圖,整體難度不大。對題目的類設計進行重構,增加一個GeometryObject容器類儲存點、線、面對象,並對該容器進行相應增add方法、刪remove方法、遍歷(我使用的是for迴圈遍歷輸出)操作,然後通過Main類在while語句中迴圈使用switch語句,選擇對應選項,建立對應物件使用對應方法,輸入0結束迴圈,最後通過遍歷操作,呼叫GeometryObject類中裝入的每一個物件的display()方法。

 主要程式碼分析:

public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int choice;
        choice = input.nextInt();
        while(choice != 0) {
            switch(choice) {
            case 1://insert Point object into list 
                double x1=input.nextDouble();
                double y1=input.nextDouble();
                GeometryObject.add(new Point(x1,y1));
                break;
            case 2://insert Line object into list
                double x=input.nextDouble();
                double y=input.nextDouble();
                double x2=input.nextDouble();
                double y2=input.nextDouble();
                String color=input.next();
                GeometryObject.add(new Line(new Point(x,y),new Point(x2,y2),color));
                break;
            case 3://insert Plane object into list
                String color1=input.next();
                GeometryObject.add(new Plane(color1));
                break;
            case 4://delete index - 1 object from list
                int index = input.nextInt();
                GeometryObject.remove(index);
                break;
            }
            choice = input.nextInt();
        }
        for(int i=0;i<GeometryObject.list.size();i++) {
            GeometryObject.list.get(i).display();
        }
        input.close();
    }
}
class GeometryObject {
    static ArrayList<Element> list=new ArrayList<>();
    public GeometryObject(){
        
    }
    public static void add(Element element) {
        list.add(element);
    }
    public static void remove(int index) {
        if(list.size()>index-1) {
            list.remove(index-1);
        }
        return;
    }
    public ArrayList<Element> getList(){
         return list;
    }
}

程式碼思路:

根據題目所給題意和所給類圖,使用for語句,迴圈使用switch語句選擇,使用GeometryObject類的靜態方法完成對應操作,以0結束迴圈。建立GeometryObject容器類中的增add方法、刪除remove方法、返回連結串列getList方法,剛開始考試時建立list變數,無法根據類圖形成私有變數,加上private後,無法呼叫靜態變數,主類中通過GeometryObject類呼叫靜態方法會報錯,其他能夠與類圖一致。考試結束後,發現Main方法中應該使用getList方法獲取List變數,GeometryObject容器類所有的變數和方法除了構造方法外都應該使用靜態。然後根據輸入格式輸入,輸出相應結果。

優缺點:

  優點:1.使用switch語句,程式碼可讀性強、易於維護。

2.可以自動地調整自己的尺寸大小。在實際的程式設計中可以往容器中放置任何數量的物件,而不用擔心容器應該設定成多大。

3.使用容器類,安全性、靈活性高。

  缺點:1.switch語句的比較是從上往下,所以需要把匹配概率大的選擇因子放在前面,否則會降低效率。

2.用於匹配的選擇因子必須是整形或字元型常量。

3.容易忘記使用break來防止後面的語句使用。

採坑心得

 PTA題目集四 7-2:

 1.此方法用於判斷是否為四邊形,但是演算法效率不高,有許多情況遺漏,嘗試了多種方法,只有這種相對測試點通過的更多。剛開始本想使用對邊的交線的交點在內部還是外部來判斷,但是存在bug測試點通過的更少了。判斷是否為四邊形的演算法還有待提高有待精煉。

 2.該函式為改變資料位數(即對資料四捨五入,保留至三位小數),通過計算資料小數點後面有幾位數,如果小於3則正常輸出,否則保留三位小數四捨五入輸出,該方法要注意資料輸出位數以及是否四捨五入,剛開始我是直接用%.3f輸出,發現有bug會出現0.100等情況。所以對演算法需要更加仔細考慮、測試。

實驗二:

 該題目比較簡單,對資料進行封裝,隱藏時,要想獲取相關資料,需要設計類似set、get的方法來設定和獲取資料變數,否則後續操作中無法獲取而顯示空。

期中考試第一題:

  

 該題目比較簡單,只需要注意getDistance()方法中因為私有變數所以要getX、getY方法獲取x、y,display()方法中需要使用getcolor方法獲取color,否則到時候呼叫display()方法時,無法獲取那些變數,導致輸出有誤,無法得到正常的輸出結果,我之前沒注意,測試時就出現問題(要切記)。

期中考試第二題:

  

 1.該題目建立抽象類和建立抽象方法時,要記住抽象方法必須在抽象類中,而抽象類可以不止放抽象方法。同時,抽象方法display不能給空,需要寫成如上圖public abstract void display();的形式。

 2.要記得寫上extends,否則構成不了繼承關係,對後面的使用造成影響。

 3.此方法通過將點物件、線物件、面對象賦於Element類物件,通過父類Element呼叫對應子類的display()方法,不能直接用相應物件呼叫相應方法,否則無法完成題目所給要求。

期中考試第三題:

  

 此題目整體難度不大,只需要理解容器類的概念,remove(int index)方法剛開始我構造時,是想要判斷輸入非法時返回空,其他情況執行移除操作,但是發現實現相對困難需要找出多種情況,後來換成先找出正確的情況(list的大小大於index-1)執行刪除操作,其他情況返回空,這樣花費的時間少,且更容易。

改進建議

題目集四7-2:

1.由SourceMonitor以及PowerDesigner軟體測評結果可以得知,程式碼複雜度低,因為吸取了前面題目集的教訓,使用正則表示式,減少了許多if-else語句的使用。但是使用正則表示式需要注意格式的問題,需要做到準確無誤,此題一開始使用正則表示式時我對點的輸出有所遺漏,導致測試點無法通過,故需要多訓練使用正則表示式,熟悉它。

2.該題目還是考察的多邊形演算法問題,數個關於判斷四邊形的測試點沒有通過,判斷四邊形的方法演算法還有待改進,需要多加測試,將四邊形演算法精練,改善演算法。

實驗二:

由SourceMonitor的評測圖以及PowerDesigner軟體測評結果可知,程式碼複雜度低,因為主要是類的設計與構造,沒有什麼複雜難度,但要注意實驗的要求,要能夠完整的完成題目所給的要求,該題幾個類的方法都有很多類似之處,因此可考慮運用繼承與多型的方法來完善和改進,提高程式碼的複用性。

期中考試7-1、7-2、7-3:

由SourceMonitor的評測圖以及PowerDesigner軟體測評結果可知,程式碼複雜度不高,應該也是程式碼較簡單,沒有使用過多的程式碼。類設計方面要注意簡潔明瞭,直觀,當然也要保證類功能的齊全,在使用私有變數時get、set等方法的使用也必不可少。繼承與多型方面,要注意寫extends形成繼承關係,同時要注意使用多型,不要還是單純呼叫相應物件來呼叫相應的方法,使用多型來提高程式碼的複用性,抽象類的知識以及抽象方法使用也要多熟悉。容器類方面,要記住容器類的許多方法,有些返回值是長度有些是下標位置,要格外注意,對容器與裝入容器物件的關係以及呼叫容器內物件的方法要理解透徹。

總結

 在java這幾周的學習中,老師講了繼承與多型還有抽象類、容器類方面的知識,學習了一些java的進階知識,同時複習了前幾周學習的類與物件,類設計等的知識。在前幾周學習相對清楚的情況下,學習這些進階知識就不會那麼累,相對易於理解,只需要上課認真聽課,課後溫習寫程式碼多加練習即可。在java面向物件的學習中,應該多加練習程式碼,多提高自己的演算法能力,其實也是在打牢基礎,為以後更難的java知識做鋪墊,避免學習後面的知識時,困難重重。

這次的題目集四、實驗二和期中考試,讓我明白了許多還需要提高的地方:

1.對於演算法方面還需要下許多功夫,要多加練習,勤能補拙,多學習網上的演算法來提高自己,掌握多種演算法防止一種演算法算不全。

2.正則表示式雖然學習了許多,但掌握的不牢固,使用正則表示式時要考慮周全,多注意格式,避免出現一些小錯誤而導致輸出結果有誤。

3.對於題目給出的類圖要理解透徹,+表示public,-表示private,#表示protected,要注意類圖的多種型別箭頭的含義,能夠更好地通過給出的類圖完成相應的程式碼。

4.繼承與多型的一些知識還不夠理解,對父類與子類的關係理解不夠清晰,抽象類方法不得給空,直接加;號結束即可。容器類的許多方法還需多背,對容器類物件的呼叫需要多加理解、練習。

5.課後多查閱java知識資料,可以在CSDN、MOOC等地方查閱相關Java的方法、知識,可以聽聽java網課,鞏固自己對java的理解,並且多記住一些Java的基本函式和語法,對Java的類圖和基本語法要能夠看懂看明白,然後多寫Java程式碼練習java,提高自己。