Đếm số nguyên tố trong mảng

sửa tới sửa lui cuối cùng nó vẫn k ra @@ có tiền bối nào hỗ trợ e với@@

#include<iostream>
using namespace std;

int main(){
	int *a, n;
	cout << "Nhap 1 so duong: ";
	cin >> n;
	a = new int(n);
	
	for (int i = 0; i < n; i++){
		cout << "Nhap so thu " << i << ": ";
		cin >> a[i];
	}
	int dem = 0;
	for (int i = 0; i < n; i++){
		for (int j = 2; j <= a[i]; j++){
			if (a[i] % j == 0){
				break;				
			}
			if (j == a[i]){
				dem++;
				cout << a[i] << " ";
			}	
		}
	}
	cout << "So nguyen to xuat hien: " << dem;
}

Dòng này có nghĩa là gì vậy bạn?

Nguyên tắc là có new thì phải có delete, mà tìm trong code không thấy?
Lưu đồ thuật toán của bạn đâu?

2 Likes

cái đó là mảng 1 chiều dạng động mà @@ cái này thầy mình dạy nha, mình không có chế vụ này @Stanley00

Tiếc là lần này bạn lại sai rồi…
Khi một người nào đó đưa ra câu hỏi, mình nghĩ bạn nên tốt hơn là kiểm tra lại từ nhiều nguồn khác nhau chứ đừng chỉ có lấy kiến thức của bản thân ra trả lời.

2 Likes

thì thầy mình đang theo học dạy viết trạng thái tĩnh và trạng thái động của mảng 1 chiều thì mình áp dụng thôi, chứ kiểm tra sao kiểm tra giờ, với lại cái này là kiến thức của thầy mình thì đúng hơn

int *a, n;
cin >> n;
a = new int(n);

đây là đoạn code k vấn đề gì nha, ít ra là compile xong chạy bth. bạn nói sai thì phải chỉ sai chỗ nào chứ @@, với lại code này trên mạng mỗi người mỗi dạng, mình toàn thấy mọi người dùng arr[ ] nhưng thầy mình dùng a[] cũng k ra vấn đề nha. a = new int() là để cập nhật lại mảng bao nhiêu phần tử thôi, bth mà, còn vụ delete đó đa phần dành cho xóa bớt bộ nhớ chiếm dụng khi khai báo mảng ban đầu ở trạng thái tĩnh thôi.

còn lưu đồ thì mình vẽ từ ban đầu rồi, chẳng qua k biết áp dụng thế nào

à quên vẽ dấu mũi tên chỉ về i++ sau khi kết luận a[i] là số nguyên tố

Câu này là cấp phát một int và khởi tạo nó bằng n, chứ có phải n số int đâu.

Với lại j chạy tới a[i] là thừa, tới sqrt thôi.

2 Likes

Từ hôm qua đến giờ bao nhiêu bạn đã chỉ cho bạn lỗi sai rồi, nhưng bạn có chắc kiến thức đâu.

Mình muốn bạn thử viết lại cả code và dùng hàm kiểm tra nguyên tố, nhưng xem ra bạn còn chưa hiểu được thực sự cách kiểm tra nguyên tố hoạt động như thế nào nữa.

1 Like

chỗ mình dạy theo hướng giải bài tập nhiều, chứ lý thuyết k đi sâu @@ bạn nói sâu hơn nữa mình cũng bó tay @rogp10

thiệt tình câu này e đọc từng chữ thì hiểu mà ghép lại cả câu thì không hiểu @@

thì cách kiểm tra số nguyên tố thì kiểm tra ước số từ 2 tới căn bậc 2 của số đó @@ hoặc đếm ước số, nếu ước số đúng bằng 2 thì số đó là số nguyên tố. Mình chỉ biết 2 cách này @noname00

Uhm.

a = new int(n); // nếu n = 5, kết quả a = 5
a = new int[n]; // cái này mới là tạo mảng. Cậu viết sai ngoặc rồi.
4 Likes

