Skip to content

Commit b573126

Browse files
committed
add Math prime
1 parent 55bde54 commit b573126

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

zh-cn/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* [Divide and Conquer](basics_algorithm/divide_and_conquer.md)
2727
* [Math](basics_algorithm/math/README.md)
2828
* [Greatest Common Divisor](basics_algorithm/math/gcd.md)
29+
* [Prime](basics_algorithm/math/prime.md)
2930
* [Basics Misc](basics_misc/README.md)
3031
* [Bit Manipulation](basics_misc/bit_manipulation.md)
3132
* [Knapsack](basics_misc/knapsack.md)
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Prime
2+
3+
素数:恰好有两个约数的整数,一个是1,另一个则是它自己,比如整数3和5就是素数。素数的基本算法有**素性测试、埃氏筛法和整数分解。**
4+
5+
## 素性测试
6+
7+
如果`d``n`的约数,则易知 $$n = d \cdot \frac{n}{d}$$, 因此 `n/d`也是`n`的约数,且这两个约数中的较小者 $$\min(d, n/d) <= \sqrt{n}$$. 因此我们只需要对前 $$\sqrt{n}$$ 个数进行处理。
8+
9+
## 埃氏筛法
10+
11+
素性测试针对的是单个整数,如果需要枚举整数`n`以内的素数就需要埃氏筛法了。核心思想是枚举从小到大的素数并将素数的整数倍依次从原整数数组中删除,余下的即为全部素数。
12+
13+
## 区间筛法
14+
15+
求区间`[a, b)`内有多少素数?
16+
17+
埃氏筛法得到的是`[1, n)`内的素数,求区间素数时不太容易直接求解,我们采取以退为进的思路先用埃氏筛法求得`[1, b)`内的素数,然后截取为`[a, b)`即可。
18+
19+
## Implementation
20+
21+
### Java
22+
23+
```java
24+
import java.util.*;
25+
26+
public class Prime {
27+
// test if n is prime
28+
public static boolean isPrime(int n) {
29+
for (int i = 2; i * i <= n; i++) {
30+
if (n % i == 0) return false;
31+
}
32+
return n != 1; // 1 is not prime
33+
}
34+
35+
// enumerate all the divisor for n
36+
public static List<Integer> getDivisor(int n) {
37+
List<Integer> result = new ArrayList<Integer>();
38+
for (int i = 1; i * i <= n; i++) {
39+
if (n % i == 0) {
40+
result.add(i);
41+
// i * i <= n ==> i <= n / i
42+
if (i != n / i) result.add(n / i);
43+
}
44+
}
45+
Collections.sort(result);
46+
return result;
47+
}
48+
49+
// 12 = 2 * 2 * 3, the number of prime factor, small to big
50+
public static Map<Integer, Integer> getPrimeFactor(int n) {
51+
Map<Integer, Integer> result = new HashMap<Integer, Integer>();
52+
for (int i = 2; i * i <= n; i++) {
53+
// if i is a factor of n, repeatedly divide it out
54+
while (n % i == 0) {
55+
if (result.containsKey(i)) {
56+
result.put(i, result.get(i) + 1);
57+
} else {
58+
result.put(i, 1);
59+
}
60+
n = n / i;
61+
}
62+
}
63+
// if n is not 1 at last
64+
if (n != 1) result.put(n, 1);
65+
return result;
66+
}
67+
68+
// sieve all the prime factor less equal than n
69+
public static List<Integer> sieve(int n) {
70+
List<Integer> prime = new ArrayList<Integer>();
71+
// flag if i is prime
72+
boolean[] isPrime = new boolean[n + 1];
73+
Arrays.fill(isPrime, true);
74+
isPrime[0] = false;
75+
isPrime[1] = false;
76+
for (int i = 2; i <= n; i++) {
77+
if (isPrime[i]) {
78+
prime.add(i);
79+
for (int j = 2 * i; j <= n; j += i) {
80+
isPrime[j] = false;
81+
}
82+
}
83+
}
84+
return prime;
85+
}
86+
87+
// sieve between [a, b)
88+
public static List<Integer> sieveSegment(int a, int b) {
89+
List<Integer> prime = new ArrayList<Integer>();
90+
boolean[] isPrime = new boolean[b];
91+
Arrays.fill(isPrime, true);
92+
isPrime[0] = false;
93+
isPrime[1] = false;
94+
for (int i = 2; i < b; i++) {
95+
if (isPrime(i)) {
96+
for (int j = 2 * i; j < b; j += i) isPrime[j] = false;
97+
if (i >= a) prime.add(i);
98+
}
99+
}
100+
return prime;
101+
}
102+
103+
public static void main(String[] args) {
104+
if (args.length == 1) {
105+
int n = Integer.parseInt(args[0]);
106+
if (isPrime(n)) {
107+
System.out.println("Integer " + n + " is prime.");
108+
} else {
109+
System.out.println("Integer " + n + " is not prime.");
110+
}
111+
System.out.println();
112+
113+
List<Integer> divisor = getDivisor(n);
114+
System.out.print("Divisor of integer " + n + ":");
115+
for (int d : divisor) System.out.print(" " + d);
116+
System.out.println();
117+
System.out.println();
118+
119+
Map<Integer, Integer> primeFactor = getPrimeFactor(n);
120+
System.out.println("Prime factor of integer " + n + ":");
121+
for (Map.Entry<Integer, Integer> entry : primeFactor.entrySet()) {
122+
System.out.println("prime: " + entry.getKey() + ", times: " + entry.getValue());
123+
}
124+
125+
System.out.print("Sieve prime of integer " + n + ":");
126+
List<Integer> sievePrime = sieve(n);
127+
for (int i : sievePrime) System.out.print(" " + i);
128+
System.out.println();
129+
} else if (args.length == 2) {
130+
int a = Integer.parseInt(args[0]);
131+
int b = Integer.parseInt(args[1]);
132+
List<Integer> primeSegment = sieveSegment(a, b);
133+
System.out.println("Prime of integer " + a + " to " + b + ":");
134+
for (int i : primeSegment) System.out.print(" " + i);
135+
System.out.println();
136+
}
137+
}
138+
}
139+
```

0 commit comments

Comments
 (0)