增近四倍 2015年Q1中國純電動車銷量達1.54萬輛

近日,中國汽車工業協會發佈最新統計資料顯示,今年第一季,中國汽車銷售達615.3萬輛,與去年同期相比增長3.9%,但相較去年同期9.2%的增幅,下滑明顯。此外新能源汽車產銷分別為2.73萬輛和2.66萬輛,與去年同期相比分別增長2.9倍和2.8倍。   其中,純電動車型銷售1.54萬輛,與去年同其相比增長3.7倍;插電式混合動力車型銷售1.12萬輛,與去年同期相比增長2.1倍。與新能源汽車相比,傳統車型銷量增幅卻明顯回落。根據資料,一季度乘用車共銷售530.51萬輛,與去年同其相比增長8.95%,增幅比去年同期回落1.14個百分點。在乘用車四類車型中,轎車銷量與去年同期相比下滑0.4%。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

歐洲純電動車市場熱絡 銷量同比勁增 73%

據《歐洲汽車新聞》報導,去年歐洲市場純電動車的銷量超越插電式混合電動車,不過今年由於車企將推出更多插電式混合車型,因此其銷量有可能超越純電動車。    歐洲汽車製造商協會 ACEA 數據顯示,2014 年在歐盟及自由貿易聯盟國家(EFTA)市場中,純電動車銷量同比勁增 73% 至 58,244 輛,插電式混合電動車及增程式電動車的銷量同比攀升 26% 至 39,547 輛,銷量最高的電動車為日產聆風,而該地區最暢銷的插電式混動車則為三菱歐藍德 PHEV。    汽車諮詢公司 IHS 預計到 2020 年,插混車的全球累計產量將達到 135 萬輛,且在 2020 年至 2025 年間將進一步翻倍至 270 萬輛。而純電動車 2020 年的銷量將在 100 萬輛以下。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

電動車電池與太陽能成本下降飛快,再生能源主宰的日子不遠了?

  電動車電池的成本下降速度超乎預期,甚至低於國際能源署(IEA)原本預估的 2020 年成本數值,且不少研究也指出,太陽能在 2020 年代將某些地區成為最便宜的能源選項,彭博新聞認為,便宜的電池與太陽能發電兩者相輔相成的結果,將加速再生能源主宰能源市場的趨勢。   國際能源署在 2013 年時,原本預估 2020 年電動車電池價格將會下降至每度電 300 美元,不過,由斯德哥爾摩環境機構最近登上《自然氣候變化(Nature Climate Change)》期刊的研究中指出,全球電動車電池價格已從 2007 年的每千瓦小時 1,000 美元,下降至 2014 年的每千瓦小時 410 美元,平均每年成本下滑 14%,且特斯拉(Tesla)及 Nissan 等電動車製造商領頭羊的價格也年減約 8%,來到 2014 年的每千瓦小時 300美元,提早 6 年達到國際能源署預定目標。   但這所謂的每千瓦小時 300 美元,除了顯示電動車電池成本下降速度超乎預期外,是否還意味著電動車躍起的時代即將來臨呢?全球顧問公司麥肯錫(Mckinsey & Company)在 2011 年曾做了一張圖表,顯示不同的油價與電池價格情況下,純電動車、插電式混合電動車、油電混合車及一般汽車何者較具競爭力,灰色區塊的部分則是 2011 年的價格區間。從下圖圖表中可以看出,當電動車電池價格位於每千瓦小時約 300 美元左右時,就是電動車競爭力逐漸起飛的時刻。    
 

  (Source:)     雖然在過去一年中,油價已下跌至每加侖 2 美元,但若電池價格也跟著不斷下跌,圖表中的灰色矩形就會繼續向左移動。該研究作者認為,若按照特斯拉執行長 Elon Musk 所言,特斯拉正在興建的超級電池工廠真能大舉降低電池組成本 30%,且天然氣價格若反彈回 3 美元區間,將可能使電動車成功在大多數地區取代一般汽車的主宰地位。   此外,根據聯合國環境署(UNEP)於 3 月 31 公布的數據指出,2014 年全球對於再生能源投資額達 2,700 億美元,而新增的再生能源裝置容量,也超過往年的成長數字,來到歷史新高的 103 GW。   即便如此,但 2014 年全球再生能源發電總量僅占 9.1%,較 2013 年的 8.5% 成長 0.6 個百分點,雖然成長速度相當緩慢,且若等到再生能源發電量占全球發電量一半的份額,得等到 2080 年才可望實現。不過,太陽能發電成本下降速度增快,加上不少研究都預估太陽能最快將在 2020 年代就能成為最便宜的能源類型,或許照這樣看來,不用等到 60 年後,就能預見再生能源主宰能源市場的世界了。   便宜的電池與太陽能發電兩者可說是相輔相成,彭博新聞認為,電動車電池價格下跌能將汽車從傳統的汽油切換到電網連結,雖然目前大多數的電網仍然由燃煤發電驅動,但若太陽能發電成本下降速度夠快,搭配如特斯拉等公司欲打造的便宜家用儲能電池組,或許能解決太陽能發電不夠穩定、無法成為基載電力的缺點,以取代燃煤發電在電網中的主導角色。     本文全文授權轉載自《科技新報》─〈〉     (首圖來源:Flickr/CC BY 2.0)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

北京掀新能源車熱:指標申請首破三千 純電動車也需搖號