nếu chỉ viết code kiểm tra số nguyên tố thì mình viết được như dưới đây:

        bool laSNT = true;
		for (int i = 2; i <= x - 1; i++){
			if (x % i == 0){
				laSNT = false;
				break;
			}
		}
		if (laSNT == true){
			cout << x << " ";

còn gắn thêm đoạn code để chuyển index từ a[0] sang a[1], v.v thì đang bị vướng lại

Ok, vậy dòng if j có bao giờ được kiểm tra không?

1 Like

oops, đa tạ, mình viết nhầm ngoặc @@ lỗi newbie thường gặp :sweat_smile: :sweat_smile: :sweat_smile:

1 Like

theo mình thấy từ bảng kết quả thì hình như tới chỗ break nó dừng mất tiêu nên đáp án lúc nào cũng ra 0 hết @@, nhưng nếu k để break thì nó cứ chạy mãi tới khi j = a[i] mới thôi @@ hoang mang ghê

Bạn có lẽ không nắm chắc kiến thức chứ không phải nhầm đâu.

Bạn viết được đoạn code kiểm tra số nguyên tố của 1 số được, áp dụng vòng for chỉ số mảng bên ngoài là được thôi. Bạn hiểu được flow của code của bạn không?

1 Like

ý tưởng của mình là cho nó kiểm tra điều kiện, chỉ cần nó đúng điều kiện thì dừng việc tăng j mà chuyển sang phần tử kế của mảng bằng cách tăng i, còn nếu a[i] k chia hết cho j thì cho nó chạy mãi tới khi j == a[i] thì tăng biến đếm.

giờ mình cũng chẳng biết mình lủng kiến thức chỗ nào nữa @@, cảm giác giống đang học C++ như mỳ ăn liền, 1 khóa C++ của mình có 10 buổi thôi, những phần còn lại của C thầy mình bảo sẽ xuất hiện ở những ngôn ngữ cao hơn nên k dạy

Bạn đọc dòng này chưa? Nếu đọc rồi thì thử áp dụng xem. Qua bao nhiêu post mà bạn không phản ứng gì, mình buồn đó :confused:

2 Likes

Cậu có vấn đề hơi nghiêm trọng đấy :smile:
Cốt lõi trong lập trình là “chia để trị”. Code để kiểm tra số nguyên tố của cậu thực ra không thể gắn thêm được đâu.

        bool laSNT = true;
		for (int i = 2; i <= x - 1; i++){
			if (x % i == 0){
				laSNT = false;
				break;
			}
		}
		if (laSNT == true){
			cout << x << " ";

Giờ, nếu cậu chia bài toán của cậu, thành:

  • Viết 1 hàm đơn giản để kiểm tra 1 số n có phải nguyên tố hay không. Nếu đúng trả về true, không trả về false.
  • Viết 1 hàm đơn giản để chạy từ đầu tới cuối của 1 mảng

Bài toán đầu tiên như thế này:

int isPrime(int n) {
	int i;
	for (i = 2; i <= sqrt(n); i++) {
		if(n % i == 0) {
			return 0;
		}
	}

	return 1;
}

thì bài toán thứ 2, duyệt từ đầu tới cuối mảng, kết hợp với bài toán đầu, sẽ ra:

int main() {
	int i, size;
	// ...

	for(i = 0; i < size; i++) {
		if(isPrime(arr[i])) {
			// in ra màn hình
		}
	}
}

Rồi, giờ nếu cậu inline toàn bộ hàm isPrime, cậu sẽ có code mà cậu cần.
Trông đơn giản không? Chỉ cần “chia để trị” thôi :smile:

Dĩ nhiên, để inline cậu cần sửa lại 1 chút. Cậu cần 1 biến trung gian, cần đổi lại biến i do cậu đã có biến i rồi, cơ mà đa phần công việc sẽ là copy paste và sửa chút thôi.
Code cuối sau khi inline của cậu có thể sẽ giống thế này:

int main() {
	int i, size;
	// ...

	for(i = 0; i < size; i++) {
		int j;
		int isPrime = 1;
		for (j = 2; j <= sqrt(n); j++) {
			if(n % j == 0) {
				isPrime = 0;
				break;
			}
		}

		if(isPrime) {
			// in ra màn hình
		}
	}
}
3 Likes

nói thiệt thì vô cùng cảm ơn bạn đã chỉ ra vô cùng chi tiết, nhưng chắc do mình lủng kiến thức hay sao mà mình thấy đoạn này của bạn

nó giống với đoạn code này của mình

	int dem = 0;
	for (int i = 0; i < n; i++){
		
		bool prime = true;
		if (a[i] < 2){ 
			prime = false;
		}
		for (int j = 2; j <= a[i]/2; j++){
			if (a[i] % j == 0){
				prime = false;
				break;				
			}
		}
			if (prime == true){
				dem++;
				cout << a[i] << " ";
			}
	}
	cout << "So nguyen to xuat hien: " << dem;

mình cũng cố viết lại code nhưng k hỉu sao nó lại không liên kết giữa việc xét số nguyên tố và thay đổi phần tử trong mảng ấy chứ @@ @noname00 giống mấy đoạn code trên mình cũng thử viết lại với điều kiện xét tới a[i] thay vì sqrt(a[i]) với ý nghĩ nếu a[i] % j != 0 tới tận j == a[i] thì a[i] là số nguyên tố đấy, nhưng cũng k ra kết quả mà @@

:smile:

Tớ giới thiệu cậu 1 vài luật nữa khi cậu cần tìm hiểu vấn đề kỹ thuật:

  • Cậu cần phải định nghĩa được vấn đề của cậu. Trong TH của cậu, hiện tại cậu đang gặp vấn đề gì?
  • Cậu cần phải tái hiện lại được vấn đề của cậu. Cậu nhập gì vào nó lại bị sai?
  • Cậu cần phải giảm scope lỗi. Phần nào chắc chắn là đúng rồi? Làm sao cậu biết nó đúng? Phần nào chưa chắc đã đúng? Làm thế nào để cậu có thể chứng minh nó hoặc đúng, hoặc sai?

Nếu cậu follow các luật trên, hầu hết các vấn đề kỹ thuật đều có thể giải quyết được.
Thử bắt đầu với luật đầu tiên nhé: Cậu đang gặp vấn đề gì?

3 Likes

mình cảm giác sau mỗi lần đổi j thì biến đếm cũng tăng theo @@ trong khi biến đếm chỉ nên biến động khi a[i] thay đổi và laSNT = true mới đúng

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?