1 •/********************************************* 2 •改编自国际大学生程序设计竞赛题解(一) 3 •源码为pascal 4 •增加creatPrime函数 5 • 6 • 7 • 8 • 9 •********************************************/ 10 • 11 • 12 •#include <iostream> 13 •#include <ctime> 14 •usingnamespace std; 15 • 16 • 17 •constint N = 100; 18 •int prime[N]; 19 • 20 •//最原始的素数判定方法 21 •bool isPrime1(int x) 22 •{ 23 • if (x == 1) 24 • returnfalse; 25 • bool result = true; 26 • for (int i = 2; i < x; i++) 27 • { 28 • if (x % i == 0) 29 • { 30 • result = false; 31 • break; 32 • } 33 • } 34 • return result; 35 •} 36 • 37 •//改进的素数判定方法,从2到sqrt(x),每次检测的因数加1 38 •bool isPrime2(int x) 39 •{ 40 • if (x == 1) 41 • returnfalse; 42 • bool result = true; 43 • for (int i = 2; i * i <= x; i++) 44 • { 45 • if ( x % i == 0) 46 • { 47 • result = false; 48 • break; 49 • } 50 • } 51 • return result; 52 •} 53 • 54 •//2的倍数都直接除掉,从3到sqrt(x)检测,每次检测的因数加2 55 •bool isPrime3(int x) 56 •{ 57 • 58 • if ( ((x - 2) % 2 == 0) || (x == 1)) 59 • returnfalse; 60 • bool result = true; 61 • for (int i = 3; i * i <= x; i = i + 2) 62 • { 63 • if ( x % i == 0) 64 • { 65 • result = false; 66 • break; 67 • } 68 • } 69 • return result; 70 •} 71 • 72 •/* 73 •先构造一个事先做好的素数表 74 •如primer[50] = {2,3,5,7} 75 •*/ 76 • 77 •//构造素数表的函数 78 •void creatPrime(int A[], int N) 79 •{ 80 • int maybeprime = 5; 81 • int gap = 4; 82 • int iCount = 2; 83 • A[0] = 2; 84 • A[1] = 3; 85 • 86 • while (iCount < N) 87 • { 88 • bool isprime = true; 89 • gap = 6 - gap; 90 • for (int i = 0; A[i] * A[i] <= maybeprime;i++) 91 • { 92 • if (maybeprime % A[i] == 0) 93 • { 94 • isprime = false; 95 • break; 96 • } 97 • } 98 • if (isprime) 99 • A[iCount++] = maybeprime; 100 • maybeprime += gap; 101 • } 102 •} 103 • 104 •bool isPrime4(int x) 105 •{ 106 • if (x == 1) 107 • returnfalse; 108 • creatPrime(prime, N); 109 • bool result = false; 110 • for (int i = 0; prime[i] * prime[i] <= x; i++) 111 • { 112 • if ( x % prime[i] == 0) 113 • { 114 • result = true; 115 • break; 116 • } 117 • } 118 • return result; 119 •} 120 • 121 •// 求a的b除以n的约数 122 •//采用二进制提高效率类似于求a的b次方,减少循环次数 123 •int modExp(int a, int b, int n) 124 •{ 125 • int iresult = 1; 126 • int itemp = a % n; 127 • 128 • while (b > 0) 129 • { 130 • if (b % 2 == 1) 131 • { 132 • iresult = (iresult * itemp) % n; 133 • } 134 • itemp = (itemp * itemp) % n; 135 • b /= 2; 136 • } 137 • return iresult; 138 •} 139 • 140 • 141 •//Miller-Rabin概率测试法 142 •/********************************************* 143 •令大奇数n = (2^l) * m + 1, m是正奇数, 144 •若b ^ m = 1(mod n) 或 b^(2^j * m) = -1 (mod n) , 145 •0 <= j <= l-1,则通过测试,视为质数 146 •**********************************************/ 147 •bool MillerRabinTest(int n) 148 •{ 149 • 150 • int m = n - 1; 151 • int l = 0; 152 • while ( m % 2 == 0) 153 • { 154 • l++; 155 • m /= 2; 156 • } 157 • srand(time(NULL)); 158 • int b = rand() % (n-1) + 1; 159 • if (modExp(b,m,n) == 1) 160 • returntrue; 161 • int k = m; 162 • for (int i = 0; i < l; i++) 163 • { 164 • if (modExp(b,k, n) == n-1) 165 • returntrue; 166 • k = k * k; 167 • } 168 • returnfalse; 169 • 170 •} 171 • 172 • 173 •int main() 174 •{ 175 • cout << isPrime1(12) << endl; 176 • cout << isPrime2(15) << endl; 177 • cout << isPrime3(71) << endl; 178 • cout << isPrime4(5987) << endl; 179 • 180 • creatPrime(prime, N); 181 • for (int i = 0; i < N; i++) 182 • cout << prime[i] << ' '; 183 • cout << endl; 184 • cout << MillerRabinTest(132397) << endl; 185 • return 0; 186 •}
浙公网安备 33010602011771号