1. 程式人生 > 其它 >BLOG-2 對7-10周的學習總結

BLOG-2 對7-10周的學習總結

面向物件程式設計---七到十週綜合性學習

引言:過去幾周的Java的學習經歷了PTA大作業四,期中考試,還有兩次實驗。對遇見的題目和知識點進行整理和分析。

PTA大作業四

前言:這次的大作業共三道題。第一題是對正則表示式的考察,第二題考察四邊形相關知識,第三題設計一個銀行服務類。

對於正則表示式的學習會優化程式碼的結構,減少選擇和迴圈對格式的判斷。只需要規定正確的表達就可以規範化格式問題。

第二題則是本次作業的難點,要求用計算機語言來實現幾何圖形的判斷,不僅是對程式設計能力的考察,更要求較高的數學能力和空間想象能力。寫這道題可以充分體現出程式設計的特色,需要與數學縝密的結合。用計算機語言來嚴謹的轉化數學語言,這可以有效的鍛鍊我們面對複雜需求下的程式設計實現。這道題對於初學者算是一道難題,不僅要求對常用的數學方法的程式碼表示,如向量叉乘,射線法,兩直線相交求交點,判斷凹凸多邊形.......

第三道題則是根據類圖設計出一個類,要求實現相關的功能,需要把握類與類之間的關係和其中的具體細節。

題目集得分:96     題目集用時:十小時以上。 題目難度:難(是我寫過最難的題目了,以後還會更難)

各題目 設計與分析 踩坑心得 改進意見 核心程式碼分析:

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

設計與分析:

 這道題的程式碼量達到了五百行。這個題目有五分分支,每個分支難度遞增又彼此不同。分支和程式碼量的增加直接導致程式碼的質量下降。

這是由於在做題目時只考慮如何實現程式碼的功能,為了寫程式碼而去寫程式碼,而沒有考慮到程式碼的質量。這道題的難處之一在於輸入檢測。

我推翻了前幾次的格式判斷函式,用正則表示式的思想,不去管有多少種錯誤,而只需要通過一定的分支判斷出正確的格式,遮蔽掉錯誤的格式

這次的格式控制不僅程式碼量大大下降,而且格式的控制更加的簡便,而且這樣的程式碼讀起來會更加的容易理解。

踩坑心得:

這個題出題人為了避免四個點構成四個點的情況過多,規定輸入的四個點兩兩相鄰,避免了構成四邊形情況過多,但是產生了新的問題。


比如判斷是否構成四邊形。

按照正常來說,是需要輸入的點不是三點(四點)共線,就一定能構成四邊形。

然而如果按照題目的輸入要求,就不能判斷所有的三點共線情況 。而是按照輸入要求只能選擇其中的一個問題,才可達到題目的要求。

而我一開始設計了所有的情況,反而是畫蛇添足了。

這題所有的坑都來自非法輸入(以下是我對於輸入非法的一些樣例)

1:+-2,001 3,1

2:   02.,3 1,2,3

3:  1+2,-0 1,2 (末尾有空格)

4:1, 1,,2 

這題我被反覆折磨,其實就是做重複的事情,由於沒有提示測試樣例的點,那我只能一步一步地去嘗試。

在經過大量輸入之後,我總結了以上的輸入非法並對程式碼進行改進,直到通過所有的測試點。其中的難受真的時不想體驗第二遍。

改進建議:

1、由圖可知,該題的圈複雜度為73。這裡有點可惜,如果小於10程式碼質量就會很好。改進可以減少迴圈的使用。

2、這題可以將獲取字串變成一個字元陣列。此題可以將split方法改進,提高程式的執行效率

核心程式碼分析:

① 格式控制程式碼

static int is_format(int m,String str)
    {    
        str = str.trim();
        String []s =str.split("[ ,]");
                int count=0 ,count1=1,sum=0;
                    loop:for(int i=0;i<s.length;i++) {
                        if(s[i].length()==0){
                            return 0;
                        }
                        for(int j=0;j<s[i].length();j++) {
                            sum=0;
                            char ch = s[i].charAt(j);
                            if(j+1==s[i].length()) {
                                if(ch=='+'||ch=='-'||ch=='.')
                                    return 0;
                                if(ch>='0'&&ch<='9'&&i+1==s.length) 
                                    break loop;
                                else if(i+1!=s.length)
                                    continue;
                                else return 0;
                            }
                            char ch1 = s[i].charAt(j+1);
                            if(ch=='0'&&j==0){
                                if(ch1>='0'&&ch<='9')
                                    return 0;
                            }
                            if(ch=='+'||ch=='-') {
                                if(j==0&&(ch1>='0'&&ch1<='9'))
                                        continue;
                                else return 0;
                            }
                            else if(ch=='.'||ch1=='.')
                            {   sum++;
                                if(((ch1<'0'||ch1>'9')&&ch=='.')||sum>2||((ch<'0'||ch>'9')&&ch1=='.'))
                                    return 0;
                                else
                                    continue;
                            }
                             
                            else if(ch>='0'&&ch<='9')
                                continue;
                            return 0;
                        }
                    }
                if(s.length==0){
                    return 0;
                }
                if(s.length!=m) {
                    return -1;
                }
                if(s.length==m){
                    return 1;
                }
     return 0;
        }

