Last active
May 15, 2017 12:52
-
-
Save nishidy/d761ba5feed5629988773e58c31014f2 to your computer and use it in GitHub Desktop.
Find common list in three lists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from random import random | |
import time | |
import sys | |
def findCommon_NNN(A,B,C): | |
if 1000<len(A) or 1000<len(B) or 1000<len(C): | |
print("# This may be huge input for this function with O(N^3). Exit.") | |
return [] | |
common = [] | |
for a in A: | |
for b in B: | |
for c in C: | |
if a==b and b==c: | |
if a not in common: | |
common.append(a) | |
return common | |
def findCommon_N(A,B,C): | |
i=j=k=0 | |
common = [] | |
while i<len(A) and j<len(B) and k<len(C): | |
if A[i]==B[j] and B[j]==C[k]: | |
common.append(A[i]) | |
m = min(A[i],B[j],C[k]) | |
if A[i]==m: | |
i+=1 | |
if B[j]==m: | |
j+=1 | |
if C[k]==m: | |
k+=1 | |
return common | |
def binary_search(C,n): | |
s=0 | |
e=len(C)-1 | |
if C[s]==n or C[e]==n: return True | |
m=int((s+e)/2) | |
while s<m and m<e: | |
if C[m]==n: return True | |
if C[m]<n: | |
s=m | |
else: | |
e=m | |
m=int((s+e)/2) | |
return False | |
def findCommon_N_L_BS(A,B,C): | |
i=j=0 | |
common = [] | |
while i<len(A) and j<len(B): | |
if A[i]==B[j]: | |
common.append(A[i]) | |
m = min(A[i],B[j]) | |
if A[i]==m: | |
i+=1 | |
if B[j]==m: | |
j+=1 | |
common2 = [] | |
for c in common: | |
if binary_search(C,c): | |
common2.append(c) | |
return common2 | |
def findCommon_N_L(A,B,C): | |
i=j=0 | |
common = [] | |
while i<len(A) and j<len(B): | |
if A[i]==B[j]: | |
common.append(A[i]) | |
m = min(A[i],B[j]) | |
if A[i]==m: | |
i+=1 | |
if B[j]==m: | |
j+=1 | |
common2 = [] | |
for c in common: | |
if c in C: | |
common2.append(c) | |
return common2 | |
def make_seqs(n): | |
i=0 | |
seq = [] | |
while len(seq)<n: | |
if int(random()*2)<1: | |
seq.append(i) | |
i+=1 | |
return seq | |
def make_seqs_sparse(n): | |
i=0 | |
seq = [] | |
while len(seq)<n: | |
if int(random()*10)<1: | |
seq.append(i) | |
i+=1 | |
return seq | |
if __name__ == "__main__": | |
if 1 < len(sys.argv): | |
n = int(sys.argv[1]) | |
else: | |
n = 10 | |
print("Preparing data...") | |
A = make_seqs(n) | |
B = make_seqs(n) | |
C = make_seqs(n) | |
print("Preparing data for sparse one...") | |
A_ = make_seqs_sparse(n) | |
B_ = make_seqs_sparse(n) | |
C_ = make_seqs(n*10) | |
if len(A)<=10:print(A) | |
if len(B)<=10:print(B) | |
if len(C)<=10:print(C) | |
print("### Try normal sequence first and then try sparse one.") | |
for data in [[A,B,C], [A_,B_,C_]]: | |
pre_commons=[] | |
commons=[] | |
for f in [findCommon_NNN,findCommon_N,findCommon_N_L_BS,findCommon_N_L]: | |
s = time.time() | |
commons = f(*data) | |
e = time.time() | |
print("{:>20} : {:.2f} sec".format(f.__name__,(e-s))) | |
if pre_commons != []: | |
if not pre_commons==commons: | |
print("The result should be same.") | |
print(*data) | |
print(pre_commons) | |
print(commons) | |
exit(-1) | |
pre_commons = commons.copy() | |
print(commons if len(commons)<100 else "" ) | |
Author
nishidy
commented
May 15, 2017
•
$ python find_common.py 100000
Preparing data...
Preparing data for sparse one...
### Try normal sequence first and then try sparse one.
# This may be huge input for this function with O(N^3). Exit.
findCommon_NNN : 0.00 sec
findCommon_N : 0.19 sec
findCommon_N_L_BS : 0.52 sec
findCommon_N_L : 57.09 sec
# This may be huge input for this function with O(N^3). Exit.
findCommon_NNN : 0.00 sec
findCommon_N : 0.57 sec
findCommon_N_L_BS : 0.24 sec
findCommon_N_L : 95.91 sec
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment