題目集4~6的總結性Blog

Mist_123發表於2024-11-23

目錄
  • 一 、前言:
    • 總結三次題目集的知識點、題量、難度等情況
      • 知識點
      • 題目及題量、難度

        • nchu-software-oop-2024-上-4:
        • nchu-software-oop-2024-上-5:
        • nchu-software-oop-2024-上-6:
  • 二、第四次的答題判題程式分析
    • 設計與分析
      • 第四次的答題判題程式類圖以及SourceMontor的生成報表內容:
    • 踩坑心得
    • 改進建議
  • 三、第一次家居強電電路模擬程式分析
    • 設計與分析
      • 第一次家居強電電路模擬程式類圖以及SourceMontor的生成報表內容:
    • 踩坑心得
    • 改進建議
  • 四、第二次家居強電電路模擬程式分析
    • 設計與分析
      • 第二次家居強電電路模擬程式類圖以及SourceMontor的生成報表內容:
    • 踩坑心得
    • 改進建議
  • 五、總結:

一 、前言:

總結三次題目集的知識點、題量、難度等情況

知識點

第四次題目集主要考察了java語言三大特性中的多型,子類與父類的繼承關係、方法重寫,資訊處理、比較,排序輸出,類的物件建立有無引數的不同構造方法、屬性的訪問許可權等知識點,對類的設計要求提高。
第五次題目集主要考察了java中的封裝與繼承,多個類的設計,類與類之間的關係考慮,向下轉型,compare介面的使用,集合介面的例項化,迭代器,資料的查詢、排序,字串處理,正規表示式,型別轉換,類與物件、方法的使用,方法的呼叫與返回,多個類的關係與使用、連結串列或雜湊表、遍歷方法等知識點。
第六次題目集主要考察了物件導向的封裝性,類的設計等知識點。集合了前幾次的知識點於一體考察。
三次題目集都體現了物件導向的設計思想。

題目及題量、難度


nchu-software-oop-2024-上-4:

7-1 答題判題程式-4
7-2 設計一個學生類和它的一個子類——本科生類
7-3 校園角色類設計-1

共三道題,難度一般,比上一次簡單多了。第一道是之前答題判題程式的最後一次迭代,增加了兩個題型,要求使用繼承,也就是這兩種新增題型可以用之間普通的選擇題為父類而繼承,在這基礎上修改判題方法、給分方法。這一次的大作業主要是要求大家使用父類、子類,學會繼承,一些方法重寫和資料的許可權設計都還是有難度的。

nchu-software-oop-2024-上-5:

7-1 家居強電電路模擬程式-1
7-2 7-3 請閱讀程式並除錯改正程式,獲得正確答案

共三道題,難度提高了很多。這次的第一道題就是核心題目:電路程式,在這題中我們要先做好類的設計,這道題中有非常多的不同的類,每個類的功能、屬性都各不相同,增加了些許難度。後面的兩道題比較簡單,考察我們對介面、迭代器使用、修改程式的能力。

nchu-software-oop-2024-上-6:

7-1 家居強電電路模擬程式-2

就一道大作業:上次電路程式的迭代。在這次作業中,老師刪除了測試點的具體說明,寫程式碼時遇到未透過的測試點,只能自己猜測哪種情況還未考慮或者程式碼哪裡出現錯誤,給我們帶來了不少的困難。除了測試點,這次還增加了電器種類、電路種類,既考察了我們對電路電阻、電流、電壓的計算,又考驗了我們遇到問題時考慮得全面不全面,還有在類的設計時能否設計出符合題目要求的多種類,縷清類與類之間的關係。

二、第四次的答題判題程式分析

設計與分析

第四次的答題判題程式類圖以及SourceMontor的生成報表內容:

  在這次題目中我在之前設計的Topic,Answer,Test,Student,Sort,Main六個類的基礎上又新增了兩個類:Multiple類(多選題)Summary類(填空題)。這兩個類是以Topic為父類的子類,繼承Topic中的方法,在此就不分析原來的六個類了,幾乎沒有改動,著重分析新增的兩個類。

  1. Multiple類:用於表示多選題,屬性與Topic類一致,包括題號(no)、題目內容(content)和標準答案(standardAnswer)。
    新增了一個type屬性用於區分題目型別。包含了一個無參構造方法和一個有參構造方法,用於初始化題目物件。
    在Topic類中所包含的方法基礎上,重寫了answer方法,即判題方法,因為多選題有多個答案,在判題上與原來的Topic不同。
  2. Summary類:用於表示填空題,屬性與Topic類一致,包括題號(no)、題目內容(content)和標準答案(standardAnswer)。
    新增了一個type屬性用於區分題目型別。
    包含了一個無參構造方法和一個有參構造方法,用於初始化答題物件。
    與Multiple類一樣,重寫了判題方法answer,判題的結果有三種:完全一樣為true,有錯誤則為false,不完全一樣且沒有錯誤答案為partiallt correct,用到了字串比較的方法。

