2019 OO第一單元總結(表達式求導)

来源:https://www.cnblogs.com/yifan-liu/archive/2019/03/27/10606851.html
-Advertisement-
Play Games

一. 基於度量的程式結構分析 1. 第一次作業 這次作業是我上手的第一個java程式,使用了4個類來實現功能。多項式採用兩個arraylist來存,繫數和冪指數一一對應。 四個類分別為 Poly類,代表表達式; PolyDiff類,代表求導運算; PolyParse類,封裝了格式檢查,encodin ...


一. 基於度量的程式結構分析

1. 第一次作業

  這次作業是我上手的第一個java程式,使用了4個類來實現功能。多項式採用兩個arraylist來存,繫數和冪指數一一對應。

1 private ArrayList<BigInteger> coefs;
2 private ArrayList<BigInteger> degrees;

  四個類分別為

  • Poly類,代表表達式;
  • PolyDiff類,代表求導運算;
  • PolyParse類,封裝了格式檢查,encoding(輸入的多項式轉為內部存儲形式),優化,decoing(內部存儲形式轉為輸出的多項式)方法;
  • PolyDiffTest類,入口類

  整個程式既有面向對象的味道(封裝),但不那麼純,也有面向過程的寫法。

類圖如下:

類複雜度分析如下:

       

優缺點分析:  

  這裡PolyParse類的代碼尤其多,在整個設計中,PolyParse類是主類,完成了大多數功能,其他類是輔助類。這樣的寫法犯了面向對象的一個大忌:類失衡。究其原因,還是受到了面向過程思想的影響。其次可以直接用Hashmap而不是arraylist來存表達式。

  對於第二次作業而言,本次作業的擴展性還行,給出了整個求導的框架。


 

 

2. 第二次作業

  本次作業最重要的變化是加入了三角函數。為了使用上次作業的架構,我只改變了表達式的存儲形式。對於求導,採用的方式還是和上次作業一樣,直接帶公式。關鍵是項的表示形式。

  以 x, sin(x), cos(x) 做為基函數,對於任何項 kxasin(x)bcos(x)都可以表示為 (k,(a,b,c))(k,(a,b,c)),

  採用複合函數求導公式 (uvw)' = (uvw)=uvw+uvw+uvw′ 得到的結果為3個項,具體形式可以拿公式直接得出來。

類圖如下:

類複雜度分析如下:

    

優缺點分析:  

  這裡優化的類裡面的代碼尤其多,為了保證每個方法的行數小於限制行數,只能強行將優化函數拆成3個不同功能的優化,但裡面有很多冗餘的代碼。

  對於第三次作業而言,本次作業不具任何的擴展性,這種求導的框架走到了盡頭。


 

 

3. 第三次作業

  本次作業加入了嵌套因數和表達式因數,由於前兩次作業不能擴展以及之前寫過編譯器的經驗,這一次我是推倒重來,從頭開始寫了小型編譯器。

  求導過程可看作是一個翻譯過程:源語言:原表達式,目標語言:求導後的表達式。指導書上對於item的要求看起來複雜,但拆成一個個小單元後,很容易就能寫出item的文法,之後採用遞歸下降分析法,一次掃描,同時完成了格式檢查和求導的工作。

  我d得這次作業最精彩的是我的求導都是形式求導,實質是字元串的拼接

  比如a=b*c 有了b和c本身以及b和c求導後的表達式b',c'的string形式,套公式(字元串拼接)就可以得到c'=b'c+bc'的string形式。整個過程非常簡單。不論是乘法,加法還是嵌套,都可以用這種方式解決。

類圖如下:

類複雜度分析如下:

          

優缺點分析:

  採用了編譯器的經典架構:Expr,Item,Factor,Lexer,Symbol,Pow,Sin,Cos類的劃分明確,職責清晰。類複雜度分析圖中標紅的地方是由於使用了大量的if,else或者switch,但這個也必須用,不知道有沒有更好的對於if,else的改寫方法。

  還是只用了封裝,繼承,多態,介面一個都沒用上。註意之後的重構部分會給出一些修改方法。


 

 

二. bug分析

第一次作業: 

  較為簡單,暫無bug發現

第二次作業:

  這次作業的bug出在了優化部分,可謂是畫蛇添足。

  測試用例:3*x + sin(x)^5*cos(x) - sin (x)^3*cos(x) - sin(x)*cos(x)^5 + sin(x)*cos(x)^3

  錯誤輸出:7*sin(x)^2*cos(x)^2-4+7*cos(x)^2  

  特征:向map中添加元素的時候,沒有先調用get()來得到原來的key之後再累加上去,而是直接調用put()方法覆蓋了原來的key。導致程式中如果有一個以上sinx^2+cosx^2=1或1-sinx^2=cosx^2或1-cosx^2=sinx^2的合併時出現錯誤。

  問題所在的類和方法:Optimization類的opt1,optimization1,optimization2方法。

  bug位置與設計結構之間的相關性:優化類的結構一開始每個方法寫的很長,超出了最大行數的限制,之後強行拆成了幾個方法,導致方法的功能有些混亂,在測試時沒有找到bug。

  分類樹角度分析程式在設計上的問題:分類樹是一種使用樹狀結構來構造測試用例的方法,避免了測試用例的冗餘。我在本次作業中構建的測試用例只針對了正確性,對於能夠優化的用例,我只構造了幾個,沒有完全覆蓋優化的函數。

