素数测试(判断素数)模板

1、素数测试:

#include<cstdlib>
#include<cstdio>
int modularExponent(int a, int b, int n) {
	int ret = 1;
	for (; b; b >>= 1, a = (int) ((long long) a * a % n)) {
		if (b & 1) {
			ret = (int) ((long long) ret * a % n);
		}
	}
	return ret;
}
bool millerRabin(int n,int a) {
	if (n == 1 || (n != 2 && !(n % 2)) || (n != 3 && !(n % 3)) || (n != 5 && !(n % 5)) || (n != 7 && !(n % 7))) {
		return false;
	}
	int r = 0, s = n - 1, j;
	if(!(n%a)) return false;
	while(!(s&1)){ s >>= 1; r++; }
	long long k = modularExponent(a, s, n);
	if(k == 1) return true;
	for(j = 0; j < r; j++, k = k * k % n)
	    if(k == n - 1) return true;
	return false;
}
bool miller_Rabin(int n)//
{
	int a[]={2,3,5,7},i;//能通过测试的最小素数为 3215031751(此数超int)
	for(i=0;i<4;i++){
		if(!millerRabin(n,a[i]))return false;
	}
	return true;
}
int main()
{
	int n,x;
	scanf("%d",&n);
	while(n--){
		scanf("%d",&x);
		printf("%s\n",miller_Rabin(x)?"Yes":"No");
	}
	return 0;
}



2、大神代码

#include<cstdlib>
#include<cstdio>
int modularExponent(int a, int b, int n) {
	int ret = 1;
	for (; b; b >>= 1, a = (int) ((long long) a * a % n)) {
		if (b & 1) {
			ret = (int) ((long long) ret * a % n);
		}
	}
	return ret;
}
bool millerRabin(int n,int a) {
	if (n == 1 || (n != 2 && !(n % 2)) || (n != 3 && !(n % 3)) || (n != 5 && !(n % 5)) || (n != 7 && !(n % 7))) {
		return false;
	}
	int r = 0, s = n - 1, j;
	if(!(n%a)) return false;
	while(!(s&1)){ s >>= 1; r++; }
	long long k = modularExponent(a, s, n);
	if(k == 1) return true;
	for(j = 0; j < r; j++, k = k * k % n)
	    if(k == n - 1) return true;
	return false;
}
bool miller_Rabin(int n)//
{
	int a[]={2,3,5,7},i;//能通过测试的最小素数为 3215031751(此数超int)
	for(i=0;i<4;i++){
		if(!millerRabin(n,a[i]))return false;
	}
	return true;
}
int main()
{
	int n,x;
	scanf("%d",&n);
	while(n--){
		scanf("%d",&x);
		printf("%s\n",miller_Rabin(x)?"Yes":"No");
	}
	return 0;
}

3、查找小于等于MAXN的素数(生成连续素数表)

/*
 *  素数筛选,查找出小于等于MAXN的素数
 *  prime[0]存素数的个数
 */

const int MAXN = 100000;
int prime[MAXN + 1];

void getPrime()
{
    memset(prime, 0, sizeof(prime));
    for (int i = 2; i <= MAXN; i++)
    {
        if (!prime[i])
        {
            prime[++prime[0]] = i;
        }
        for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)
        {
            prime[prime[j] * i] = 1;
            if (i % prime[j] == 0)
            {
                break;
            }
        }
    }
}





4、大数素数测试

#define MAXL 4
#define M10 1000000000
#define Z10 9

const int zero[MAXL - 1] = {0};

struct bnum
{
    int data[MAXL]; //  断成每截9个长度

    //  读取字符串并转存
    void read()
    {
        memset(data, 0, sizeof(data));
        char buf[32];
        scanf("%s", buf);
        int len = (int)strlen(buf);
        int i = 0, k;
        while (len >= Z10)
        {
            for (k = len - Z10; k < len; ++k)
            {
                data[i] = data[i] * 10 + buf[k] - '0';
            }
            ++i;
            len -= Z10;
        }
        if (len > 0)
        {
            for (k = 0; k < len; ++k)
            {
                data[i] = data[i] * 10 + buf[k] - '0';
            }
        }
    }

    bool operator == (const bnum &x)
    {
        return memcmp(data, x.data, sizeof(data)) == 0;
    }

    bnum & operator = (const int x)
    {
        memset(data, 0, sizeof(data));
        data[0] = x;
        return *this;
    }

    bnum operator + (const bnum &x)
    {
        int i, carry = 0;
        bnum ans;
        for (i = 0; i < MAXL; ++i)
        {
            ans.data[i] = data[i] + x.data[i] + carry;
            carry = ans.data[i] / M10;
            ans.data[i] %= M10;
        }
        return  ans;
    }

    bnum operator - (const bnum &x)
    {
        int i, carry = 0;
        bnum ans;
        for (i = 0; i < MAXL; ++i)
        {
            ans.data[i] = data[i] - x.data[i] - carry;
            if (ans.data[i] < 0)
            {
                ans.data[i] += M10;
                carry = 1;
            }
            else
            {
                carry = 0;
            }
        }
        return ans;
    }

    //  assume *this < x * 2
    bnum operator % (const bnum &x)
    {
        int i;
        for (i = MAXL - 1; i >= 0; --i)
        {
            if (data[i] < x.data[i])
            {
                return *this;
            }
            else if (data[i] > x.data[i])
            {
                break;
            }
        }
        return ((*this) - x);
    }

    bnum & div2()
    {
        int  i, carry = 0, tmp;
        for (i = MAXL - 1; i >= 0; --i)
        {
            tmp = data[i] & 1;
            data[i] = (data[i] + carry) >> 1;
            carry = tmp * M10;
        }
        return *this;
    }

    bool is_odd()
    {
        return (data[0] & 1) == 1;
    }

    bool is_zero()
    {
        for (int i = 0; i < MAXL; ++i)
        {
            if (data[i])
            {
                return false;
            }
        }
        return true;
    }
};

void mulmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)
{
    bnum tmp = a0, b = b0;
    ans = 0;
    while (!b.is_zero())
    {
        if (b.is_odd())
        {
            ans = (ans + tmp) % p;
        }
        tmp = (tmp + tmp) % p;
        b.div2();
    }
}

void powmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)
{
    bnum tmp = a0, b = b0;
    ans = 1;
    while (!b.is_zero())
    {
        if (b.is_odd())
        {
            mulmod(ans, tmp, p, ans);
        }
        mulmod(tmp, tmp, p, tmp);
        b.div2();
    }
}

bool MillerRabinTest(bnum &p, int iter)
{
    int i, small = 0, j, d = 0;
    for (i = 1; i < MAXL; ++i)
    {
        if (p.data[i])
        {
            break;
        }
    }
    if (i == MAXL)
    {
        // small integer test
        if (p.data[0] < 2)
        {
            return  false;
        }
        if (p.data[0] == 2)
        {
            return  true;
        }
        small = 1;
    }
    if (!p.is_odd())
    {
        return false;   //  even number
    }
    bnum a, s, m, one, pd1;
    one = 1;
    s = pd1 = p - one;
    while (!s.is_odd())
    {
        s.div2();
        ++d;
    }

    for (i = 0; i < iter; ++i)
    {
        a = rand();
        if (small)
        {
            a.data[0] = a.data[0] % (p.data[0] - 1) + 1;
        }
        else
        {
            a.data[1] = a.data[0] / M10;
            a.data[0] %= M10;
        }
        if (a == one)
        {
            continue;
        }

        powmod(a, s, p, m);

        for (j = 0; j < d && !(m == one) && !(m == pd1); ++j)
        {
            mulmod(m, m, p, m);
        }
        if (!(m == pd1) && j > 0)
        {
            return false;
        }
    }
    return true;
}

int main()
{
    bnum x;

    x.read();
    puts(MillerRabinTest(x, 5) ? "Yes" : "No");

    return 0;
}


5、判断小于MAXN得数是不是素数

/*
 *  素数筛选,判断小于MAXN的数是不是素数
 *  notprime是一张表,false表示是素数,true表示不是
 */

const int MAXN = 1000010;
bool notprime[MAXN];

void init()
{
    memset(notprime, false, sizeof(notprime));
    notprime[0] = notprime[1] = true;
    for (int i = 2; i < MAXN; i++)
    {
        if (!notprime[i])
        {
            if (i > MAXN / i)   //  阻止后边i * i溢出(或者i,j用long long)
            {
                continue;
            }
            //  直接从i * i开始就可以,小于i倍的已经筛选过了
            for (int j = i * i; j < MAXN; j += i)
            {
                notprime[j] = true;
            }
        }
    }
}


posted @ 2017-10-21 15:53  Bryce1010  阅读(159)  评论(0编辑  收藏  举报