You are on page 1of 4

HỌ TÊN SINH VIÊN : NGUYỄN TRỌNG TẤN AT180243 v à LÊ XUÂN PHÚ AT180243

(LỚP AT18B)

– THUÂT TOÁN L03

SÀNG SỐ NGUYÊN TỐ ERATOSTHENES NGUYÊN THUỶ

- Khái quát : + số nguyên tố là một số có đúng 2 ước tự nhiên là 1 và chính nó

+ Là một thuật toán cổ đại để tìm tất cả các số nguyên tố nhỏ hơn hoặc bằng
một số nguyên cho trước

* Ý tưởng :

1. bắt đầu với số nguyên tố đầu tiên là 2


2. Sinh tất cả các bội của số nguyên tố đã cho (nhỏ hơn số tự nguyên
cho trước) với hiệu số cố định giữa các số bằng số nguyên tố đó

3. Đánh dấu tất cả các bội của mỗi số nguyên tố là hợp số


4. Các số còn lại đánh dấu là số nguyên tố

- Mô tả thuật toán : thuật toán sàng nguyên tố eratosthenes nguyên thuỷ là một thuật toán
dùng chủ yếu vào việc sàng lọc những số nguyên tố nhỏ hơn n, nó hoạt động theo nguyên
tắc là sàng lọc loại bỏ đi những bội số của số trước nó ví dụ 4 6 8.. là bội số của 2 chẳng
hạn. cứ đánh dấu những số là bội số của những số đứng trước mà không bị đánh dấu.
Cuối cùng ta còn lại những số không bị đánh dấu là số nguyên tố. Ta được kết quả bài
toán ..
- Các bước thực hiện :
 Bước 1 : Liệt kê các số nguyên liên tiếp từ 2 đến n (2,3,4…n)
 Bước 2 : Khởi tạo p = 2
 Bước 3 : Liệt kê các bội số của p bằng cách đếm các số gia của p từ
2p,3p,4p…. tới n và đánh dấu chúng là hợp số
 Bước 4 : Tìm số nhỏ nhất trong danh sách , lớn hơn p mà không bị đánh
dấu , nếu không tìm thấy số nào thì dừng lại và ngược lại gán p bằng số
vừa tìm đuợc sau đó lặp lại bước 3
 Kết thúc thuật toán, các số còn lại trong dnah sách mà không bị đánh dấu
là tất cả các số nguyên tố nhỏ hơn hoặc bằng n
- Ví Dụ minh hoạ : Tìm các số nguyên tố <=30
 Các số nguyên từ 2 đến 30

 Tạo ra một mảng có ít nhất 30 kí tự để chứa dấu của số nhỏ hơn n (30) ban
đầu tích tất cả bằng 1

i
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 p=2 loại bỏ tất cả các bội của 2 thì các ô A[i] mà i là bội của 2 thì bị đánh
dấu về 0

i
1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
 p=3 loại bỏ tất cả các bội của 3 thì các ô A[i] mà i là bội của 3 thì bị đánh
dấu về 0

i
1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
 p=5 loại bỏ tất cả các bội của 5 thì các ô A[i] mà i là bội của 3 thì bị đánh
dấu về 0

i
1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0
 p=7 loại bỏ tất cả các bội của 3 thì các ô A[i] mà i là bội của 3 thì bị đánh
dấu về 0

i
1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0
với p=7 thì các bội của 7 là 14 21 28 đều đã bị loại cho nên không cần loại
nữa

 vậy sau khi kết thúc ta thu được dãy số nguyên tố nhỏ hơn 30 là là :
2 3 5 7 11 13 17 19 23 29

 Nhận xét:
 Thuật toán duyệt toàn bộ mảng chứa chuỗi các số không lớn hơn n mà không
hiện thị vị trí tham chiếu ( có phải các hợp số có thể bị đánh dấu nhiều lân ?? )
 Yêu cầu bộ nhớ lớn