受4月2日北京宣佈純電動小客車不尾號限行()的利好政策推動,據4月9日北京小客車指標調控管理辦公室公佈的資料顯示,本期搖號個人新能源車指標的申請者首次突破三千,達3874人,而此前申請指標的人數徘徊在2000多人左右。根據今年的指標配置方案,本期分配給個人的新能車指標為3333個,這意味著從這一期開始,在北京購買純電動車也要搖號分配了。   在北京剛剛結束的新能源汽車工作會議上,北京相關新能源小客車採取備案制的方案已經通過,知情人士稱,未來進口純電動汽車也有望通過備案進入免購置稅目錄,這無疑將大大增加北京純電動汽車的供應類型。   而針對充電樁安裝困難問題,北京市科委新能源與新材料處處長許心超透露,現在北京正著手做三件事:一是和百度合作,標識所有充電樁地圖並上線;二是印製北京充電樁地圖,發放給消費者和計程車司機;三是辦充電體驗周活動,聯合所有在京車企,做充電實際體驗。   北京市環保局機動車排放管理處處長李昆生在4月7日透露,未來北京將嚴格控制機動車總量,每年新增小客車指標由24萬輛削減到15萬輛,力爭在2017年底前,全市機動車保有量控制在600萬輛以內,而新能源和清潔能源汽車的應用規模將達到20萬輛。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

2015台灣國際電動車展 充電樁與電池技術備受矚目

隨著電動車普及,充電設備、車體以及電池等相關領域也成了相關業者爭相投入的目標。今年共有75家展商參與2015年台灣國際電動車展,許多台廠用充電樁與電動車電池等技術做為「電力」展示主軸。

2015年台北國際汽車零配件展&車用電子展於四月8日至11日在台北世貿、南港展覽館同時展出。其中,在世貿展覽的台北國際電動車展有來自台灣、中國大陸、日本、香港、紐西蘭等廠商參加。除了電動車外,其他主要展出內容包括:電池材料、模組與控制系統,馬達與驅控系統、充電樁相關設備與服務、檢測設備。電力是電動車之本,充電樁、電池或自動充電系統等取得電力的管道是本次展覽中十分重要的部分。

台灣的電動車展出

台灣地狹人稠,對電動載具的需求主要是電動機車和小貨卡、高球車、觀光區小車等工具車,且以電動機車最有發展潛力。受限於電池容量以及載重限制,電動機車體積仍較小,但在造型、避震、輪胎、車燈與置物空間等其他部分則已有多樣化發展,整體功能更接近傳統機車。

電動車的功能考量主要有幾個面向:

  • 充電方便性,如充電樁分布、快充功能、電池交換系統
  • 續航力(每次充電至少需可行駛40~50km)
  • 載重力
  • 爬坡力
  • 行駛速度

哈哈世代主要展出的電動車自動回充發電系統為針對電動車之充電需求所研發,小從電動機車,大到電動卡車、輪船或高鐵列車等皆可應用,車輛行駛一小時左右即可充飽電池,最低每公里耗電成本約為新台幣0.2~0.3元。

大同電子在本次展覽中未展出車輛,而是以電動車馬達為主要展示內容。大同所展示的馬達分成感應馬達、磁阻馬達以及內藏式永磁馬達,額定功率與電壓分別從1.8kW到30kW,以及24V到360V,可根據車輛需求的差別選擇不同功率與電壓的馬達。

晶片解決方案提供者Renesas展出了一種專為HEV/EV驅動馬達設計的變頻器套件解決方案,能縮小變頻器尺寸並提升其效率,且可適用各種馬達,也有助提升電動車馬達的效能。

 

電動車電池與充電樁

在本次展覽中,電動車電池的技術仍是最主要的內容。包括電池的蓄電力、充電後的續航力、充放電技術(快充功能)、防爆與安全性之檢測等,都有展示。

長泓能源科技展示氧化鋰鐵動力電池,這種電池的電性穩定、循環壽命長且能量密度高,加上它十分安全、重量又輕,很適合搭配電動車或其他儲設備使用。

充電樁與電池交換站是電動車的電力來源,密集分布的充電樁有助推廣民眾使用電動車。展場中常見的充電設備包括:壁掛式充電站、立柱式充電樁、電池交換器;而非家用充電設備的使用方法分成兩種,一種是經由卡片認證(可設計特殊RFID卡片或與悠遊卡等電子商務整合),另一種則是投幣式。據了解,台灣設置充電樁依縣市政策之別,可獲得約50%的補助;桃園市補助較高,可接近100%。

EValue 展出單槍、雙槍式充電樁,亦有裝設了液晶螢幕的多媒體充電站,可做為廣告看板。Phihong EV Charger 展出多種充電設備,立柱式充電樁的電容有40kW、70kW以及140kW等類型,也有簡易的小型充電站以及電池充電系統。

台灣喜洋洋公司展出的投幣式電動機車充電站可為裝設戶帶來一定的收益,每投幣10元可充100分鐘。目前有大學、社區等裝設與維護合作。

其他相關展示

汽車電控系統也是本次電動車展覽中可見的項目,例如Chroma就展示一體化的智慧電動車方案,可有效掌控電動車電力系統。EV Equipment  則展示更加環保的電動概念車Preeve。

台灣車輛研發聯盟主題館展示多種電動車相關技術,其中汰役電池的應用為未來將大量產生的廢電池找到了第二春。汰役電池的電容、續航力雖低,但可用於供應較低需求電力,或改作UPS系統。目前在金門烈嶼鄉東坑社區已有汰役電池應用測試,搭配太陽能與風能供應30戶住宅用電,也能支援當地的電動車用電。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

《HelloGitHub》第 51 期

興趣是最好的老師,HelloGitHub 就是幫你找到興趣!

簡介

分享 GitHub 上有趣、入門級的開源項目。

這是一個面向編程新手熱愛編程對開源社區感興趣 人群的月刊,月刊的內容包括:各種編程語言的項目讓生活變得更美好的工具書籍、學習筆記、教程等,這些開源項目大多都是非常容易上手,而且非常 Cool。主要是希望大家能動手用起來,加入到開源社區中。

  • 會編程的可以貢獻代碼
  • 不會編程的可以反饋使用這些工具中的 Bug
  • 幫着宣傳你覺得優秀的項目
  • Star 項目⭐️

在瀏覽、參与這些項目的過程中,你將學習到更多編程知識提高編程技巧找到編程的樂趣

最後 HelloGitHub 這個項目就誕生了

以下為本期內容|每個月 28 號發布最新一期|點擊查看往期內容

C 項目

1、goaccess:實時 Web 日誌分析工具

2、u6a:函數式編程語言 Unlambda 的一個樸素實現,包含字節碼編譯器和解釋器。此項目可以幫助初學者理解函數式編程的思想,並提供了實現函數式編程語言解釋器的一些樸素思路。

  • 性能優異:運行性能遠高於官方實現,且優於多數現有的開源實現
  • 穩定可靠:有豐富的測試樣例支撐,可靠性高
  • 簡單樸素:代碼簡單易讀,且提供了實現思路文檔,對初學或者完全沒有學過編譯原理的新手非常友好

C# 項目

3、Netch:一款 Windows 平台的開源遊戲加速工具

4、ScheduleMasterCore:一款基於 .NET Core 開發的分佈式任務調度系統。支持豐富的調度類型、靈活可控的系統參數、簡易的 UI 操作、支持多節點高可用、業務 API 集成等等特性。同時支持多樣化的部署方式,容易上手

5、HandyControl:一套 WPF 控件庫。它幾乎重寫了所有原生樣式,同時包含 70 餘款自定義控件。支持跨平台、國際化,適用於 MVVM 架構開發,扁平化設計、支持動態更換主題和背景色。豐富的自定義控件解決了 View 設計的痛點,讓程序員更加專註於業務邏輯的開發

C++ 項目

6、CnC_Remastered_Collection:EA 發布的《紅警》和《泰伯利亞黎明》遊戲源代碼

7、chinessChess:基於 Qt5 開發的中國象棋網絡對戰平台,支持單機和網絡對戰

Go 項目

8、grmon:Goroutine 的命令行監控工具

9、HackChrome:Go 語言實現的從 Chrome 中獲取自動保存的用戶名密碼工具。目前僅支持 Windows Chrome 中存儲的密碼,但是很有意思還可以學習怎麼用 Go 調用 DLL 動態鏈接庫的姿勢

10、seaweedfs:一款基於 Go 開發的部署方便、使用簡單且強大的分佈式文件系統

11、fate:起中文名工具,去吧!算名先生

Java 項目

12、JApiDocs:一個無需額外註解、開箱即用的 SpringBoot 接口文檔生成工具。特性:

  • 代碼即文檔
  • 支持導出 HTML
  • 同步導出客戶端 Model 代碼
  • 等等

13、PowerJob:基於 Akka 架構的新一代分佈式任務調度與計算框架。支持 CRON、API、固定頻率、固定延遲等調度策略,支持單機、廣播、MapReduce 等多種執行模式,支持在線任務治理與運維,提供 Shell、Python、Java 等功能豐富的任務處理器,提供工作流來編排任務解決依賴關係,使用簡單,功能強大,文檔齊全。同類產品對比:

JavaScript 項目

14、react-trello:任務狀態管理面板組件。實現了拖拽方式管理任務狀態,點擊即可編輯任務內容

15、perfume.js:用於測量第一個 dom 生成的時間、用戶最早可操作時間和組件的生命周期性能的庫。示例代碼:

perfume.start('fibonacci');
fibonacci(400);
perfume.end('fibonacci');
// Perfume.js: fibonacci 0.14 ms

16、Mongood:MongoDB 圖形化的管理工具。特性:

  • 基於微軟 Fluent UI,支持自動黑暗模式
  • 支持完整的 Mongo-shell 數據類型和查詢語法,利用索引實現的自動查詢和排序
  • 支持 Json 數據庫模式,既可用於 Server 也可用於 Client

17、TimeCat:一款 JS 的網頁錄屏工具。參考了遊戲錄像的原理而實現的渲染引擎,生成的錄像文件只有傳統視頻的百分之一!還可以在錄製語音的同時自動生成字幕,導出的視頻文件可以跨端播放。目前已經開發一段時間,後續還將實現更多有意思的功能,歡迎持續關注。在線預覽

18、react-visual-editor:基於 React 組件的可視化拖拽、搭建頁面的代碼生成工具。所見即所得,可以完美還原 UI 設計搞,並支持多款型號手機(可配置)和 PC 效果展示,模板功能可以使你分享你的頁面或者頁面中局部任何部分組件組合,減少相似頁面的重複操作。效果如下:

19、elevator.js:一個 back to top 返回頂部的插件。如他的名字一樣,網頁在返回頂部過程中像電梯向上運行,當頁面返回到頂部時,會有電梯“到達”的提示音。叮~頁面已到達頂部

PHP 項目

20、code6:一款 GitHub 代碼泄露監控系統,通過定期掃描 GitHub 發現代碼泄露行為。特性:

  • 全可視化界面,操作部署簡單
  • 支持 GitHub 令牌管理及智能調度
  • 掃描結果信息豐富,支持批量操作
  • 任務配置靈活,可單獨配置任務掃描參數
  • 支持白名單模式,主動忽略白名單倉庫

Python 項目

21、rich:一個讓你的終端輸出變得“花里胡哨”的三方庫。我的一位前輩告訴我,不要整那些花里胡哨的主題和樣式,這是在自尋煩惱。可是臣妾做不到啊,這麼好看的終端輸出,讓我的心情都愉悅起來了。瞧那性感的語法高亮、整齊的表格、舒服的顏色、進度條等,一切都是值得的

22、poetry:Python 虛擬環境、依賴管理工具。依賴管理工具有很多,我相上了它有三點:通過單文件 pyproject.toml 便可輕鬆的區別安裝、管理開發和正式環境、有版本鎖定可方便回滾、輸出界面簡單清爽。當然它還是個“新生兒”,嘗鮮的風險還是有的,選擇須謹慎

