題目:在2.5億個整數中,找出不重複的整數(注,內存不足以容納這2.5億個整數)。
構建測試數據
# 構建一個測試數據集:隨機生成10000個(-20000, 20000)的整數,以字符串格式存入bigdata中
import random
for i in range(10000):
with open('bigdata', 'a') as file:
file.write(str(random.randint(-20000, 20000)) + '\n')
方法一(內存充足):用python字典結構:
返回頂部
在內存充足的情況下,使用python中的字典結構。
對2.5億個數中的每一個數,出現一次,字典對應的值+1。
最後遍歷字典,找出value爲1的所有key。
int_dict = {} # 整數字典,整數爲key,次數爲value
def dict_int():
with open('bigdata') as file:
for str_in in file:
num = str_in.replace('\n', '')
if num not in int_dict: # 第一次出現
int_dict[num] = 1
else:
int_dict[num] += 1
with open('bigdata') as file:
for str_in in file:
num = str_in.replace('\n', '')
if int_dict[num] == 1: # 返回一個不重複整數的迭代器
yield num
if __name__ == '__main__':
unique_list = list(dict_int())
print('不重複整數個數:', len(unique_list))
不重複整數個數: 7875
前10個不重複整數
print('前10個不重複整數:', unique_list[:10])
前10個不重複整數: [-3421, -1349, -6778, 16932, 14847, -1504, 15398, 12612, -8009, -1250]
方法二(內存不足):用bool數組:
返回頂部
初始化一個(2.5*10^8) * 2 bool數組,並且初始化爲False,對於每一個整數。
使用兩個bit,來表示它出現的次數:
0 0:出現0次
0 1:出現一次
1 1:出現多次
import numpy as np
mark =np.zeros((25*(10**7), 2), dtype=np.bool)
存放(2.5*10^8) * 2 bool數組,需要0.47 G 內存
print('(2.5*10^8) * 2 bool數組的大小:',round(mark.size/1024**3, 2), 'G內存')
(2.5*10^8) * 2 bool數組的大小: 0.47 G內存
def get_unique_int():
with open('bigdata') as file: # bigdata:原始的2.5億個整數大文件
for str_in in file:
num = int(str_in)
if mark[num][0] == False and mark[num][1] == False: # 這個數第一次出現。賦值 0 1
mark[num][0] = False
mark[num][1] = True
else:
mark[num][0] = True # 出現了不止一次的數據,賦值 1 1
mark[num][1] = True
with open('bigdata') as file:
for str_in in file:
num = int(str_in)
if mark[num][0] == False and mark[num][1] == True: # 判斷只出現一次,即值爲 0 1
yield num
if __name__ == '__main__':
unique_list = list(get_unique_int())
print('不重複整數個數:', len(unique_list))
不重複整數個數: 7875
前10個不重複整數
print('前10個不重複整數:', unique_list[:10])
前10個不重複整數: [-3421, -1349, -6778, 16932, 14847, -1504, 15398, 12612, -8009, -1250]
總結:
兩種思路殊途同歸,用字典結構可能存不下2.5億個結果;用bool數組,只需要0.5 G 左右的內存。
歡迎關注,敬請點贊!
返回頂部