数据结构和算法 数论 素数/质数、回文素数

 一、素数概述

        素数是初等数论中重点研究的对象,早在公元前300年,当时古希腊著名数学家欧几里得发现了数论的本质是素数。欧几里得在其著作《几何原本》中证明了素数具有无穷多个。

        素数又称为质数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数。比1大,但不是素数的称为合数。0和1既不是素数也不是合数。

        素数的分布没有很明显的规律,仍然有很多伟大的数学家对其进行研究。例如,最早的欧几里得、17世纪法国的费尔马、法国的梅森等。

        谈到素数,有著名的算术基本定理:任何一个大于1的正整数n,可以唯一表示成有限个素数的乘积。

        围绕着素数,数学家提出了各种猜想,内容如下。

        ・黎曼猜想:黎曼研究发现,素数分布的绝大部分猜想都取决于黎曼zeta函数的零点位置。黎曼在此基础上,猜想那些非平凡零点都落在复平面中实部为1/2的直线上。

        ・孪生素数猜想:对于素数n,如果n+2同样为素数,则称n和n+2为孪生素数。到底有没有无穷多个孪生素数呢?这是一个至今仍无法解决的问题。

        ・哥德巴赫猜想:哥德巴赫通过大量的数据猜测,所有不小于6的偶数,都可以表示为两个奇素数之和。后人将其称为“1+1”。并且,对于每个不小于9的奇数,都可以表示为三个奇素数之和。哥德巴赫猜想是数学中的璀璨明珠,至今仍无实质性进展。

        近年来,素数在密码学上也有相应的应用。基于大的素数质因数分解的复杂性,从而构造出广泛应用的公钥密码。这是现代密码学的基础。

1、查找素数方法一

        计算步骤

        1、如果整数小于等于 1,则返回 False。
        2、如果给定的数字可以被从 2 到 n 的任何数字整除,则函数将返回 False
        3、否则它将返回 True

        这是一种简单的方法,但需要很长时间才能运行。

import time
def is_prime(n):
	if n <= 1:
		return False
	for i in range(2,n):
		if n % i == 0:
			return False
	return True

# Driver function
t0 = time.time()
c = 0 #for counting

for n in range(1,100000):
	x = is_prime(n)
	c += x
print("Total prime numbers in range :", c)

t1 = time.time()
print("Time required :", t1 - t0)

2、查找素数方法二

        计算步骤

        1、如果整数小于等于 1,则返回 False。
        2、现在,我们将需要检查的数字减少到给定数字的平方根。
        3、如果给定的数字可以被从 2 到该数字的平方根的任何数字整除,则该函数将返回 False
        4、否则它将返回 True

import math
import time
def is_prime(n):
	if n <= 1:
		return False

	max_div = math.floor(math.sqrt(n))
	for i in range(2, 1 + max_div):
		if n % i == 0:
			return False
	return True

# Driver function
t0 = time.time()
c = 0 #for counting

for n in range(1,100000):
	x = is_prime(n)
	c += x
print("Total prime numbers in range :", c)

t1 = time.time()
print("Time required :", t1 - t0)

3、查找素数方法三

        计算步骤
        1、如果整数小于等于 1,则返回 False。
        2、如果数字等于 2,它将返回 True。
        3、如果数字大于 2 且可被 2 整除,则返回 False。
        4、4现在,我们检查了所有偶数。现在,寻找奇数。
        5、如果给定的数字可以被从 3 到该数字的平方根之间的任何数字整除,跳过所有偶数,该函数将返回 False,否则它将返回 True

import math
import time
def is_prime(n):
	if n <= 1:
		return False
	if n == 2:
		return True
	if n > 2 and n % 2 == 0:
		return False

	max_div = math.floor(math.sqrt(n))
	for i in range(3, 1 + max_div, 2):
		if n % i == 0:
			return False
	return True

# Driver function
t0 = time.time()
c = 0 #for counting

for n in range(1,100000):
	x = is_prime(n)
	c += x
print("Total prime numbers in range :", c)

t1 = time.time()
print("Time required :", t1 - t0)

4、生成素数的列表

        此方法打印所有小于或等于给定数 n 的素数。例如,如果 n 为 10,则输出应为“2, 3, 5, 7”。如果 n 为 20,则输出应为“2, 3, 5, 7, 11, 13, 17, 19”。 

        这种方法被认为是生成所有小于给定数 n 的素数的最有效方法。它被认为是生成素数列表的最快方法。此方法不适合检查特定数字。此方法适用于生成所有素数的列表。

import time
def SieveOfEratosthenes(n):
	
	# 创建一个布尔数组“prime[0..n]”并将所有条目初始化为真。 如果 i 不是素数,则 prime[i] 中的值最终将为假,否则为真。
	prime = [True for i in range(n+1)]
	
	p = 2
	while(p * p <= n):
		# 如果 prime[p] 没有改变,那么它是一个素数
		if (prime[p] == True):
			# Update all multiples of p
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	c = 0

	# Print all prime numbers
	for p in range(2, n):
		if prime[p]:
			c += 1
	return c

# Driver function
t0 = time.time()
c = SieveOfEratosthenes(100000)
print("Total prime numbers in range:", c)

t1 = time.time()
print("Time required:", t1 - t0)

二、回文素数

1、概述

        回文素数是一种具有特殊性质的素数,其既是素数又是回文数。而所谓回文数,即从左向右读与从右向左读是完全一样的自然数,例如,11、22、101、222、818、12321等。

        回文素数即从左向右读与从右向左读是完全一样的素数。典型的回文素数如下:

        11、101、131、151、181、191、313、……。

        回文素数往往与记数系统的进位值有关。目前,数学家仍无法证明在十进制中是否包含无限多个回文素数。

        在其他进制中也有回文素数的概念,例如,在二进制中,回文素数包括梅森素数和费马素数。

2、判断是否回文素数

#include<stdio.h>  
int main()    
{    
    int n,r,sum=0,temp;
    printf("enter the number=");
    scanf("%d",&n);
    temp=n;
    while(n>0)    
    {    
        r=n%10;    
        sum=(sum*10)+r;    
        n=n/10;    
    }  

    if(temp==sum)    
        printf("palindrome number ");
    else    
        printf("not palindrome");

    return 0;  
}   

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/124923087