习题6.2: (a) 大整数分解:假设需要多次计算大整数分解因子。首先可以利用筛法计算出一部分较小素数(2-m),然后存储起来。然后利用这些素数对大整数进行分解,将大整数变成一个相对较小的数。然后继续利用筛法和已有的素数计算新的素数序列(m-km),不断重复上面的过程,直到该数自己小于下一个素数。伪代码如下:
compute the base_primes
def f(n,primes)
for each in base_primes:
while 1:
t =n/each
if t is not integer:break
output each
n = t# update t
if n < each:
output n#n is the last prime
return
compute the next_primes and add it to base_primes
f(n,nextprimes)#call the function recursively using new base_primes and new n
代码如下:
#compute the base_primes
base_primes = [2,3,5,7,11,13,17,19]
def test(f,randargs,case=10):
import time,random
start = time.time()
for i in range(case):
f(randargs())
end = time.time()
print(end-start)
def compute_primes(k = 1.5):
global base_primes
next_primes = list(range(base_primes[-1]+2,int(k*(base_primes[-1])),2))
for each in base_primes:
temp = []
for it in next_primes:
if it%each!=0 :temp.append(it)
next_primes = temp
if next_primes==[]:return []
next_prime = min(next_primes)
ans = [next_prime]
base_primes.append(next_prime)
for each in ans:
temp=[]
for it in next_primes:
if it%each!=0:temp.append(it)
if temp==[]:break
next_primes = temp
m = min(next_primes)
ans.append(m)
base_primes.append(m)
return ans
def f(n,primes = base_primes):
for each in primes:
while 1 :
if n%each!=0:break
#print(each)
n //=each # update t
if n < each:
if n != 1:print(n)#n is the last prime
#print('*'*10)
return
#compute the next_primes and add it to base_primes
x = min(int(primes[-1]*1.5),n)
#if x-primes[-1] < 1000:
f(n,compute_primes(x))#call the function recursively using new base_primes and new n
#else:
# direct_func(n,primes[-1]+2)
import random
test(f,lambda:random.randint(2**10,2**17),case=50)
该方法的瓶颈在于计算新的素数序列消耗太大。存储已有的素数序列可以在大整数比较多的时候起到加速作用。但是这种方法对于提高计算单个case是没有帮助的,用普通的办法肯定不能计算500位。pollard-rho质数分解算法可以帮助我们,但是具体的实现我就没有去做了,这只是提供了算法层面上提高速度的思路。
另外使用test函数来辅助测试耗时。
(b) 查找字符串:
首先从算法层面采取KMP算法,伪代码如下:
def compute_matches:
pass
def match(str,text):
str_len = len(str)
text_len = len(text)
pos = 0
while pos+str_len<=text_len:
test if str mathces text from pos
length = the length of matching substr
if success:return pos
else pos += matches[length]
return -1
具体实现见该博文:
http://blog.youkuaiyun.com/pp634077956/article/details/51864103