Trước hết, mã của bạn vừa ngắn vừa chính xác, rất tốt cho người mới bắt đầu. ;-)
Đây là những gì tôi sẽ làm gì để cải thiện mã:
1) Xác định các biến bên trong các vòng, vì vậy họ không bị lẫn lộn với cái gì khác. Tôi cũng sẽ làm cho một tham số bị ràng buộc hoặc một hằng số.
#define MAX 1000
for(int i=2;i<MAX;i++){
for(int j=2;j<i/j;j++){
if(!(i%j)) break;
if(j>(i/j)) cout<<i<<" is prime\n";
}
}
2) Tôi sẽ sử dụng số Sieve of Eratosthenes, như Joey Adams và Mau đã đề xuất. Lưu ý cách tôi không phải viết giới hạn hai lần, vì vậy hai tập quán sẽ luôn giống nhau.
#define MAX 1000
bool prime[MAX];
memset(prime, sizeof(prime), true);
for(int i=4;i<MAX;i+=2) prime[i] = false;
prime[1] = false;
cout<<2<<" is prime\n";
for(int i=3;i*i<MAX;i+=2)
if (prime[i]) {
cout<<i<<" is prime\n";
for(int j=i*i;j<MAX;j+=i)
prime[j] = false;
}
Các giới hạn cũng đáng chú ý. i*i<MAX
nhanh hơn rất nhiều so với j > i/j
và bạn cũng không cần đánh dấu bất kỳ số nào < i * i, bởi vì chúng đã được đánh dấu, nếu chúng là hỗn hợp. Điều quan trọng nhất là time complexity.
3) Nếu bạn thực sự muốn thực hiện thuật toán này nhanh, bạn cần phải tối ưu hóa bộ nhớ cache. Ý tưởng đầu tiên là tìm tất cả các số nguyên tố < sqrt (MAX) và sau đó sử dụng chúng để tìm phần còn lại của số nguyên tố . Sau đó, bạn có thể sử dụng cùng một khối bộ nhớ để tìm tất cả các số nguyên tố từ 1024-2047, giả sử, và sau đó là 2048-3071. Điều này có nghĩa là mọi thứ sẽ được giữ trong L1-cache. Tôi đã từng đo tốc độ tăng tốc ~ 12 lần bằng cách sử dụng tối ưu hóa này trên Sàng Eratosthenes.
Bạn cũng có thể cắt giảm không gian sử dụng một nửa bằng cách không lưu số chẵn, có nghĩa là bạn không phải thực hiện các tính toán để bắt đầu làm việc trên khối mới thường xuyên.
Nếu bạn là người mới bắt đầu, có lẽ bạn nên quên bộ nhớ cache trong giây lát.
nó không GIỮA 2 và 1000 đó là giữa 1 và 1000 (mã của bạn bao gồm 2 nhưng không bao gồm 1000) – Jacob
Rất tiếc, bạn thx đúng – user377622
@Jacob - khi sử dụng dãy nửa mở (rất phổ biến trong lập trình) , "từ 2 đến 1000" có nghĩa là để bao gồm 2 nhưng loại trừ 1000. Odd rằng bạn khẳng định một phạm vi độc quyền - hầu hết mọi người khi từ chối nửa mở sẽ nhấn mạnh trên một phạm vi bao gồm (từ 2 đến 999). Không phải là bất kỳ điều này làm cho một sự khác biệt, vì không phải 1 cũng không 1000 là chính. – Steve314