新增類程式碼如下:

點選檢視程式碼
class Multiple extends Topic{//多選題
	public Multiple()
    {}
    public Multiple(int no,String cotent,String standaraAnswer)
    {
        super(no,cotent,standaraAnswer);
        type=1;
    }
    public String answer(String s)//判題
    {
    	int j=0;//正確答案數量
    	int k=0;//錯誤答案數量
        //System.out.println(standaraAnswer);
        String[] s1=s.split(" ");//分隔作答
        String[] s2=standaraAnswer.split(" ");//分隔答案
        
        //先判斷兩個陣列長度是否相同
        for(int i=0;i<s1.length;i++)
        {
        	//System.out.println(s1[i]);
        	int flag=-1;
        	for(int l=0;l<s2.length;l++)
        	{
        	//System.out.println(s2[l]);
        		  if (s2[l].equals(s1[i])) {
                      flag=0;
                      j++;
                      break;
                  } 
        		  else if(!s1[i].equals(""))
                      flag=1;
                else flag=-1;
        	}
        	if(flag==1)
        		k++;
        }
         //System.out.println(k+" "+j);
            if(k!=0)
            	return "false";
            else if(k==0&&j==4)
            	return "true";
            else 
            return "partially correct";
    }
}
class Summary extends Topic{//填空題
	public Summary() {
		// TODO 自動生成的建構函式存根
	}
    public Summary(int no,String cotent,String standaraAnswer)
    {
        super(no,cotent,standaraAnswer);
        type=2;
    }
     public String answer(String s)//判題
    {
       s=s.trim();
        if(standaraAnswer.indexOf(s)==-1){
            return "false";
        }
        else{
            if(standaraAnswer.equals(s)==true){
                return "true";
            }else{
                return "partially correct";
            }
        
    }
    }
}

踩坑心得

  • 這次的大作業對輸入資訊要求不一樣,可以亂序輸入,導致對部分資訊的處理應該放在所有資訊輸入之後。比如刪除題目的資訊可以出現在題目之前,試卷可以出現在題目之前等。
  • 在寫多選題和填空題的判題方法中遇到了困難,不像之前的Topic類的判題,完全一樣就是正確,否則就是錯誤,但是新增的兩個題型考慮到答案部分正確的情況,因此判題時不僅要比較標準答案與回答的答案的長度、內容是否一致,還要考慮不一致時有沒有出現錯誤答案,在寫這兩個判題方法時學到了字串的子串的應用,非常好用,幾行程式碼就能將多種情況都實現了。
  • 之前的學生答題不會出現多張試卷,但是這次時多個學生有多張不同試卷,需要考慮輸出順序的優先順序,實現這個時要注意!

改進建議

  • 對輸入資訊處理時,注意可亂序輸入的資訊,我增加了題目變數用於儲存輸入的題目資訊,類似於題庫,在試卷中查詢題目、刪除題目的操作均放在所有題目資訊的輸入之後。
  • 用字串的子串來判斷填空題答案是否正確,在這裡要注意空字串、空格,有些空格是答案的一部分,在一開始我沒有用子串判斷,而是用了最笨的方法:一個一個字元查詢比對,這樣就導致程式碼效率不高,還會出現對一些空格判斷時的錯誤,於是我去搜尋了比對字串還有沒有什麼更好的方法,就發現了indexOf()方法。

三、第一次家居強電電路模擬程式分析

設計與分析

第一次家居強電電路模擬程式類圖以及SourceMontor的生成報表內容:



  可以看出這次的程式有非常多的類,第一次的電路程式中只考慮一條串聯電路,故電路中只有控制裝置(開關,分檔調速器,連續調速器),受控裝置(燈啊,風扇啊)。這次的類都是元件裝置,所以我先設計了一個Lead類作為所有電路元件的父類:包含了一個無參構造方法和一個有參構造方法,用於初始化物件。包括了兩個引腳(雖然沒怎麼用上)、狀態、電壓、名字、優先順序等屬性。提供了輸出方法(每個電器都需重寫,有對應不同的輸出方法)、設定電壓方法等。
我還設計了一個Array類和Build類,其中Array類包括了一個連結串列,用於儲存所以元件資訊。Build類用於建立不同元件物件。

