程式設計題彙總3

2021-08-02 09:14:29 字數 2637 閱讀 3401

1. 請寫出c/c++語言實現矩陣乘法加速的常用方法

for(i=0;i

i) for(j=0;j

j){ sum=0;

for(k=0;k

但是考慮了快取記憶體的問題後,其實有一種更好的實現方式:

for(i=0;i

i) for(k=0;k{

r=a[i][k];

for(j=0;j

細看一番就會發現這兩種實現語義是等價的,但是後者的實際執行效率卻比前者高。

那為什麼會如此呢?

那是因為cpu讀資料時,並不是直接訪問記憶體,而是先檢視快取中是否有資料,有的話直接從快取讀取。而從快取讀取資料比從記憶體讀資料快很多。

當資料不在快取中時,cpu會將包含資料在內的乙個資料塊讀到快取,如果程式具有良好空間區域性性,那麼第一次cache miss後,之後的幾次資料訪問就可以直接在快取中完成。除了空間區域性性(程式傾向於引用與當前資料鄰近的資料)之外,還有時間區域性性(程式傾向於引用最近被引用過的資料)。

回到矩陣乘法。(我們只考慮內迴圈)

前者對矩陣a,有良好的空間區域性性,假設一次能快取四個元素,則每次迭代對於a只有0.25次miss,但是對於b,則不然,因此b是按列訪問的,每次訪問都會miss,因此每次迭代總的miss數是1.25。

後者對於矩陣c和矩陣b都有良好的區域性性,每次迭代都只有0.25詞miss,因此總的miss數是0.5。後者每次迭代多了一次儲存(對c[i][j]寫入),但是即便如此,後者的執行效率也比前者高。

總而言之,要想程式跑得快,就要在程式中多利用區域性性,讓快取hold住你的資料,減少訪存次數。要知道cpu可以在3個時鐘週期內訪問到l1 cache,10個時鐘週期左右的時間訪問到l2 cache。訪問記憶體卻要上百個時鐘週期,孰快孰慢,很清楚了吧?

2. 找到乙個陣列中出現頻率超過12

的數,要求時間複雜度o(

n),空間複雜度o(1)

主要想法是用乙個計數器c和乙個變數v,首先將陣列的第乙個數給變數賦值v,並給計數器+1,此後如果讀到相同的數則計數器+1,如果計數器的值小於0則將,剛讀入的數賦值給變數v,並重複操作,最後變數v的值便是陣列中頻率超過12

的數。如果題目中沒指出陣列中一定存在超過12

頻率的數的話,則再將陣列掃瞄一遍,看值等於v的元素數量是否大於陣列數量的一半。

python實現**如下:

if __name__ == '__main__':

a = [1,3,4,3,3,7,3,11,3]

count = 1

value = a[0]

for i in xrange(1,len(a)):

if a[i] == value:

count += 1

else:

count -= 1

if count < 0:

count = 1

value = a[i]

count = 0

for i in xrange(0, len(a)):

if a[i] == value:

count +=1

if count > len(a)/2:

print value

3. 找到乙個陣列中出現頻率超過13

的數,要求時間複雜度o(

n),空間複雜度o(1)

此題和上一題類似,主要思想是利用兩個計數器和兩個變數,首先先將陣列的前兩個數讀入變數,知道讀到相同的數則對應的計數器加一,否則讀到非兩個變數中的數則兩個計數器同時減去1,如果計數器的值小於0則將,剛讀入的數賦值給變數,並重複操作,最後變數中的值便是陣列中頻率超過13

的數。和上一題類似就不貼**了。

4.二分查詢,要求找到陣列中第乙個滿足要求的數

這個沒什麼好解釋的,微軟的程式設計之美上有提到,但是其中起到的第乙個改進方法即midindex = maxindex + (maxindex - minindex)/2,如果用python寫的話就不用考慮這點了,因為python隨便賦多大值都不會有越界錯誤。
def

bisearch_left

(array, target_value):

max_index = len(array) - 1

min_index = 0

while min_index < max_index-1: #當搜尋範圍只有兩個數停止

mid_index = (max_index + min_index)/2

if target_value <= array[mid_index]: #取等號保證取index較小的數

max_index = mid_index

else:

min_index = mid_index

if array[min_index] == target_value:

return min_index

elif array[max_index] == target_value:

return max_index

else:

return -1;

程式設計題彙總4

本部分主要是機器學習的題目 1.神經網路訓練時使用dropout主要目的是什麼?訓練和測試時使用的區別是什麼 2.深度學習解決過擬合和欠擬合的策略都有哪些?過擬合 data augmentation。人工增加訓練集的大小.通過平移,翻轉,加雜訊等方法從已有資料中創造出一批 新 的資料.regular...

Python刷題彙總3

利用map和reduce編寫乙個str2float函式,把字串 123.456 轉換成浮點數123.456 from functools import reduce 123.456 digits defstr2float s defchar2num s return digits s n s.ind...

筆試程式設計題彙總 2

描述 給乙個整數陣列num,和乙個鎮整數k,能否把陣列num切成k個子集,且各個子集的和相等,返回布林型別 輸入輸出 輸入 乙個整數陣列num和乙個正整數k 輸出 返回true或者false,bool型別 樣例 輸入 4,3,2,3,5,2,1 4 輸出 true 解釋 可以分解為4個子集,他們的和...