第三次作業:

  暫無bug發現,為了防止錯誤出現,沒有做過多優化。


 

 

三. 測試方法

  雖然我們沒有互測,但自動測試可以顯著提高測試效率,很有必要實現對拍程式。

1. 構建測試用例

  對於第三次作業,情況較為複雜,採用隨機生成大量用例的方法易生成大量類似測試用例,不能保證全覆蓋。我依照指導書精心設計了30多個用例,保證了測試的全覆蓋。

2. 測試方法

  稍微修改java程式的Main方法,使其從文件讀表達式,將結果輸出到文件。使用python的sympy庫編寫對拍程式,符號求導,代入隨機數運算後比對,實現了正確格式用例的測試。對於Wrong Format的測試,直接看java程式是否輸出WF。


 

 

四. Applying Creational Pattern

  第三次作業依舊沒有使用繼承和介面,但每個類的形式都是一樣的。

 1 private String fun = "";
 2 private String diffFun = "";
 3 
 4 String getFun() {
 5     return fun;
 6 }
 7 
 8 String getDiff() {
 9     return diffFun;
10 }
11 
12 void analyse() {
13     ......  
14 }

  重構:

  新建一個父類對象Expression包含fun和diffFun變數成員,getFun()和getDiff()函數成員。由於每個子類的analyse()行為不一樣,無法使用父類的getFun()和getDiff()完成功能,因此直接將analyse定義為一個介面。每一個子類需要繼承父類Expression並且實現介面analyse。

  我的設計思路中也體現出Factory Pattern的思想。因為語法分析的結果實質是構建了一個語法樹,每一個父節點都會創建兩個子節點,並且調用子節點的getFun()和getDiff()函數,整個過程是一個遞歸過程,最終從樹的根節點上拿到結果。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 深層理解-棧平衡原理-底層是如何實現棧平衡的? 在iOS、android操作系統中,經常會遇到入棧出棧的操作。 那麼現在操作系統已經不需要我們去關心堆棧的操作。 比如:iOS中的ARC模式,android中的JVM都會幫我們自動釋放記憶體,自動保持堆棧平衡。但是對於開發者來說,還是很有必要掌握堆棧平衡 ...
  • 對於一個的坐擁1.4億多用戶,平均日活躍用戶量超過 3400 萬,人均日訪問時長 1 小時,月累計頁面訪問量達到 230 億的大廠來說(數據截止2018年 3 月),知乎的AI都到底應用在了哪些領域,這中間應用到了哪些技術和模型,又產生了哪些作用?今日第1期數智方法論將從內容生產、內容消費與分發、內... ...
  • 那個時候初入java這個大家庭,學習的方向很亂。畢業後,在公司磨練了一年,總想著是該交一份答卷了,可能成績不會很好,但求及格!那麼考試題目呢,我計劃搭建一個橫向可擴展的項目,可以在平臺自擴展各種子項目,包括 後臺許可權控制,日誌分析,秒殺,微信小程式,愛代客(www.idaike.com)項目等等,所 ...
  • OO第一單元作業總結 在第一單元作業中,我們只做了一件事情:求導,對多項式求導,對帶三角函數的表達式求導,對有括弧嵌套的表達式求導。作業難度依次遞增,讓我們熟悉面向對象編程方法,開始從面向過程向面向對象轉變。本文中,我將介紹我個人每一次作業的做法,以及三次作業的分析,互測時策略。 第一次作業 第一次 ...
  • 第一次OO博客作業 前言 面向對象課程已經經過了4周的時間。前三次作業全部是關於多項式求導的相關內容,內容由易到難,同時我也開始逐漸深入感受學習面向對象的各項特征,逐漸將自己的編程風格從C向真正的面向對象語言轉換。同時我還接觸了DEBUG和互測屋這樣嶄新的學習方式,在閱讀別人代碼的過程中不斷增強自己 ...
  • 一、由於項目需要進行手機看板展示設計及開發展示效果圖如下: 上圖為概況(點擊相應模塊進入詳情頁面) 上圖為運營統計(一些統計類圖標狀圖折線圖等......) 車輛分佈狀況(展示在地圖上分佈) 上圖為點擊一輛車的軌跡和運行情況 此產品唯一亮點在於完全可以把利用HTML5和echarts開發大數據大屏展 ...
  • 本文是BUAA OO課程Unit1在課程講授、三次作業完成、自測和互測時發現的問題,以及傾聽別人的思路分享所引起個人的一些思考的總結性博客。本文第二部分介紹三次作業的設計思路,主要以類圖的形式展現,並有簡單的優劣分析;第三部分為程式代碼複雜度的分析(二、三兩部分為基於度量的對自己程式結構的分析);第... ...
  • 一、前言 經過一個月來的學習,我從對面向對象一無所知到逐漸入門,圍繞著“多項式求導”,對面向對象的特性進行了探索。 我對面向對象印象最深的兩句話就是“萬物皆對象”和“高內聚、低耦合”,這三次作業也是儘量貫徹了這兩句話。 我們的作業從第一次的僅含冪函數的求導,到第二次包含正餘弦函數,再到最後函數可以嵌 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...