點選檢視程式碼
class Array{
	public Array() {
		// TODO 自動生成的建構函式存根
	}
	ArrayList<Lead> arrayList=new ArrayList<Lead>();
	public Object arraylist;
	void add1(Lead l)
	{
		arrayList.add(l);
	}
class Build{
	public Build() {}
	public void bulid(String string,Array array,int x,int a) {
		switch (string) {
		case "K": {
			SW sw=new SW(x,string+a);
        	sw.VVC();
        	array.add1(sw);
        	break;
		}
		case "L":{
			Continuous_governor L=new Continuous_governor(x,string+a);
        	L.VVC();
        	array.add1(L);
        	break;
		}
		case "F":{
			Grade_governor F=new Grade_governor(x,string+a);
        	F.VVC();
        	array.add1(F);
        	break;
		}
		case "B":{
			Incandescent_light_bulb B=new Incandescent_light_bulb(x,string+a);
         	B.VVC();
         	array.add1(B);
         	break;
		}
		case "R":{
			LED L=new LED(x,string+a);
         	L.VVC();
         	array.add1(L);
         	break;
		}
		case "D":{
         	Ceiling_fan L=new Ceiling_fan(x,string+a);
         	L.VVC();
         	array.add1(L);
         	break;
		}
	}
}
	}

  1. SW類:用於表示開關,和別的類不同的有一個切換開關狀態的方法。
  2. Grade_governor類:用於表示分檔調速器,增加了一個檔位greas屬性,和別的類不同的有增加檔位、減小檔位的方法。還有根據不同檔位,設定分檔連續器輸出的電壓不同的方法。
  3. Continuous_governor類:用於表示連續調速器,也增加了一個檔位greas屬性,和別的類不同的有設定檔位的方法,根據不同檔位,設定分檔連續器輸出的電壓不同的方法。與分檔調速器不同的就是這個調速器的檔位是輸入後設定的,而分檔調速器是一檔一檔增加或減少。
  4. Light類:用於表示燈,是日光燈、白熾燈的父類。增加了亮度的屬性。增加了一個根據不同電壓設定不同亮度的方法
    Incandescent_light_bulb類和LED類均只重寫了設定亮度的方法。
  5. fan類:用於表示風扇,是吊扇的父類,增加了轉速的屬性。增加了一個根據不同電壓設定不同轉速的方法。
    Ceiling_fan類則是重寫設定電壓的方法。
  6. Main類:包含了主程式,用於輸入電路元件資訊和電路連線資訊和處理這些資訊。我在主類裡寫的一些對應不同元件不同屬性的處理方法:VVC連線方法,連線方法,開關調整方法,分檔調速器調檔方法,連續調速器調檔方法。

踩坑心得


  • 分檔調速器的調檔,寫的時候沒有考慮調小檔位時最小值為0,增加檔位時最大值為4,在我原來的程式碼中會出現檔位為-1或5、6的情況。
  • 開關預設是開著的!一開始沒有考慮這個情況導致整條電路中元件的電壓都不對。後面發現預設開著的,一定有輸入一條開關資訊使其閉合後電路中才有電壓。
      

改進建議

  • 將開關的狀態預設設為0
  • 修改分檔調速器中增加或減小檔位的程式碼,對是否不可增加或減小的情況進行判斷。
修改前程式碼
class Grade_governor extends Lead{//分檔調速器
	int gears=0;//檔位
	public Grade_governor() {}
	public Grade_governor(int lead1,String name) {
		super(lead1,name);
		k=2;
	}
	public void U() {
		gears--;
		U0();
	}
	public void Z() {
		gears++;
		U0();
	}
	public void U0() {
		u=220;
		if(gears==0)
			u=0;
		else if(gears==1)
			u=u*0.3;
		else if(gears==2)
			u=u*0.6;
		else if(gears==3)
			u=u*0.9;
		else if(gears==4)
			u=u;
	}
	public void L(double u) {
		if(u==0)
			lead2=0;
	}
	public void print() {
		System.out.println("@"+name+":"+gears);
	}
}
修改部分方法
public void U() {
        if(gears!=0)
		gears--;
		U0();
	}
	public void Z() {
        if(gears!=3)
		gears++;
		U0();
	}

四、第二次家居強電電路模擬程式分析

設計與分析

第二次家居強電電路模擬程式類圖以及SourceMontor的生成報表內容:

  這一次的迭代中增加了一種風扇(落地扇Stand_fan類)和並聯電路,並聯電路是由串聯電路組成的。所以我寫了一個電路類:Circuit類(也繼承Lead類,也是電路元件的一種)。其中包含了電路中電路元件數量,計算電流、電壓、電阻的方法。然後設計了Series類(串聯電路)和Multiple類(並聯電路),這兩個類都繼承Circuit類,結合物理知識我們知道這兩種電路有不同的計算電阻、電壓方法。

