图像处理职位面试题汇总(1)
Matlab編程部分
1. Matlab 中讀、寫及顯示一幅圖像的命令各是什么?
解:第一、Matlab中讀圖像函數(shù)是imread( )。imread 函數(shù)用于讀入各種圖像文件,其一般的用法為:[X,MAP]=imread(‘filename’,‘fmt’)
其中,X,MAP分別為讀出的圖像數(shù)據(jù)和顏色表數(shù)據(jù),fmt為圖像的格式,filename為讀取的圖像文件(可以加上文件的路徑)。如: [X,MAP]=imread(’flowers.tif’,’tif’);比較讀取二值圖像,灰度圖像,索引圖像,彩色圖像的X和MAP的特點。
第二、Matlab中讀圖像函數(shù)是imwrite( ),imwrite函數(shù)用于輸出圖像,其語法格式為: imwrite(X,map,filename,fmt)
按照fmt指定的格式將圖像數(shù)據(jù)矩陣X和調(diào)色板map寫入文件filename。
第三、Matlab中顯示圖像函數(shù)是imshow( ),imshow函數(shù)是最常用的顯示各種圖像的函數(shù),其語法如:imshow(X,map)
其中X是圖像數(shù)據(jù)矩陣,map是其對應(yīng)的顏色矩陣,若進行圖像處理后不知道圖像數(shù)據(jù)的值域可以用[]代替map。
- 二進制(二值)圖像顯示方法,在MATLAB中一幅二值圖像是uint8或雙精度的,該矩陣僅包含0和1。如果希望工具箱中的函數(shù)能將圖像理解為二進制的,那么所有數(shù)據(jù)都要是邏輯數(shù)據(jù),必須對其進行設(shè)置(將所有數(shù)據(jù)標志均設(shè)置on).可以對數(shù)據(jù)利用“~”取反操作實現(xiàn)圖像逆轉(zhuǎn)即黑白反色。
- 灰度圖像的顯示方法,正常情況下無需指定灰度圖像的調(diào)色板格式。可以是使用imshow函數(shù)指定要顯示灰度級數(shù)目,格式 imshow(I,n),n為指定的灰度級數(shù)目。用戶也可以指定數(shù)據(jù)的范圍,格式imshow(I,[low high])其中l(wèi)ow 和high參數(shù)分別為數(shù)據(jù)數(shù)組的最小值和最大值。如果為空矩陣([]),那么imshow函數(shù)將自動進行數(shù)據(jù)標度。
- 索引圖像,imshow(x,map)對于x的每個個像素,imshow顯示存儲map中相應(yīng)行的顏色。
- RGB圖像的顯示,它直接對顏色進行描述而不使用調(diào)色板,格式imshow(RGB)。 RGB(:,:,1) RGB(:,:,2) RGB(:,:,3)
- 特殊顯示,如多幅圖像的顯示,需要顯示多幅圖像時。可以使用figure語句,它的功能就是重新打開一個圖像顯示窗口.
2. Matlab 與VC++混合編程有哪幾種方式?
解:Matlab與VC++混合編程主要有三種方式:Matlab引擎方式、Matlab編譯器及COM組件。
第一種:Matlab引擎方式。Matlab引擎采用客戶機/服務(wù)器(Client/Server)的方式,提供了一組Matlab API函數(shù),通過調(diào)用這些函數(shù)實現(xiàn)以用程序進程之間的數(shù)據(jù)傳遞。VC程序作為前端客戶機,向Matlab引擎?zhèn)鬟f命令和數(shù)據(jù),并從Matlab引擎接受數(shù)據(jù)信息,實現(xiàn)動態(tài)通信。采用這種方法幾乎能利用MATLAB全部功能,但是需要在機器上安裝MATLAB軟件,而且執(zhí)行效率低,因此在實際應(yīng)用中不采用這種方法,在軟件開發(fā)中也不可行。
第二種:Matlab編譯器。MATLAB Compiler可以將M語言函數(shù)文件自動轉(zhuǎn)化產(chǎn)生獨立應(yīng)用程序或者軟件組件,生成的組件或者獨立應(yīng)用程序可以與其他用戶共享。使用MATLAB Compiler創(chuàng)建的獨立應(yīng)用程序或者軟件組件能夠完全脫離MATLAB環(huán)境。MATLAB Compiler能夠顯著的縮短桌面應(yīng)用程序的開發(fā)時間,僅僅通過簡單的指令就可以將M語言函數(shù)轉(zhuǎn)變?yōu)楠毩⒌膽?yīng)用程序或者軟件組件,然后將它們打包發(fā)布給最終用戶。這里所指的利用M語言開發(fā)的MATLAB應(yīng)用程序可以包括數(shù)學(xué)計算、圖形應(yīng)用和GUIDE開發(fā)的圖形界面等,而最終用戶根本不需要擁有MATLAB。
其特點:1、自動將M語言函數(shù)文件轉(zhuǎn)換為可執(zhí)行應(yīng)用程序,脫離MATLAB環(huán)境2、簡單易用的發(fā)布過程3、支持所有MATLAB的M語言特性,例如MATLAB對象、Java對象等等。4、支持大多數(shù)工具箱函數(shù),允許將MATLAB基本算法免費發(fā)布使用強大功能。 5、用戶可以利用MATLAB集成環(huán)境開發(fā)自己的算法原型和應(yīng)用程序,然后利用MATLAB Compiler將開發(fā)的算法發(fā)布給最終用戶,最終用戶可以通過可執(zhí)行應(yīng)用程序或者軟件組件應(yīng)用開發(fā)完好的算法。用戶在進行算法維護的時候無需針對C代碼進行操作。
算法開發(fā)僅僅需要三個步驟:第一步:創(chuàng)建算法,MATLAB本身是一種集成化的算法開發(fā)環(huán)境,它提供了各種工具用于完成算法快速原型的開發(fā)、測試。其中包括了高級的基于矩陣運算的向量化算法語言M語言,并且內(nèi)建了大量用于數(shù)學(xué)計算、數(shù)據(jù)分析和圖形可視化的算法函數(shù)。MATLAB開發(fā)工具提供了語言編輯器、調(diào)試工具和性能分析器,并且可以利用交互式圖形界面開發(fā)工具開發(fā)自定義的圖形界面工具。第二步:轉(zhuǎn)化應(yīng)用程序。使用MATLAB Compiler可以將開發(fā)好的M語言算法函數(shù)轉(zhuǎn)變成為:獨立可執(zhí)行應(yīng)用程序;C/C++算法共享庫;軟件組件,例如COM對象或者Excel插件;獨立可執(zhí)行應(yīng)用程序;MATLAB Compiler可以自動地將MATLAB應(yīng)用程序轉(zhuǎn)變?yōu)楠毩⒖蓤?zhí)行應(yīng)用程序;自動確定相關(guān)的MATLAB函數(shù) ;生成C/C++接口代碼文件 ;將所有相關(guān)的文件打包壓縮保存在單一壓縮文件中;可在最終的應(yīng)用程序中集成用戶的C或C++代碼。第三步:算法函數(shù)庫。使用與創(chuàng)建獨立可執(zhí)行應(yīng)用程序相同的指令就可以創(chuàng)建MATLAB函數(shù)庫。MATLAB? Compiler將自動創(chuàng)建相應(yīng)的頭文件和共享庫文件,以便集成自定義的C/C++代碼文件,最終完成應(yīng)用程序的開發(fā)。通過MATLAB Compiler完成應(yīng)用程序的發(fā)布之后,可以將應(yīng)用程序打包、發(fā)布給任意的最終用戶。MATLAB Compiler提供了相應(yīng)的應(yīng)用軟件可以將運行應(yīng)用程序必需的庫文件打包。
第三種:COM組件。COM(Component Object Model,組件對象模型)是以組件為發(fā)布單元的對象模型,是一系列面向?qū)ο蠹夹g(shù)和工具的集合。由于COM是建立在二進制級別上的規(guī)范,所以組件對象之間的交互規(guī)范不依賴于任何特定的語言。MATLAB提供了COM生成器。COM生成器提供了實現(xiàn)MATLAB獨立應(yīng)用的一種新途徑。它能把MATLAB開發(fā)的算法做成組件,這些組件作為獨立的COM對象,可以直接被C++、VB、VC、C#、JAVA或其他支持COM的語言所引用,只要相應(yīng)的MATLAB編譯器和C/C+ +編譯器都已經(jīng)安裝及配置成功,MATLAB COM編譯器即可開始使用,并不需要特別的設(shè)置。該方法實現(xiàn)簡單,通用性強,而且?guī)缀蹩梢允褂肕ATLAB的任何函數(shù)(注意:不支持腳本文件,腳本文件使用時要改為函數(shù)文件),因此在程序較大、調(diào)用工具箱函數(shù)或調(diào)用函數(shù)較多時推薦使用。Matlab的COM 編譯器是在Matlab6.5中才開始提供的一個新工具,從Matlab7.0起,這個產(chǎn)品改名為MatlabBuilder for COM。基于COM的混合編程方法也是Mathworks公司推薦使用的方法。
以上3種方法中,采用Matlab引擎方式,應(yīng)用程序整體性能好,Matlab引擎支持功能全面,但需要Matlab后臺運行,不能脫離Matlab 環(huán)境。而MCC方法和COM組件方法均可以脫離Matlab環(huán)境,應(yīng)用程序運行效率高,利于軟件的開發(fā)。
3.Matlab運算中 . *和 * 的區(qū)別?
解:MATLAB中 帶“.” (讀作“點”)的運算符都表示點運算。這就要求A.*B中的A、B必須同規(guī)格,然后對應(yīng)點的數(shù)據(jù)相乘,結(jié)果也是一個與A、B相同規(guī)格的矩陣。(標量是1*1矩陣)MATLAB的數(shù)據(jù)單元是矩陣,*表示的是矩陣相乘。要求A*B中A的列數(shù)等于B的行數(shù)。
圖像處理基礎(chǔ)部分
1. Intel指令集中MMX,SSE,SSE2,SSE3和SSE4指的是什么?
解:Intel指令集中MMX(Multi Media eXtension,多媒體擴展指令集)指令集是Intel公司于1996年推出的一項多媒體指令增強技術(shù)。MMX指令集中包括有57條多媒體指令,通過這些指令可以一次處理多個數(shù)據(jù),在處理結(jié)果超過實際處理能力的時候也能進行正常處理,這樣在軟件的配合下,就可以得到更高的性能。MMX的益處在于,當(dāng)時存在的操作系統(tǒng)不必為此而做出任何修改便可以輕松地執(zhí)行MMX程序。但是,問題也比較明顯,那就是MMX指令集與x87浮點運算指令不能夠同時執(zhí)行,必須做密集式的交錯切換才可以正常執(zhí)行,這種情況就勢必造成整個系統(tǒng)運行質(zhì)量的下降。
Intel指令集中SSE(Streaming SIMD Extensions,單指令多數(shù)據(jù)流擴展)指令集是Intel在Pentium III處理器中率先推出的。其實,早在PIII正式推出之前,Intel公司就曾經(jīng)通過各種渠道公布過所謂的KNI(Katmai New Instruction)指令集,這個指令集也就是SSE指令集的前身,并一度被很多傳媒稱之為MMX指令集的下一個版本,即MMX2指令集。究其背景,原來"KNI"指令集是Intel公司最早為其下一代芯片命名的指令集名稱,而所謂的"MMX2"則完全是硬件評論家們和媒體憑感覺和印象對"KNI"的 評價,Intel公司從未正式發(fā)布過關(guān)于MMX2的消息。而最終推出的SSE指令集也就是所謂勝出的"互聯(lián)網(wǎng)SSE"指令集。SSE指令集包括了70條指令,其中包含提高3D圖形運算效率的50條SIMD(單指令多數(shù)據(jù)技術(shù))浮點運算指令、12條MMX 整數(shù)運算增強指令、8條優(yōu)化內(nèi)存中連續(xù)數(shù)據(jù)塊傳輸指令。理論上這些指令對目前流行的圖像處理、浮點運算、3D運算、視頻處理、音頻處理等諸多多媒體應(yīng)用起到全面強化的作用。S SE指令與3DNow!指令彼此互不兼容,但SSE包含了3DNow!技術(shù)的絕大部分功能,只是實現(xiàn)的方法不同。SSE兼容MMX指令,它可以通過SIMD和單時鐘周期并行處理多個浮點數(shù)據(jù)來有效地提高浮點運算速度。
Intel指令集中SSE2(Streaming SIMD Extensions 2,Intel官方稱為SIMD 流技術(shù)擴展 2或數(shù)據(jù)流單指令多數(shù)據(jù)擴展指令集 2)指令集是Intel公司在SSE指令集的基礎(chǔ)上發(fā)展起來的。相比于SSE,SSE2使用了144個新增指令,擴展了MMX技術(shù)和SSE技術(shù),這些指令提高了廣大應(yīng)用程序的運行性能。隨MMX技術(shù)引進的SIMD整數(shù)指令從64位擴展到了128 位,使SIMD整數(shù)類型操作的有效執(zhí)行率成倍提高。雙倍精度浮點SIMD指令允許以 SIMD格式同時執(zhí)行兩個浮點操作,提供雙倍精度操作支持有助于加速內(nèi)容創(chuàng)建、財務(wù)、工程和科學(xué)應(yīng)用。除SSE2指令之外,最初的SSE指令也得到增強,通過支持多種數(shù)據(jù)類型(例如,雙字和四字)的算術(shù)運算,支持靈活并且動態(tài)范圍更廣的計算功能。SSE2指令可讓軟件開發(fā)員極其靈活的實施算法,并在運行諸如MPEG-2、MP3、3D圖形等之類的軟件時增強性能。Intel是從Willamette核心的Pentium 4開始支持SSE2指令集的,而AMD則是從K8架構(gòu)的SledgeHammer核心的Opteron開始才支持SSE2指令集的。
Intel指令集中SSE3(Streaming SIMD Extensions 3,Intel官方稱為SIMD 流技術(shù)擴展 3或數(shù)據(jù)流單指令多數(shù)據(jù)擴展指令集 3)指令集是Intel公司在SSE2指令集的基礎(chǔ)上發(fā)展起來的。相比于SSE2,SSE3在SSE2的基礎(chǔ)上又增加了13個額外的SIMD指令。SSE3 中13個新指令的主要目的是改進線程同步和特定應(yīng)用程序領(lǐng)域,例如媒體和游戲。這些新增指令強化了處理器在浮點轉(zhuǎn)換至整數(shù)、復(fù)雜算法、視頻編碼、SIMD浮點寄存器操作以及線程同步等五個方面的表現(xiàn),最終達到提升多媒體和游戲性能的目的。Intel是從Prescott核心的Pentium 4開始支持SSE3指令集的,而AMD則是從2005年下半年Troy核心的Opteron開始才支持SSE3的。但是需要注意的是,AMD所支持的SSE3與Intel的SSE3并不完全相同,主要是刪除了針對Intel超線程技術(shù)優(yōu)化的部分指令。
Intel指令集中SSE4 (Streaming SIMD Extensions 4) 是英特爾自從SSE2之后對ISA擴展指令集最大的一次的升級擴展。新指令集增強了從多媒體應(yīng)用到高性能計算應(yīng)用領(lǐng)域的性能,同時還利用一些專用電路實現(xiàn)對于特定應(yīng)用加速。IntelSSE4 由一套全新指令構(gòu)成,旨在提升一系列應(yīng)用程序的性能和能效。Intel SSE4 構(gòu)建于英特爾64指令集架構(gòu)(Intel64 ) (ISA)。Intel SSE4 是英特爾與其獨立軟件開發(fā)商 (ISV) 團體精誠合作的成果,它可以支持開發(fā)人員輕松改進產(chǎn)品,同時保持必要的應(yīng)用級兼容性,以適應(yīng)處理器不斷迭代的需求。
2. 并行計算有哪些實現(xiàn)方式?
解:并行計算就是在并行計算或分布式計算機等高性能計算系統(tǒng)上所做的超級計算。實現(xiàn)方式有:單指令多數(shù)據(jù)流SIMD、對稱多處理機SMP、大規(guī)模并行處理機MPP、工作站機群COW、分布共享存儲DSM多處理機。
3. 彩色圖像、灰度圖像、二值圖像和索引圖像區(qū)別?
解:彩色圖像,每個像素通常是由紅(R)、綠(G)、藍(B)三個分量來表示的,分量介于(0,255)。RGB圖像與索引圖像一樣都可以用來表示彩色圖像。與索引圖像一樣,它分別用紅(R)、綠(G)、藍(B)三原色的組合來表示每個像素的顏色。但與索引圖像不同的是,RGB圖像每一個像素的顏色值(由RGB三原色表示)直接存放在圖像矩陣中,由于每一像素的顏色需由R、G、B三個分量來表示,M、N分別表示圖像的行列數(shù),三個M x N的二維矩陣分別表示各個像素的R、G、B三個顏色分量。RGB圖像的數(shù)據(jù)類型一般為8位無符號整形,通常用于表示和存放真彩色圖像,當(dāng)然也可以存放灰度圖像。
灰度圖像(gray image)是每個像素只有一個采樣顏色的圖像,這類圖像通常顯示為從最暗黑色到最亮的白色的灰度,盡管理論上這個采樣可以任何顏色的不同深淺,甚至可以是不同亮度上的不同顏色。灰度圖像與黑白圖像不同,在計算機圖像領(lǐng)域中黑白圖像只有黑色與白色兩種顏色;但是,灰度圖像在黑色與白色之間還有許多級的顏色深度。灰度圖像經(jīng)常是在單個電磁波頻譜如可見光內(nèi)測量每個像素的亮度得到的,用于顯示的灰度圖像通常用每個采樣像素8位的非線性尺度來保存,這樣可以有256級灰度(如果用16位,則有65536級)。
二值圖像(binary image),即一幅二值圖像的二維矩陣僅由0、1兩個值構(gòu)成,“0”代表黑色,“1”代白色。由于每一像素(矩陣中每一元素)取值僅有0、1兩種可能,所以計算機中二值圖像的數(shù)據(jù)類型通常為1個二進制位。二值圖像通常用于文字、線條圖的掃描識別(OCR)和掩膜圖像的存儲。
索引圖像即它的文件結(jié)構(gòu)比較復(fù)雜,除了存放圖像的二維矩陣外,還包括一個稱之為顏色索引矩陣MAP的二維數(shù)組。MAP的大小由存放圖像的矩陣元素值域決定,如矩陣元素值域為[0,255],則MAP矩陣的大小為256Ⅹ3,用MAP=[RGB]表示。MAP中每一行的三個元素分別指定該行對應(yīng)顏色的紅、綠、藍單色值,MAP中每一行對應(yīng)圖像矩陣像素的一個灰度值,如某一像素的灰度值為64,則該像素就與MAP中的第64行建立了映射關(guān)系,該像素在屏幕上的實際顏色由第64行的[RGB]組合決定。也就是說,圖像在屏幕上顯示時,每一像素的顏色由存放在矩陣中該像素的灰度值作為索引通過檢索顏色索引矩陣MAP得到。索引圖像的數(shù)據(jù)類型一般為8位無符號整形(int8),相應(yīng)索引矩陣MAP的大小為256Ⅹ3,因此一般索引圖像只能同時顯示256種顏色,但通過改變索引矩陣,顏色的類型可以調(diào)整。索引圖像的數(shù)據(jù)類型也可采用雙精度浮點型(double)。索引圖像一般用于存放色彩要求比較簡單的圖像,如Windows中色彩構(gòu)成比較簡單的壁紙多采用索引圖像存放,如果圖像的色彩比較復(fù)雜,就要用到RGB真彩色圖像。
4. 常用邊緣檢測有哪些算子,各有什么特性?
解:常用邊緣檢測算子如下所述:
Sobel算子,其主要用于邊緣檢測,在技術(shù)上它是以離散型的差分算子,用來運算圖像亮度函數(shù)的梯度的近似值,?Sobel算子是典型的基于一階導(dǎo)數(shù)的邊緣檢測算子,由于該算子中引入了類似局部平均的運算,因此對噪聲具有平滑作用,能很好的消除噪聲的影響。Sobel算子對于象素的位置的影響做了加權(quán),與Prewitt算子、Roberts算子相比因此效果更好。Sobel算子包含兩組3x3的矩陣,分別為橫向及縱向模板,將之與圖像作平面卷積,即可分別得出橫向及縱向的亮度差分近似值。缺點是Sobel算子并沒有將圖像的主題與背景嚴格地區(qū)分開來,換言之就是Sobel算子并沒有基于圖像灰度進行處理,由于Sobel算子并沒有嚴格地模擬人的視覺生理特征,所以提取的圖像輪廓有時并不能令人滿意。
5.? 簡述BP神經(jīng)網(wǎng)絡(luò),AdBoost的基本原理?
解:BP神經(jīng)網(wǎng)絡(luò)模型處理信息的基本原理是:輸入信號Xi通過中間節(jié)點(隱層點)作用于輸出節(jié)點,經(jīng)過非線形變換,產(chǎn)生輸出信號Yk,網(wǎng)絡(luò)訓(xùn)練的每個樣本包括輸入向量X和期望輸出量t,網(wǎng)絡(luò)輸出值Y與期望輸出值t之間的偏差,通過調(diào)整輸入節(jié)點與隱層節(jié)點的聯(lián)接強度取值Wij和隱層節(jié)點與輸出節(jié)點之間的聯(lián)接強度Tjk以及閾值,使誤差沿梯度方向下降,經(jīng)過反復(fù)學(xué)習(xí)訓(xùn)練,確定與最小誤差相對應(yīng)的網(wǎng)絡(luò)參數(shù)(權(quán)值和閾值),訓(xùn)練即告停止。此時經(jīng)過訓(xùn)練的神經(jīng)網(wǎng)絡(luò)即能對類似樣本的輸入信息,自行處理輸出誤差最小的經(jīng)過非線形轉(zhuǎn)換的信息。
AdBoost是一個廣泛使用的BOOSTING算法,其中訓(xùn)練集上依次訓(xùn)練弱分類器,每次下一個弱分類器是在訓(xùn)練樣本的不同權(quán)重集合上訓(xùn)練。權(quán)重是由每個樣本分類的難度確定的。分類的難度是通過分類器的輸出估計的。
C/C++部分
1.? 關(guān)鍵字static的作用是什么?
解:1)在函數(shù)體,一個被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。2)在模塊內(nèi)(但在函數(shù)體外),一個被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù),它是一個本地的全局變量。3)在模塊內(nèi),一個被聲明為靜態(tài)的函數(shù)只可被這一模塊的它函數(shù)調(diào)用。那就是,這個函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
2. 嵌入式系統(tǒng)總是用戶對變量或寄存器進行位操作。給定一個整型變量a,寫兩段代碼,第一個設(shè)置a的bit3,第二消除a的 bit 3。在以上兩個操作中,要保持其它位不變.
解:
#define BIT3(0x1<<3) static int a; void set_bit3(void) {a|=BIT3; } void clear_bits(void) {a&=~BIT3; }3. 簡述C,C++程序編譯的內(nèi)存分配情況?
解:C,C++中內(nèi)存分配方式可以分為三種:
一個C、C++程序編譯時內(nèi)存分為5大存儲區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)和程序代碼區(qū)。
4. 給定一個矩陣intmaxtrixA[m][n],每行和每列都是增序的,實現(xiàn)一個算法去找矩陣中的某個元素element.
解:方法一:
#include<iostream> using namespace std; const int M = 4; const int N = 4; int main { int matrix[M][N] = {}; double element; int flag = 1; for(int j=0; j<N; j++) { if(matrix[i][j] == element) cout<<"位置"<<endl; while( flag<M && matrix[i][j]<element ) --flag; while( flag<M && matrix[i][j]>element ) ++flag; } } 方法二:bool Find(int *matrixA, int m, int n, int element) { bool found = false; if(matrixA != NULL & m & n) { int i,j; i=0;j=n-1; while(i<m;j>=0) { if(maxtrixA[i*n+j] == element) { found = true; break; } else if(matrix[i*n+j]>element --j; else ++i } } }
5. 從1到500的500個數(shù),第一次刪除奇數(shù)位,第二次刪除剩下來的奇數(shù)位,以此類推,最后剩下的唯一一位數(shù)是什么?
解:比如:1,2,刪除奇數(shù)位,那剩下的是2,1,2,3,刪除奇數(shù)位,剩下的是2,1,2,3,4,剩下的是4,1,2,3,4,5,6,7,剩下的是4,1,2,3,4,5,6,7,8 和1,2,3,4,5,6,7,8,9,10,11,12,13,14,15剩下的是8,這里有什么規(guī)律:就是當(dāng)1~n,2^i<n<2^(i+1)時候,這樣刪除剩下的是2^i。2^8<500<2^9,所以剩下的就是2^8=256。
6. 給出了一個n*n的矩形,編程求從左上角到右下角的路徑數(shù)(n > =2),限制只能向右或向下移動,不能回退。例如當(dāng)n=2時,有6條路徑。
解:一是利用數(shù)學(xué)知識,從左上角到右下角總共要走2n步,其中橫向要走n步,所以總共就是C2n~n。二是利用遞歸實現(xiàn)
int getTotalPath(int m, int n) { if(m == 1) return n + 1; if(n == 1) return m + 1; return getTotalPath(m-1, n) + getTotalPath(m, n-1); }
7. 給出一棵二叉樹的前序和中序遍歷,輸出后續(xù)遍歷的結(jié)果,假設(shè)二叉樹中存儲的均是ASCII碼。如前序:ABDHECFG,中序:HDBEAFCG,則輸出后序為:HDECFGCA,改正為:HDECFGBA,再次改正HDEBFGCA。
解:先利用前序和中序構(gòu)建出二叉樹,然后后序遍歷輸出結(jié)果
Node* getBinaryTree(char* preOrder, char* inOrder, int len) { if(preOrder == NULL || *preOrder == '\0' || len<=0) return NULL; Node* root = (Node*) malloc(sizeof(Node)); if(root == NULL) exit(EXIT_FAILURE); root->data = *preOrder; int pos = 0; while(true) { if(*(inOrder+pos) == root->data) break; pos++; } if(pos == 0) root->lchild = NULL; else root->lchild = getBinaryTree(preOrder+1, inOrder, pos); if(len-pos-1 == 0) root->rchild = NULL; else root->rchild = getBinaryTree(preOrder+pos+1, inOrder+pos+1,len-pos-1); return root; } void postOrder(Node* root) { if(root == NULL) return; postOrder(root->lchild); postOrder(root->rchild); printf("%c", root->data); } void printPostOrderViaPreOrderAndInorder(char* preOrder, char* inOrder) { Node* root = getBinaryTree(preOrder, inOrder, strlen(preOrder)); postOrder(root); }
8.自定義實現(xiàn)字符串轉(zhuǎn)為整數(shù)的算法,例如把“123456”轉(zhuǎn)成整數(shù)123456.(輸入中可能存在符號,和數(shù)字)
解:
enum Status {VALID,IN_VALID}; int gStatus = VALID; int strToInt(const char* str) { long long result = 0; gStatus = IN_VALID; if(str != NULL) { const char* digit = str; bool minus = false; if(*digit == '+') digit++; else if(*digit == '-'){ digit++; minus = true; } while(*digit != '\0') { if(*digit >= '0' && *digit <= '9'){ result = result * 10 + (*digit -'0'); if(result > std::numeric_limits<int>::max()){ result = 0; break; } digit++; } else { result = 0; break; } } if(*digit == '\0'){ gStatus = VALID; if(minus) result = 0 - result; } } return static_cast<int>(result); }9. 求2個字符串最長公共部分
解:方法一:2個循環(huán),遍歷2個字符串,這里記得要回溯,2個字符串都要有,否則,找不出來正確的結(jié)果。
int main(){char a[80],b[80],c[80],d[500][80]; memset(c, 0, 80);int i,j,m,n,t,k; gets(a); gets(b);//輸入字符串 puts(a); puts(b);//輸出字符串 m=strlen(a); n=strlen(b);//計算字符串實際長度 int nFlag = 0;k = 0;int nTemp = 0;for(i=0;i<m;i++){nFlag = 0;t=0; nTemp = i;for(j=0;j<n;j++){ if(a[i]==b[j]){ nFlag = 1; c[t]=a[i]; t=t+1; i=i+1; //j=j+1; }else{if (nFlag == 1){strcpy(d[k++], c);memset(c, 0, 80);nFlag = 0;t=0;i = nTemp;j=j-1;}}} if (nFlag == 1){strcpy(d[k++], c);memset(c, 0, 80);i = nTemp;}}strcpy(c,d[0]);for(i=1;i<k-1;i++){ if(strlen(c)<strlen(d[i])) strcpy(c,d[i]);//如果d[i]字符串長度比c長就把d[i]中的字符串復(fù)制給c } puts(c); return 0; } 方法二
//最長公共子序列字符個數(shù) //c[i][j]保存字符串 {xi},{yj},(長度分別為i,j)的最長公共子序列的字符個數(shù) //i=0或者是j=0 時,c[i][j]必定為零, i,j>=0 且 xi=yj, c[i][j]=c[i-1][j-1]+1 //若 i,j>0 但xi!=yj, c[i][j]=max{ c[i-1][j] , c[i][j-1] } #include <stdio.h> #include <string.h> int c[1001][1001]; void lcs(int a, int b, char x[], char y[], int c[][1001]){ int i,j; for(i=1;i<a;i++) c[i][0]=0; //if b==0, set c[i][j]=0; for(i=1;i<b;i++) c[0][i]=0; // if a==0; set c[i][j]=0; for(i=1;i<=a;i++) // if a!=0,b!=0 loop for(j=1;j<=b;j++){ if(x[i-1]==y[j-1]) c[i][j]=c[i-1][j-1]+1; else if (c[i-1][j]>=c[i][j-1]) c[i][j]=c[i-1][j]; else c[i][j]=c[i][j-1]; } } int main() { char x[1001],y[1001]; while ( scanf("%s%s",x,y)!=EOF ){ int a=strlen(x); int b=strlen(y); memset(c,0,sizeof(c));lcs(a,b,x,y,c);printf("%d\n",c[a][b]);} return 0; }
10.請實現(xiàn)一個函數(shù):最長順子。輸入很多個整數(shù)(1<=數(shù)值<=13),返回其中可能組成的最長的一個順子(順子中數(shù)的個數(shù)代表順的長度); 其中數(shù)字1也可以代表14;
順子包括單順\雙順\3順;單順的定義是連續(xù)5個及以上連續(xù)的數(shù),比如1,2,3,4,5、3,4,5,6,7,8和10,11,12,13,1等; 雙順的定義是連續(xù)3個及以上連續(xù)的對(對:兩個相同的數(shù)被稱為對),比如1,1,2,2,3,3、4,4,5,5,6,6,7,7和11,11,12,12,13,13,1,1等; 3順的定義是連續(xù)2個及以上連續(xù)的3張(3張:3個相同的數(shù)被稱為3張),比如1,1,1,2,2,2、3,3,3,4,4,4,5,5,5,6,6,6和13,13,13,1,1,1等等;比如:輸入數(shù)組[1,5,2,3,4,4,5,9,6,7,2,3,3,4], 輸出數(shù)組[2,2,3,3,4,4,5,5]。
解:實現(xiàn)代碼如下:
int putList(int k, map<int, map<int, int>* >& listData, map<int, int>* mapData){ int nFlag =0;if (0 == k && mapData->size() >= 5){ nFlag =1;//listData.put(mapData.size(), mapData); listData.insert(pair <int, map<int, int>* >( mapData->size(), mapData));} if (1 == k && mapData->size() >= 3){ nFlag =1;//listData.put(2 * mapData.size(), mapData); listData.insert(pair <int, map<int, int>* >(2* mapData->size(), mapData));} if (2 == k && mapData->size() >= 2){ nFlag =1 ;//listData.put(3 * mapData.size(), mapData); listData.insert(pair <int, map<int, int>* >( 3*mapData->size(), mapData));} return nFlag; }map<int, int>* getList(int* count, int k, int num, int& nMaxCount){ map<int, map<int, int>* > listData;//= new map<int, map<int, int>*>(); map<int, int>* mapTemp = NULL; int flag = 0; int nRet = 0;for (int i = 1; i < num; i++){ if (count[i] > k && flag == 0){ flag = 1; mapTemp = new map<int, int>;//mapTemp.put(i, count[i]); mapTemp->insert(pair <int, int>( i, count[i]));} else if (count[i] > k && flag == 1) { //mapTemp.put(i, count[i]); mapTemp->insert(pair <int, int>( i, count[i]));if (13 == i){ if (count[14 - i] > k) { //mapTemp.put(14 - i, count[14 - i]); mapTemp->insert(pair <int, int>( 14 - i, count[14 - i]));nRet = putList(k, listData, mapTemp); if (nRet==0){delete mapTemp;mapTemp = NULL;}} else { flag = 0; nRet=putList(k, listData, mapTemp); if (nRet==0){delete mapTemp;mapTemp = NULL;}} } } else if (count[i] <= k && flag == 1){ flag = 0; nRet=putList(k, listData, mapTemp); if (nRet==0){delete mapTemp;mapTemp = NULL;}} } if (listData.size() > 0){listData.rend();map<int, map<int, int>* >::iterator it = listData.begin();nMaxCount = (*it).first;map<int, int>* mapReturn = (*it).second;map<int, int>* maptemp;it++;for (; it!=listData.end(); it++){maptemp = (*it).second;delete maptemp;maptemp = NULL;}return mapReturn;}else return NULL; } int* GetLongeststr(int* array, int nCount, int& outCount, int MaxNum){int* count = new int[MaxNum+1]; memset(count, 0, MaxNum*sizeof(int));int nMaxLoop=0;int nMaxTemp;int nMax1Loop=0;int nMax2Loop=0;int nMax3Loop=0;int nMaxkey =0;for (int i = 0; i < nCount; i++){ if (array[i] < 1 || array[i] > MaxNum) return NULL; ++count[array[i]];}map<int, map<int, int>*> allList;map<int, int>* mapTemp = NULL; map<int, int>* map1Temp = NULL;map<int, int>* map2Temp = NULL;map<int, int>* map3Temp = NULL;for (int k = 0; k < 3; k++){ mapTemp = getList(count, k, MaxNum, nMaxTemp);if (NULL != mapTemp){ if (0 == k) {map1Temp = mapTemp;nMax1Loop = nMaxTemp;nMaxLoop=nMaxTemp;}else if (1 == k){if (nMaxTemp>=nMaxLoop) {map2Temp = mapTemp;nMax2Loop = nMaxTemp;nMaxLoop = nMaxTemp;}else{delete mapTemp;mapTemp =NULL;}}else{if (nMaxTemp>=nMaxLoop) {map3Temp = mapTemp;nMax3Loop = nMaxTemp;nMaxLoop = nMaxTemp;}else{delete mapTemp;mapTemp =NULL;}}} }delete[] count;count = NULL;if (nMaxLoop>0) {if (nMaxLoop == nMax3Loop){nMaxkey = 3;mapTemp = map3Temp;}else if (nMaxLoop == nMax2Loop) {nMaxkey = 2;mapTemp = map2Temp;}else{nMaxkey = 1;mapTemp = map1Temp;}outCount = nMaxLoop;int* result = new int[outCount]; int k; int nAllCount = 0;map<int, int>::iterator itorResult;for (itorResult = mapTemp->begin(); itorResult!=mapTemp->end(); itorResult++){k = itorResult->first;for (int j =0; j<nMaxkey; j++){ result[nAllCount++] = k; cout << itorResult->first <<",";}}cout << endl;if (map1Temp!=NULL){delete map1Temp;map1Temp = NULL;}if (map2Temp!=NULL){delete map2Temp;map2Temp = NULL;}if (map3Temp!=NULL){delete map3Temp;map3Temp = NULL;}return result;}else {outCount = 0;return NULL;} }
關(guān)于Image Engineering & Computer Vision的更多討論與交流,敬請關(guān)注本博和新浪微博songzi_tea.
總結(jié)
以上是生活随笔為你收集整理的图像处理职位面试题汇总(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【专题】莫比乌斯反演
- 下一篇: 莫比乌斯函数