23、free-python-games:真入門級的 Python 遊戲集合庫。都是簡單的小遊戲:貪吃蛇、迷宮、Pong、猜字等,運行方便、代碼簡單易懂。用遊戲開啟的你 Python 學習之旅,玩完再學源碼,其樂無窮啊。安裝運行:

pip install freegames
python -m freegames.snake # freegames.遊戲名

24、py2sec:一款輕量級跨平台 Python “加密”、加速的腳本工具。原理是基於 Cython 將 .py 編譯成 run-time libraries 文件:.so(Linux && Mac)或 .pyd(Win),一定程度上實現了“加密”保護源代碼的功能。參數詳解如下:

-v,  --version    显示 py2sec 版本
-h,  --help       显示幫助菜單
-p,  --pyth       Python 的版本,默認為你的 Python 命令綁定的 Python 版本
-d,  --directory  Python 項目路徑(如果使用 -d 參數,將編譯整個 Python 項目)
-f,  --file       Python文件(如果使用 -f,將編譯單個 Python 文件)
-m,  --maintain   標記你不想編譯的文件或文件夾路徑
-x  --nthread     編譯啟用的線程數
-q  --quiet       靜默模式,默認 False
-r  --release     Release 模式,清除所有中間文件,只保留加密結果文件,默認 False
python py2sec.py -f test.py
python py2sec.py -f example/test1.py -r
python py2sec.py -d example/ -m test1.py,bbb/

25、oxfs:一個基於 sftp 協議的 fuse 網絡文件系統,功能上類似於 sshfs。特性:

  • 引入了異步併發讀遠端文件機制,提高了文件首次讀速度。
  • 緩存持久化到本地磁盤,下次掛載時訪問更加快速。
  • 異步任務負責同步文件,避免低速的網絡讀寫阻塞上層應用。

Swift 項目

26、Aerial:炫酷的蘋果系統屏保項目。該屏保視頻取材自蘋果零售店 Apple TV 的專用屏保,航拍質量超棒,快換上試試吧。直接下載 Aerial.saver.zip 文件,解壓后雙擊文件“即可食用”

其它

27、shan-shui-inf:自動生成一副山水畫

28、kuboard-press:一款基於 Kubernetes 的微服務管理界面。包含文檔、教程、管理界面和實戰分享

29、vscode-rainbow-fart:一款在你編程時花式誇你的 VSCode 擴展插件。可以根據代碼關鍵字,播放貼近代碼意義的真人語音,並且有一個醒目的項目名字“彩虹屁”

30、flink-training-course:Flink 視頻直播教程回放集合

31、raft-zh_cn:《分佈式 Raft 一致性算法論文》中文翻譯

32、GitHub-Chinese-Top-Charts:每周更新一次的 GitHub 中文項目排行榜

開源書籍

33、go-ast-book:《Go語法樹入門:開啟自製編程語言和編譯器之旅》

機器學習

34、Surprise:一款簡單易用基於 Python scikit 的推薦系統。如果你想用 Python 上手做一套推薦系統,那你可以試試它

35、djl:亞馬遜開源的一款基於 Java 語言的深度學習框架。對於 Java 開發者而言,可以在 Java 中開發及應用原生的機器學習和深度學習模型,同時簡化了深度學習開發的難度。通過 DJL 提供直觀的、高級的 API,Java 開發人員可以訓練自己的模型,或者利用數據科學家用 Python 預先訓練好的模型來進行推理。如果您恰好是對學習深度學習感興趣的 Java 開發者,那麼這個項目完全對口。運行效果如下:

36、data-science-ipython-notebooks:數據科學的 IPython 集合。包含:TensorFlow、Theano、Caffe、scikit-learn、Spark、Hadoop、MapReduce、matplotlib、pandas、SciPy 等方方面面

最後

如果你發現了 GitHub 上有趣的項目,歡迎在 HelloGitHub 項目提 issues 告訴我們。

關注 HelloGitHub 公眾號獲取第一手的更新

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

推薦一種通過刷leetcode來增強技術功底的方法

背景

如果前人認為這個一種學習提高或者檢驗能力的成功實踐。而自己目前又沒有更好的方法,那就不妨試一試。

而不管作為面試官還是被面試者,編碼題最近越來越流行。而兩種角色都需要思考的問題是希望考察什麼能力,通過什麼題目,需要達到怎樣的程度可以說明面試者具有了這樣的能力。

而要找到上面這些問題的答案,比較好的方式除了看一些理論性文章和接受培訓之外,自己動手刷一刷leetcode切身實踐一下不失為一個不錯的方式。而既然要花精力去做這件事情,那就需要解決一個問題:我從中可以獲得什麼提高。以下是個人的一些經驗和感受。

 

收益

對底層有了更深入的了解和思考

leetcode一些常見題也是平時工作中常用的一些底層數據結構的實現方法。 

先舉個大家使用比較多的算法:LRU(最近最少使用),在Java的實現中實現特別簡單。只是使用了LinkedHashMap這種數據結構。而如果看一些開源包里LRU的實現,發現也是這樣實現的。實際上動手實現一遍,LRU就再也不會忘了。

再舉個數據結構的例子:字典樹又叫前綴樹。它是搜索和推薦的基礎。標準點的定義是:

字典樹又稱單詞查找樹,Tire樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。

因為之前做過搜索引擎,一直也對這塊很有興趣,所以對它底層知識的補充對個人而言,感覺深度有增加。

 

  

養成評估時空開銷的習慣

我刷leetcode必看官方解答里估算的時間和空間複雜度。這也是作為一個架構師的必備基本能力。

數組、哈希這些因為數據的位置不需要進行查找,只需要算數計算就可以得到,所以它們的時間複雜度是O(1)。