  1. Series類:用於表示串聯電路,包括電路元件數量(num)、各元件名字(s[],根據名字來查詢arraylist的中電路元件)、狀態(x)。包含了一個無參構造方法和一個有參構造方法,用於初始化串聯電路物件。
    提供了:
    add方法:用於增加該電路中的電路元件。
    R方法:用於計算該條電路的電阻。串聯電路的電阻計算就是將各元件的電阻相加即可。
    jude方法:用於判斷該電路狀態,主要是看電路中有無開關,並且根據開關狀態來改變電路狀態。
    working方法:用於通路,使各元件工作。
  2. Multiple類:用於表示並聯電路,包括電路元件數量(num)、各元件名字(s[],根據名字來查詢arraylist的中電路元件)、狀態(x)。包含了一個無參構造方法和一個有參構造方法,用於初始化並聯電路物件。
    提供了:
    add方法:用於增加該電路中的電路元件。
    R方法:用於計算該條電路的電阻。並聯電路的電阻計算複雜一點,總電阻的倒數等於各電阻的倒數之和。
    jude方法:用於判斷該電路狀態,主要是看並聯中的串聯電路的狀態,呼叫串聯電路的jude方法。
    working方法:用於通路,使各元件工作。

踩坑心得

這次的大作業老師把測試點的說明給關了,給我們增加了很大難度啊,只能幹猜,一點點試,改程式碼的過程中經常出現這個過了那個又沒過了。

  • 電阻的計算中就有很多坑!串聯電路中還好,都是直接相加,但是!並聯電路中倒數加來加去,就需要注意!首先要考慮並聯電路中的串聯電路是否連線到電路中,如果其中有一條電路狀態為開,計算電阻時不加進去,如果所有電路狀態為開,則該並聯電路狀態為開,總電路狀態也會為開。還有要考慮元件電阻為0的情況,這時編譯器可能不會報錯但是真正執行的時候會導致計算錯誤或者空輸出。不僅要考慮元件電阻為0,也要考慮最後整個並聯電路為0、並聯電路中有一條電阻為0的情況(雖然這次電路不考慮短路),但是還是要注意。
  • 注意兩個調速器,設定電壓的時候要先看調速器輸出電壓為多少,連線電路時的電壓就為多少。連續調速器預設為0,輸出電壓為0,這也是一個需要注意的細節。
  • 精度問題啊,和同學交流之後知道有一個測試的竟然是風扇的的轉速輸出中199和200的差別。資料在多次計算中誤差越來越大。

改進建議

  • 每一條電路中的電路計算前先對整條電路進行狀態判斷,再進行電阻的計算。並聯電路計算中記得考慮電阻為0時不能作為分母計算。
點選檢視程式碼
public void R(Series[] series,int a) {//並聯電路計算電阻
		jude(series, a);//判斷電路狀態
		if(this.x==0)
			R=0;
		else {
			double r=0;
		for(int i=0;i<a;i++)
		{
			for(int j=0;j<num;j++) {
			if(series[i].name.equals(s[j])&&series[i].x==1)
			{
				if (series[i].R!=0) 
			r+=1.0/series[i].R;
				else {
					r=0;break;
				}
			}
			}
		}
		if(r!=0)
		this.R=1.0/r;
		else {
			this.R=0;
		}
		}
	}
  • 連線電路時先找找電路中是否有調速器,有的話根據調速器的電壓再設定整條電路的電壓。

五、總結:

  在這三次大作業中寫了兩種程式,之前的試卷程式終於結束了,感覺自己寫的很不好,雖然都拿到了滿分,但是每次寫新的迭代的時候都大改特改,結構寫的很不好,看那個圈複雜度也很高,很無奈。
  這幾次的大作業為了降低難度都沒有考慮異常輸入資訊的處理,但是我傻傻的還是稍微考慮了一下,有點耽誤時間。感覺自己寫程式碼中經常會忽略一些小細節,比如電路中電阻為0的情況。
  上一次的三次大作業時嚴格的三週,但是這次時間跨度有點大,老師也提前把題面發出讓我們好好設計設計類,整理思路。給足時間思考,寫大作業時就有個大致方向,沒有那麼迷茫了。
  我覺得在我完成的這三次大作業中仍然有很多可以改進的地方:資料結構可以更好,下次嘗試用下HashMap,提高查詢速度、改善插入刪除操作;依然沒有很好的實現函式單一職責,但和上一次有點長進,學會了把功能相同類似的程式碼合併成一個函式,記得之前的程式碼主類裡只有一個主函式,這幾次我都將一些功能單拎出來成為一個函式,雖然有些函式的功能比還是很複雜;封裝性不夠,寫的時候有些急,想到什麼寫什麼,想用那個資料就直接用了,沒有考慮資料的私有化,就直接呼叫,導致程式碼的安全性、靈活性都不高。
  大概還有兩次大作業就結束了這學期的java學期,學習java這門語言主要是培養我們物件導向的思想,在一次次的大作業中遇到越來越多的類的設計,錯綜複雜的類的關係讓人頭疼,但也學到了很多,最後希望剩下的幾次大作業能做到更好,保證拿分的同時提高自己程式碼結構的靈活性,程式碼的安全性、靈活性。

相關文章