②判斷四個點是否構成三角形

 static boolean IsSJX(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4) {
        double a = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        double b = Math.sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
        double c = Math.sqrt((x3-x4)*(x3-x4)+(y3-y4)*(y3-y4));
        double d = Math.sqrt((x4-x1)*(x4-x1)+(y4-y1)*(y4-y1));
            if(k(x1,y1,x2,y2)!=-100&&k(x2,y2,x3,y3)!=-100&&k(x3,y3,x4,y4)!=-100&&k(x4,y4,x1,y1)!=-100) {//四個點構成三角形
                       if((y2-y1)*(x3-x2)==(y3-y2)*(x2-x1)){ //點1,2,3共線
                          if(on(x2,y2,x1,y1,x3,y3)) //3 2 1  為什麼是||而不是&&?
                           // if(a+b+c>d&&c+d>a+b&&a+b+d>c)
                                return true;
                    }
                if((y3-y2)*(x4-x3)==(y4-y3)*(x3-x2)) {  //2,3,4共線
                    if(on(x3,y3,x2,y2,x4,y4))
                        if(b+c+a>d&&b+c+d>a&&a+d>b+c)
                            return true;
                }
                if((y4-y1)*(x1-x2)==(y1-y2)*(x4-x1)) //4 1 2
                    if(on(x1,y1,x4,y4,x2,y2))
                       return true;
               if((y4-y1)*(x1-x3)==(y1-y3)*(x4-x1)) //1 4 3
                   if(on(x4,y4,x1,y1,x3,y3))
                        return true;
               // return true;
        }
            if(k(x1,y1,x2,y2)==-100||k(x2,y2,x3,y3)==-100||k(x3,y3,x4,y4)==-100||k(x4,y4,x1,y1)==-100)
            {
                if((k(x1,y1,x2,y2)==-100&&k(x2,y2,x3,y3)==-100)||(k(x2,y2,x3,y3)==-100&&k(x3,y3,x4,y4)==-100)||(k(x3,y3,x4,y4)==-100&&k(x4,y4,x1,y1)==-100)||(k(x4,y4,x1,y1)==-100&&k(x1,y1,x2,y2)==-100))
                    return false;
                else if(a+b+c>d&&a+b+d>c&&a+c+d>b&&b+c+d>a)
                    return true;
            }
            return false;
    }

期中考試

前言:期中考試時間比較緊張,只有兩個小時,題目也是三個題目。但是這三個題目作為考試設計的非常的巧妙,題目承上啟下,寫起來重複的內容越來越少,而考察了最近學習的內容。

主要考察了繼承,多型,介面,容器類,ArrayList ,set和get方法,泛類。

各題目 設計與分析 踩坑心得 改進意見 核心程式碼分析:

題目:7-1 點與線(類設計)

設計與分析:

 踩坑心得:

這道題倒不是很難,不過需要理解類圖中類之間的關係,才可以很好的解決這樣的問題

程式碼的有些語句判斷過長,可以將其拆分,增強觀感

改進意見:

暫無。

核心程式碼分析:

這題是對點與線的型別設計。很好的闡述了類之間的設計

import java.util.Scanner;