鏈表如果直接在頭部或者尾部插入,因為不需要查找,所以時間複雜度也是O(1),但是定位的話因為涉及查找,按遍歷查找來算是log(n)。所以對於jdk1.7之前,hashmap底層採用的是數組+鏈表的數據結構。所以如果不算哈希衝突和擴容的話,獲取和插入數據的時間複雜度是O(1);如果出現了哈希衝突,則插入因為是頭部插入,時間複雜度還是O(1);獲取時間複雜度因為涉及先查找,所以是O(n),這個n代表衝突的數量。

對於在有序數據中進行查找,因為可採用二分查找等優化,時間複雜度可降到log(n).

對於遞歸調用,如果遞歸方法內進行2次調用。對於層數n來說,時間複雜度是2的n次方。舉個例子就是一個數等於前面兩個數之和。當然,如果是前面3個數之和,不進行優化的情況下時間複雜度就是3的n次方。

對於一個n*m的二維數組等需要進行嵌套循環遍歷的,時間複雜度是O(n*m),有個特殊情況是n*m,這時候時間複雜度是n的平方。

對於全排列的情況,時間複雜度是O(n!)。

 

代碼簡化的方法

 

我習慣的一種學習方法是先做題,有了一定自己的總結和思考之後,再看書學習別人的總結思考方法。對於刷leetcode相關性高,也比較受認可的書是《Cracking the Coding interview(6th)》,中文版翻譯是《程序員面試金典》。這本書對於面試官和面試者來說讀了都會有一定的收穫。

 

我讀了這本書,對我印象最深的是介紹了兩種代碼優化的方法:BUD和BCR。

 

BUD 

BUD是瓶頸、不必要工作、重複工作 三個詞組首字母的縮寫。

 

作者提出拿到一道編程題,可先嘗試用暴力解法將題目寫出來,之後找到解法的性能瓶頸,針對瓶頸進行優化,之後在去掉不必要的工作,最後去掉重複的工作。

這個經典的編程優化方法不只可應用於編程,還可應用於整個程序的優化,也是最常規的優化方法。

 

BCR

BCR是Best Conceivable Runtime的縮寫,意思是想知道自己可以優化到什麼程度,先估算可達到的最優情況。

比如:在一個無序數組中,查找兩個兩個相同的數。直覺來說如果找到這兩個數,最起碼需要將每個數都遍歷一遍,所以可達到的最優情況是O(n),無論怎麼優化,都不可能比這個更好。所以這就是優化的上限。

這本書里還介紹了其他的優化方法如:使用額外數據結構、通過構建測試用例、根據題目的限制和提示來尋找線索,大家看這本書的時候可以了解下。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

【asp.net core 系列】14 .net core 中的IOC

0.前言

通過前面幾篇,我們了解到了如何實現項目的基本架構:數據源、路由設置、加密以及身份驗證。那麼在實現的時候,我們還會遇到這樣的一個問題:當我們業務類和數據源越來越多的時候,我們無法通過普通的構造對象的方法為每個實例進行賦值。同時,傳統意義上的賦值遇到底層切換或者其他修改的時候,就需要修改大量的代碼,對改變不友好。為了改變這種現狀,我們基於面向接口編程,然後使用一些DI功能和IOC框架。

1. IOC和DI

先來給大家解釋幾個概念,IOC全稱Inversion of Control,翻譯過來就是控制反轉,是面向對象編程的一種設計原則,用來降低代碼之間的耦合度。所謂的控制反轉簡單來講就是將類中屬性或者其他參數的初始化交給其他方處理,而不是直接使用構造函數。

public class Demo1
{
}

public class Demo2
{
	public Demo1 demo;
}

對於以上簡單示例代碼中,在Demo2類中持有了一個Demo1的實例。如果按照之前的情況來講,我們會通過以下方法為demo賦值:

// 方法一
public Demo1 demo = new Demo1();
// 方法二
public Demo2()
{
    demo = new Demo1();
}

這時候,如果Demo1變成下面的樣子:

public class Demo1
{
    public Demo1(Demo3 demo3)
    {
        // 隱藏
    }
}
public class Demo3
{
}

那麼,如果Demo2 沒有持有一個Demo3的實例對象,這時候創建Demo1的時候就需要額外構造一個Demo3。如果Demo3需要持有另外一個類的對象,那麼Demo2中就需要多創建一個對象。最後就會發現這樣就陷入了一個構造“地獄”(我發明的詞,指這種為了一個對象卻得構造一大堆其他類型的對象)。

實際上,對於Demo2並不關心Demo1的實例對象是如何獲取的,甚至都不關心它是不是Demo1的子類或者接口實現類。我在示例中使用了類,但這裏可以同步替換成Interface,替換之後,Demo2在調用Demo1的時候,還需要知道Demo1有實現類,以及實現類的信息。

為了解決這個問題,一些高明的程序員們提出了將對象的創建這一過程交給第三方去操作,而不是調用類來創建。於是乎,上述代碼就變成了:

public class Demo2
{
    public Demo1 Demo {get;set;}
    public Demo2(Demo1 demo)
    {
        Demo = demo;
    }
}

似乎並沒有什麼變化?對於Demo2來說,Demo2從此不再負責Demo1的創建,這個步驟交由Demo2的調用方去創建,Demo2從此從負責維護Demo1這個對象的大麻煩中解脫了。

但實際上構造地獄的問題還是沒有解決,只不過是通過IOC的設計將這一步后移了。這時候,那些大神們想了想,不如開發一個框架這些實體對象吧。所以就出現了很多IOC框架:AutoFac、Sping.net、Unity等。

說到IOC就不得不提一下DI(Dependency Injection)依賴注入。所謂的依賴注入就是屬性對應實例通過構造函數或者使用屬性由第三方進行賦值。也就是最後Demo2的示例代碼中的寫法。

早期IOC和DI是指一種技術,後來開始確定這是不同的描述。IOC描述的是一種設計模式,而DI是一種行為。

2. 使用asp.net core的默認IOC

在之前的ASP.NET 框架中,微軟並沒有提供默認的IOC支持。在最新的asp.net core中微軟提供了一套IOC支持,該支持在命名空間:

