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

来源:互联网 发布:先导者之爱知重生 编辑:程序博客网 时间:2024/05/22 12:48

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 9const 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;            }        }    }}


原创粉丝点击