zoukankan      html  css  js  c++  java
  • 素数测试(判断素数)模板

    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
    ",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
    ",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;
                }
            }
        }
    }


  • 相关阅读:
    cz_health_day07
    cz_health_day06
    mysql索引底层原理
    cz_health_day05
    redis无法获取连接原因分析
    cz_health_day04
    cz_health_day03
    cz_health_day02
    cz_health_day01
    Spring学习
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9387127.html
Copyright © 2011-2022 走看看