Microsoft.Extensions.DependencyInjection

里,在代碼中引用即可。

主要通過以下幾組方法實現:

public static IServiceCollection AddScoped<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddTransient<TService>(this IServiceCollection services) where TService : class;

這裏只列出了這三組方法的一種重載版本。

這三組方法分別代表三種生命周期:

  • AddScored 表示對象的生命周期為整個Request請求
  • AddTransient 表示每次從服務容器進行請求時創建的,適合輕量級、 無狀態的服務
  • AddSingleton 表示該對象在第一次從服務容器請求后獲取,之後就不會再次初始化了

這裏每組方法只介紹了一個版本,但實際上每個方法都有以下幾個版本:

public static IServiceCollection AddXXX<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Type implementationType);
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory);
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services)
            where TService : class
            where TImplementation : class, TService;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType);
public static IServiceCollection AddXXX<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class;
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
            where TService : class
            where TImplementation : class, TService;

其中:implementationFactory 表示通過一個Provider實現TService/TImplementation 的工廠方法。當方法指定了泛型的時候,會自動依據泛型參數獲取要注入的類型信息,如果沒有使用泛型則必須手動傳入參數類型。

asp.net core如果使用依賴注入的話,需要在Startup方法中設置,具體內容可以參照以下:

public void ConfigureServices(IServiceCollection services)
{
    //省略其他代碼
    services.AddScoped<ISysUserAuthRepository,SysUserAuthRepository>();
}

asp.net core 為DbContext提供了不同的IOC支持,AddDbContext:

public static IServiceCollection AddDbContext<TContext>(
      this IServiceCollection serviceCollection,
      Action<DbContextOptionsBuilder> optionsAction = null,
      ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
      ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
      where TContext : DbContext;

使用方法如下:

services.AddDbContext<DefaultContext>();

3. AutoFac 使用

理論上,asp.net core的IOC已經足夠好了,但是依舊原諒我的貪婪。如果有二三百個業務類需要我來設置的話,我寧願不使用IOC。因為那配置起來就是一場極其痛苦的過程。不過,可喜可賀的是AutoFac可以讓我免收這部分的困擾。

這裏簡單介紹一下如何使用AutoFac作為IOC管理:

cd Web  # 切換目錄到Web項目
dotnet package add Autofac.Extensions.DependencyInjection # 添加 AutoFac的引用

因為asp.net core 版本3更改了一些邏輯,AutoFac的引用方式發生了改變,現在不介紹之前版本的內容,以3為主。使用AutoFac需要先在 Program類里設置以下代碼:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    		Host.CreateDefaultBuilder(args)
    		.UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 添加這行代碼
    		.ConfigureWebHostDefaults(webBuilder =>
			{
                webBuilder.UseStartup<Startup>();
            });

在Program類里啟用AutoFac的一個Service提供工廠類。然後在Startup類里添加如下方法:

public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<DefaultContext>().As<DbContext>()
                .WithParameter("connectStr","Data Source=./demo.db")
                .InstancePerLifetimeScope();
            

    builder.RegisterAssemblyTypes(Assembly.Load("Web"))
        .Where(t => t.BaseType.FullName.Contains("Filter"))
        .AsSelf();

    builder.RegisterAssemblyTypes(Assembly.Load("Domain"),
                    Assembly.Load("Domain.Implements"), Assembly.Load("Service"), Assembly.Load("Service.Implements"))
                .AsSelf()
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .PropertiesAutowired();
}

修改:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
            {
                options.Filters.Add<UnitOfWorkFilterAttribute>();
            }).AddControllersAsServices();// 這行新增
    // 省略其他
}

4. 總結

這一篇簡單介紹了如何在Asp.net Core中啟用IOC支持,並提供了兩種方式,可以說是各有優劣。小夥伴們根據自己需要選擇。後續會為大家詳細深入AutoFac之類IOC框架的核心秘密。

更多內容煩請關注我的博客《高先生小屋》

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

作為一個Java開發你用過Jib嗎

1. 前言

JibGoogle開發的可以直接構建 Java應用的DockerOCI鏡像的類庫,以MavenGradle插件形式提供。它最騷操作的是可以在沒有Docker守護程序的情況下構建,也就是說,您不必在計算機上安裝docker守護程序!儘管Spring Boot 2.3.0.RELEASE已經推出了構建鏡像的功能,胖哥還是忍不住要試試Jib

其實最騷的還是名字。

2. Docker構建流程和Jib的構建流程

沒有對比就沒有傷害。我們還是要對比一下這兩者的構建流程。

Docker構建流程需要我們先把項目打成Jar然後編寫Dockerfile,然後使用Docker構建功能進行構建鏡像、運行容器。流程如下:

而Jib是這樣構建的:

作為一個Java開發者,不用再關心各種無關的命令和操作,只需要專註於Java,而且高效穩定以及可復用的增量構建。為什麼Jib能這麼快而高效?

傳統上,將Java應用程序與應用程序Jar一起構建為單個圖像層,而Jib的構建策略將Java應用程序分為多層,以進行更細化的增量構建。更改代碼時,僅重建更改,而不重建整個應用程序。

3. Jib構建Spring Boot應用

接下來我將演示如何將Spring Boot 應用打成鏡像並上傳到Dockerhub倉庫。

Maven工程為例,我們只需要在pom.xml中引入Jib Maven 插件。默認情況下Jib會把我們打好的鏡像上傳到Googlegcr.io倉庫,實際中我們會把打好的鏡像上傳到私有倉庫,所以我們要加一些個性化配置。這裏我以dockerhub倉庫為例添加一些個性化配置:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.4.0</version>
    <configuration>
        <!-- 相當於 Dockerfile 中的 FROM -->
        <from>
            <image>amazoncorretto:8</image>
        </from>
        <to>
            <!--構建鏡像名稱,這裏我使用maven中定義的項目名稱-->
            <image>daxus/${project.name}</image>
            <!--私有倉庫的賬號密碼-->
            <auth>
                <username>felordcn</username>
                <password>yourpassword</password>
            </auth>
            <!--Docker 鏡像的 tag 這裏使用maven定義的版本號-->
            <tags>
                <tag>
                    ${project.version}
                </tag>
            </tags>
        </to>
    </configuration>
