程式設計珠璣學習筆記 第一章

2021-07-10 21:45:36 字數 2960 閱讀 7416

def

fast_generate

(n,k):

random_list =

x = [i for i in range(0,n)]

for i in range(0,k):

t = int(random()*(n-i)+i)

x[i],x[t] = x[t],x[i]

return random_list

這是乙個o(k)效率的巧妙演算法,我自己的思路是將所有沒有選作隨機數的加入到乙個集合裡面,然後從這個集合找隨機數,開始每找到乙個隨機數,就從集合裡面刪除.但是刪除這個操作也是很消耗時間的,對於乙個list,刪除的效率與元素位置有關,越靠近末尾消耗時間越少.但是逆序刪除乙個元素的效率是o(n)!!!而在c/c++裡面,如果我們使用陣列儲存資料,就不能執行刪除操作了.

所以上面這個演算法的巧妙之處在於通過交換間接的執行了刪除的效果.而交換是乙個常數時間的操作.

[5]習題5,進行兩次排序,分別解決0-4999999,和5000000-100000000的排序.

下面的**對分兩趟進行排序

class

bit_vector

(object):

def__init__

(self):

self.__vector =

self.__shift = 5

self.__mask = 0x1f

defset

(self,i):

self.__vector[i>>self.__shift] |= 1

<<(i&self.__mask)

deftest

(self,i):

return self.__vector[i>>self.__shift] & 1

<<(i&self.__mask)

defclc(self,max):

self.__vector = [0]*(1+max//self.__mask)

defsort

(self,l,min,max):

print('*'*10,'start sorting')

self.clc(max-min)

for item in l:

self.set(item-min)

for i in range(min,max+1):

if(self.test(i-min)):print(i)

start = time.clock()

random = fast_generate(10000000,20)

sort_vec = bit_vector()

sort_vec.sort([i for i in random if i<5000000],0,5000000)

sort_vec.sort([i for i in random if i>=5000000],5000000,10000000)

end = time.clock()

print(end-start)

解決方法是用4位來表示乙個數,最多可以表示15次重複出現.
class

bit_vector

(object):

def__init__

(self):

self.__vector =

self.__shift = 0b11

self.__mask = 0b111

defset

(self,i):

self.__vector[i>>self.__shift] += 1

<<(i&self.__mask)*4

deftest

(self,i):

return self.__vector[i>>self.__shift] & 0b1111

<<(i&self.__mask)*4

defdec

(self,i):

self.__vector[i>>self.__shift] -= 1

<<(i&self.__mask)*4

defclc

(self,max):

self.__vector = [0]*(1+max//self.__mask)

defsort

(self,l,min,max):

print('*'*10,'start sorting')

self.clc(max-min)

for item in l:

self.set(item-min)

for i in range(min,max+1):

while(self.test(i-min)):

print(i)

self.dec(i)

或者:

1、首先掃瞄整個檔案,看有哪個免費號碼字首。以及每個免費號碼字首下的號碼個數。

2、設定區間對映表:比如800字首有125個免費號碼,找到最大的數,與最小的數,差值做為該索引下的位數.這種方法比較節省空間.

排序:分多次(字首個數)讀入檔案排序是可以的,還可以分兩次讀入資料,然後先做兩次排序,然後進行歸併.這裡的歸併稍微特殊一點,先比較字首再看是否需要比較後面7位.

data[i] = 1;

from[i] = top;

to[top++] = i;

這個**是什麼意思呢?

首先我們要檢測乙個位置是不是被初始化了(訪問了),可以檢視from[i] 中的值,這裡有幾個判斷:首先from[i]from[i]>=0,這個語句的意思是,from[i]至少不是負數的隨機值且對應的to肯定被處理過,保證訪問to的時候不會出錯,現在有兩種情況,from[i]如果不是隨機值,那麼data[i]就被訪問(賦值)過了.所以關鍵是判斷是不是隨機值,這就看to[from[i]]==i了,如果from[i]是乙個隨機值,那麼to[from[i]]就不可能等於i了.因為i根本就沒有被放入to這個向量裡面.

《程式設計珠璣》第一章筆記

文章從乙個實際的問題開始 乙個 系統,7位數的 號碼,用1mb的記憶體空間將這些 號碼排序。分析 如果將這些 號碼看成int型別的整數,將其讀入記憶體中進行排序,int型別4個位元組,最多有10000000個 號碼,則需要40mb的記憶體空間,遠遠超出題目的要求,但是這10000000個資料有他們的...

程式設計珠璣第一章

原文中的問題 如何在1mb的空間裡面對一千萬個整數進行排序?並且每個數都小於1千萬。實際上這個需要1.25mb的記憶體空間。1mb總共有838,8608。所以估計也可以在1mb左右的空間裡面進行排序了。include include define bitsperword 32 define shif...

程式設計珠璣第一章

下午看完程式設計珠璣第一章,感覺很不錯!如作者所說 閱讀本書乙個提示,不要太快,一次閱讀一章。集中精力思考,解答課後習題。寫總結就是在剛弄懂的時候,這時候是最恰當的時候,最容易接受。題目要求 乙個最多含有1000萬個整數的檔案,整數沒有重複,請輸出公升序排列。約束 最多1m記憶體,時間10s。題目很...