寻找质数(prime number)

-- TOC --

如果一个正整数,它只能被1和它自己整除,那么,它就是一个质数,也称为素数,英文叫prime number。

下面这个算法的思路是我昨天中午午休时睡不着,突然灵机一动的成果。

如果\(N \neq 2 \cdot M\),那么在\((\left\lceil\frac{N}{2}\right\rceil,N)\)这个区间内,不存在因数。

假设在上述区间存在一个因数,那么这个因数一定是\(\frac{N}{2}\),矛盾。

如果\(N \neq 3 \cdot M\),那么在\((\left\lceil\frac{N}{3}\right\rceil,N)\)这个区间内,不存在因数。

假设在上述区间存在一个因数,那么这个因数一定是\(\frac{N}{3}\),矛盾。

按照这个思路,代码每尝试一个数是否为因数,后续尝试的范围就会缩小。

当一个数不能被2整除的时候,其实我们是没有必要再用4来做整除测试,4不是质数。代码在使用某个数做整除判断的时候,可以只使用前面已经判断出来的,较小的质数。

结合以上两点,可以写出一个较快的寻找质数的算法。

我写的Python版本,如下:

$ cat test_prime.py
import sys


print(2)
print(3)
print(5)
pn = [5]
i = 5
while True:
    i += 2  # skip even number
    # check if can ben divided by 3
    if sum(list(map(int,list(str(i))))) % 3 == 0:
        continue
    idx = -1
    pn_len = len(pn)
    found = False
    while True:
        idx += 1
        if idx == pn_len or pn[idx] > i//pn[idx]:
            found = True
            break
        if i%pn[idx] == 0:
            break
    if found:
        pn.append(i)
        print(i)
        # stupid check
        for j in range(2, i):
            if i%j == 0:
                print('bad algo...')
                sys.exit(1)
    else:
        # stupid check
        for j in range(2, i):
            if i%j == 0:
                break
        else:
            print('bad algo... omit', i)
            sys.exit(2)

这个算法跑得挺快的,但如果一直运行下去,最终pn这个list会吃掉所有的内存。可以不适用pn这个list,即不记录前面已经找到的质数,用一个循环+1的变量来做除法判断。把这个算反的一部分抠出来,可以实现快速判断某一个数是否为质数的接口,但是不要使用pn这个list。

本文链接:https://cs.pynote.net/ag/202207161/

-- EOF --

-- MORE --