</plugin>

然後在項目根目錄執行mvn clean compile jib:build就可以了。

其實也可以簡單引入Jib插件:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.4.0</version>
</plugin>

只不過我們的命令會更複雜一些,需要指定一些必要的參數,例如:

mvn clean compile jib:build \
    -Djib.to.image=myregistry/myimage:latest \
    -Djib.to.auth.username=$USERNAME \
    -Djib.to.auth.password=$PASSWORD

更多的定製命令可參考官方文檔:

https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#extended-usage

4. 總結

Jib使用起來非常簡單,讓開發人員以Java的風格來完成Docker鏡像的構建,能夠大大改善編程的體驗。多多關注:碼農小胖哥 獲取更多有用的編程乾貨教程。

關注公眾號:Felordcn 獲取更多資訊

個人博客:https://felord.cn

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

聊聊算法–堆的構建和調整

先提個問題,完全二叉樹/滿二叉樹,區別?前者是指每一層都是緊湊靠左排列,最後一層可能未排滿,後者是一種特殊的完全二叉樹,

每層都是滿的,即節點總數和深度滿足N=(2^n) -1。堆Heap,一堆蘋果,為了賣相好,越好看的越往上放,就是大頂堆;為了蘋果堆

的穩定,質量越小越往上放,就是小頂堆;堆首先是完全二叉樹,但只確保父節點和子節點大小邏輯,不關心左右子節點的大小關係,

通常是一個可以被看做一棵樹的數組對象,是個很常見的結構,比如BST對象,都與堆有關係,今天就說下這個重要的數據結構和應用。

 

作者原創文章,謝絕一切轉載,違者必究!

本文只發表在”公眾號”和”博客園”,其他均屬複製粘貼!如果覺得排版不清晰,請查看公眾號文章。 

 

準備:

Idea2019.03/Gradle6.0.1/Maven3.6.3/JDK11.0.4

難度: 新手–戰士–老兵–大師

目標:

1.堆的構建和調整算法

1 優先級隊列

為理解堆的原理,先看優先級隊列,它是一種數據結構,插入或者刪除元素的時候,元素會自動排序,(優先級不是狹義的數值大小,

但為了通俗理解,這裏以字母序為例),通常使用數組存儲,我們可以按照下圖進行轉換,序號 0 不用:

優先級隊列的實現(Java版):

public class PriorityQueue<Key extends Character> {
    /** 存儲元素的數組 */
    private Key[] keys;
    private int N = 0;

    public PriorityQueue(int capacity){
        // 下標0不用,多分配一個單位
        keys = (Key[]) new Character[capacity + 1];
    }

    public Key max(){
        return keys[1];
    }

    public void insert(Key e){
        N ++;
        keys[N] = e;
        swim(N);
    }
    public Key delMax(){
        Key max = keys[1];
        swap(1,N);
        keys[N] = null;
        N --;
        // 讓第一個元素下沉到合適的位置
        sink(1);
        return max;
    }
    /** 上浮第k個元素*/
    private void swim(int k){
        // 比父節點小,即進行交換,直到根
        while (k > 1 && less(parent(k),k)){
            swap(k,parent(k));
            k = parent(k);
        }
    }
    /** 下沉第 k 個元素*/
    private void sink(int k){
        while(k < N){
            int small = left(k);
            if (right(k) < N && less(right(k),left(k))){
                small = right(k);
            }
            if (less(k,small)){
                swap(k,small);
                k = small;
            }
        }
    }
    private void swap(int i,int j){
        Key temp = keys[i];
        keys[i] = keys[j];
        keys[j] = temp;
    }
    /** 元素i和j大小比較*/
    private boolean less(int i,int j){
//   'a' - 'b' = -1 ;
        return keys[i].compareTo(keys[j]) > 0;
    }
    /** 元素i的父節點*/
    private int parent(int i){
        return i/2;
    }
    /** 元素i的左子節點*/
    private int left(int i){
        return i * 2;
    }
    /** 元素i的右子節點*/
    private int right(int i){
        return i * 2 + 1;
    }
}
 

以上代碼解析:

1 swim 上浮,對於元素k,是否需要上浮,僅需與其父節點比較,大於父節點則交換,迭代直到根節點;

2 sink 下沉,對於元素k,是否需要下沉,需先比較其左右子節點,找出左右子節點中較小者,較小者若比父節點大,則交換,迭代直到末尾元素;

3 insert 插入,先將元素放到數組末尾位置,再對其進行上浮操作,直到合適位置;

4 delMax 刪除最大值,大根堆,故第一個元素最大,先將首末元素交換,再刪除末尾元素,再對首元素下沉操作,直到合適位置;

總結:以上只是Java簡化版,java.util.PriorityQueue 是JDK原版,客官可自行研究。但設計還是非常有技巧的,值得思考一番,假設 insert 插入

到首位,會導致數組大量元素移動。delMax 若直接刪除首位最大值,則需要進一步判斷左右子節點大小,並進行先子節點上浮再首元素下沉操作。

        有了這個堆結構,就可以進行堆排序了,將待排數全部加入此堆結構,然後依次取出,即成有序序列了!

2 堆排序

如要求不使用上述堆數據結構。思路(升序為例):將數組構建為一個大頂堆,首元素即為數組最大值,首尾元素交換;排除末尾元素后調整大頂堆,

則新的首元素即為次最大值,交換首尾並再排除末尾元素;如此循環,最後的數組即為升序排列