o với n lớn có thể bộ nhớ không đáp ứng đủ nhu cầu
o còn với n vừa phải thì việc sử dụng bộ nhớ cache của nó là không tối
ưu
o => do đó ta đã ra đời sàng phân đoạn

SÀNG SỐ NGUYÊN TỐ ERATOSTHENES PHÂN ĐOẠN

- Khái quát : là một dạng sàng nguyên tố nhưng nó có giới hạn rõ ràng là từ a đến b còn
sàng nguyên thuỷ là giới hạn của nó là các số nguyên tố nhỏ hơn n. như vậy nếu n quá
lớn thì thuật toán sàng nguyên thuỷ sẽ không khả thi , sàng phân đoạn sẽ chia nhỏ chuỗi
ra và thực hiện nó
- Ý tưởng :
1. bắt đầu bằng số 2 đến căn của R (là giới hạn bên phải )
2. sinh tất cả các bội số củai từ 2 đến căn R
3. đánh dấu các bội của i
4. kết thúc thu được những số không bị đánh dấu là số nguyên tố từ L đến R
- Mô tả thuật toán : ví dụ đoạn cần tìm các số nguyên tố trong đoạn L đến R
Chúng ta sẽ duyệt i từ 2 đến căn R sau đó dùng vẫn sẽ loại bỏ từng bội của i trong
khoảng từ L đến R . cứ làm như vậy cho đến cuối cùng để thu được dãy số nguyên tố
trong đoạn từ L đến R
- Các bước thực hiện :
 Bước 1 : khởi tạo một mảng để đánh dấu với số lượng lưu trữ ít nhất phải
R-L+1 và khởi tạo tất cả bằng 1 gọi là mảng KT
 Bước 2 cho biến I chạy từ 2 cho đến khi i*i<=R thì dừng lại
 Bước 3 : cho biến j nằm trong vòng for trên chạy từ max(i*i, (L+i-1)/i*i)
cho đến R tức là kiểm tra xem i*i có lớn hơn R không nếu lớn hơn thì bắt
đầu duyệt từ i*I còn nếu không thì sẽ duyệt từ số nhỏ nhất trong khoảng L
R mà là bội của i;
 Bước 4 : đánh dấu loại bỏ tất cả các phần tử j bằng cách đánh dấu trong
mảng KT, ví dụ mảng KT bắt đầu từ vị trí 0 thì mình sẽ đánh dấu các
phần tử j bằng cách cho KT[j-L] =0
 Bước 5 : Kết thúc thuật toán, các số còn lại trong danh sách mà không bị
đánh dấu là tất cả các số nguyên tố trong khoảng L R
 Bước 6 : đưa các phần tử ra bằng cách I chạy từ 0 đến R-L rồi nếu KT[i]
=1 thì in ra L+I rồi kết thúc thuật toán
- Ví dụ minh hoạ :
Ta có yêu cầu bài toán là tìm các số nguyên tố từ 7 đến 20;
 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 1 1 1 1 1 1 1 1 1 1 1 1 1
 duyệt từ 2 đến căn n là căn 20 bằng 4;
2 3 4
 p=2 loại bỏ các bội của 2 bắt đầu từ max(i*i, (L+i-1)/i*i) ở đâu =bằng 8
7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 0 1 0 1 0 1 0 1 0 1 0 1 0
 p=3 loại bỏ các bội của 2 bắt đầu từ max(i*i, (L+i-1)/i*i) ở đâu =bằng 9
7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 0 0 0 1 0 1 0 0 0 1 0 1 0
 p=4 loại bỏ các bội của 2 bắt đầu từ max(i*i, (L+i-1)/i*i) ở đâu =bằng 16
thì đã được loại bỏ hết bởi số 2
7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 0 0 0 1 0 1 0 0 0 1 0 1 0
 vậy sau đó ta thu được dãy nguyên tố thoả mãn bài toán cần tìm

You might also like