public class Main {
    
}
class Point{
    private double x;
    private double y;
    public Point() {
        
    }
    public Point(double x,double y) {
        this.x = x;
        this.y =y;
    }
    public double getX() {
        return x;
    }
    public double getY(){
        return y;
    }
    public void setX(double x) {
        this.x = x;
    }
    public void setY(double y) {
        this.y = y;
    }
    public void display() {
        System.out.println("("+String.format("%.2f", getX())+","+String.format("%.2f", getY())+")");
    }
}
class Line {
    private String color;
    private Point Point1,Point2 = new Point();
    Line(){
        
    }
    Line(Point Point1,Point Point2,String color){
        this.Point1 = Point1;
        this.Point2 = Point2;
        this.color = color;
    }
    Point getPoint1() {
        return Point1;
    }
    Point getPoint2() {
        return Point2;
    }
    void setPoint1(Point Point1) {
        this.Point1 = Point1;
    }
    void setPoint2(Point Point2) {
        this.Point2 = Point2;
    }
    String getcolor(){
        return color;
    }
    void setcolor(String color) {
        this.color = color;
    }
    String getDistance() {
        Double data = Math.sqrt((Point1.getX()-Point2.getX())*(Point1.getX()-Point2.getX())+(Point1.getY()-Point2.getY())*(Point1.getY()-Point2.getY()));
        return String.format("%.2f", data);
    }
    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:"+getDistance());
    }    
}

這是第二題的類圖

 核心程式碼分析:

這道題附上運用多型的系列程式碼進行說明

public static void main(String []arge) {
         Scanner input = new Scanner(System.in);
         Double x1,y1,x2,y2;
         String color;
         x1 = input.nextDouble();
         y1 = input.nextDouble();
         x2 = input.nextDouble();
         y2 = input.nextDouble();
         color = input.next();
         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 ;
         if((x1<=0||x1>200)||(x2<=0||x2>200)||(y1<=0||y1>200)||(y2<=0||y2>200))
             System.out.println("Wrong Format");
         else 
         {
              element = p1;//起點Point
              element.display();
              
              element = p2;//終點Point
              element.display();
              
              element = line;//線段
              element.display();
              
              element = plane;//
              element.display();

         }
     }

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

類圖如下

 這道題主要是書寫一個容器類,用到ArrayList的add和delete方法做到增加和減少。

這個需要熟練的運用ArrayLIst的方法,對於Java課程的學習上課聽講有很好的檢驗效果。

而這道題的容器類只要理解好這個類圖的類與類之間的關係,就很容易做出來了。

踩坑心得:

 這就是我對ArrayList不熟悉導致的 我在刪除的時候書寫的程式碼時list.remove(index);

對比上圖 我忘記了應該刪除的是index-1而不是index導致這道題目的錯誤

這就很好的說明了我對Java的ArrayList不夠熟悉,對於下標引用的不夠熟悉,這說明我們在學習的過程中需要注意細節,差之毫釐,謬以千里。

在這裡也給我自己一個警示,上課需要非常的專心。

改進意見:

1、如複雜度分析圖所示,本題的圈複雜度為33,超過了程式碼的一般範圍,這就意味這該程式碼的可讀性非常的差,而對與前文提到的方法都可有效減少圈複雜度。

2、本題的程式碼有兩百多行,程式碼的簡化就顯得尤為重要,應該適當的合適程式碼的邏輯,讓程式碼模組化。

3、如果能夠將程式碼的邏輯顛倒一下,程式將更加的合理。

核心程式碼如下:

class Plane extends Element{
private String color;
public void display(){
    System.out.println("The Plane's color is:"+getColor());
    }
Plane(){
    
}
Plane(String color){
    this.color = color    ;
}
String getColor() {
    return color;
}
void setColor(String color) {
    this.color = color;
}
}
 class GeometryObject {
    ArrayList<Element> list =new ArrayList<Element>();
    GeometryObject(){
        
    }
    public void add(Element element) {
        list.add(element);
    }
    public void remove(int index) {
        if(index<list.size())
            list.remove(index-1);
    }
    public void getlist() {
        for( Element element : list)
               element.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開始)
...
}

學習心得:

1、讓我對自己的水平有了一定的認知,提醒我今後的學習還有很多改進的地方,領悟自上而下逐步細化的程式設計思想更加的透徹

2、深刻了解了關於Java程式結構和程式碼書寫的規範,以及要遵守的程式碼書寫規範,拔高了我對程式設計的眼界和深度,學習了很多程式設計時使用的技巧和方法

3、積累了一些debug的經驗,深刻認識到了除錯的重要性,學會了除錯的基本技巧,如何設定斷點,單步進入,跟蹤引數,以及更改程式碼的邏輯順序,排除邏輯錯誤,對提高程式碼的質量大有改善。

4、學會了對於一些類的使用,瞭解瞭如何使用例項方法,抽象方法,和包括ArrayList的使用方法,這對於今後的學習有很大的提示空間。

特別鳴謝出題目的老師和幫助我修改程式碼的同學們,讓我有了提高自己的機會