public class HeapSort02 {
    public static void main(String []args){
        int []arr = {2,1,8,6,4,7,3,0,9,5};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void sort(int []arr){
        int len = arr.length;
        // 創建一個大頂堆
        for(int i = (int) Math.ceil(len/2 - 1); i >= 0; i--){
            //從第一個非恭弘=叶 恭弘子結點從下至上,從右至左調整結構
            adjustHeap(arr,i,len);
        }
        // 交換首尾元素,並重新調整大頂堆
        for(int j = len-1;j > 0;j--){
            swap(arr,0,j);
            adjustHeap(arr,0,j);
        }
    }

    /** 迭代寫法*/
    public static void adjustHeap(int []arr,int i,int length){
        int temp = arr[i];
        for (int k = 2*i + 1; k < length; k=k*2 + 1) {
        // 注意這裏的k + 1 < length
            // 如果右子節點大於左子節點,則比較對象為右子節點
            if (k + 1 < length && arr[k] < arr[k+1]){
                k++;
            }
            if (arr[k] > temp){
                // 不進行值交換
                arr[i] = arr[k];
                i = k;
            }
            else{
                break;
            }
        }
        arr[i] = temp;
    }

    /** 遞歸寫法*/
    private static void adjustHeap2(int[] arr, int i, int len){
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int maxIndex = i;
        // 注意這裏的 left < len
        if (left < len && arr[left] > arr[maxIndex]){
            maxIndex = left;
        }
        if (right < len && arr[right] > arr[maxIndex]){
            maxIndex = right;
        }
        if (maxIndex != i){
            swap(arr,i,maxIndex);
            adjustHeap2(arr,maxIndex,len);
        }
    }

    /** 交換元素 */
    public static void swap(int []arr,int a ,int b){
        int temp=arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}
 

以上代碼解析:

1完全二叉樹結構中,如果根節點順序號為 0,總節點數為 N,則最末節點的父節點即為最後一個非恭弘=叶 恭弘子節點,順序號為 ceil(N/2 -1),

2 adjustHeap2 為啥使用三個參數,不用中間的參數可以?使用三個參數,是為了進行遞歸調用,因為遞歸肯定是縮小計算規模,而這裏的形參arr和len是固定不變的;

3 adjustHeap是非遞歸寫法,不用中間的參數可以?調用一在“構建大頂堆”處,可寫為函數體內初始化 i,並形成雙重 for 循環;調用二在“重新調整大頂堆”處,

    可見中間參數為 0,可直接去掉。故回答是可以!但需要調整寫法,且影響該方法復用,這裏直接寫為三個形參的函數更為優雅而已。

4非遞歸寫法理解:類似插入排序思想(依次移動並找到合適的位置再插入),先將 arr[i] 取出,然後此節點和左右子樹進行比較,如子樹更大則子節點上升一層,使

    用for循環迭代到最終位置,並進行賦值;

 

以 i=0 為例:

5遞歸方式理解:定位目標元素的左右子樹,若子樹值更大,則進行值交換,且因為子樹發生了變化,故需要對子樹進行遞歸處理;

3 前K個最大的數

在N個數中找出前K個最大的數: 思路:從N個數中取出前K個數,形成一個數組[K],將該數組調整為一個小頂堆,則可知堆頂為K個數中最小值,

然後依次將剩餘 N-K 個數與堆頂比較,若大於,則替換掉並調整堆,直到所有元素加入完畢,堆中元素即為目標集合。

public class HeapSort {
    public static void main(String[] args) {
        int[] arr = new int[100];
        for (int i = 0; i < 100; i++) {
            arr[i] = i + 1;
        }
        // 前10個最大的數
        int k = 10;
        // 構造小頂堆
        for (int i = (int) Math.ceil(k/2 - 1); i >= 0; i--) {
            adjustHeap(arr,i,k);
        }
        // 依次比較剩餘元素
        for (int i = 10; i < arr.length; i++) {
            if (arr[i] > arr[0]){
                swap(arr,0,i);
                adjustHeap(arr,0,k);
            }
        }
        // 輸出結果
        for (int i = 0; i < 10; i++) {
            System.out.print(arr[i]+"-");
        }
    }

    /** 非迭代寫法 ,對arr[i]進行調整 */
    private static void adjustHeap(int[] arr,int i,int length){
        int temp = arr[i];
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
            // 因第一次循環中可能越界,故需要 k+1 < length
            if (k + 1 < length && arr[k] > arr[k + 1]){
                k++;
            }
            if (arr[k] < temp){
                arr[i] = arr[k];
                i = k;
            }
            else {
                break;
            }
        }
        arr[i] = temp;
    }
    /** 遞歸寫法 */
    private static void adjustHeap2(int[] arr,int i,int length){
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int samller = i;
        if (left < length && arr[left] > arr[samller]){
            samller = right;
        }
        if (right < length && arr[right] > arr[samller]){
            samller = right;
        }
        if (samller != i){
            swap(arr,i,samller);
            adjustHeap2(arr,samller,length);
        }
    }

    /** 交換元素 */
    public static void swap(int []arr,int a ,int b){
        int temp=arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}
 

以上代碼解析:按照”初始化—構建小頂堆—比較調整—輸出結果”執行。注意for循環中,因第一次循環中未使用for語句條件判斷,可能越界,故需要 k+1 < length

輸出結果如下:

請看官思考,如果需求變為找出N個數中找出前K個最小的數,該如何實現? 建議動腦且動手的寫一遍!因為魔鬼在細節!

全文完!

我近期其他文章:

  • 1 Dubbo學習系列之十九(Apollo配置中心)
  • 2 聊聊算法——二分查找算法深度分析
  • 3 DevOps系列——Jenkins/Gitlab自動打包部署
  • 4 DevOps系列——Jenkins私服
  • 5 DevOps系列——Gitlab私服

    只寫原創,敬請關注 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!