Fix bài tính tổng số nguyên tố bằng danh sách tuyến tính

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


typedef struct {
	int n;
	int pt[50];
}list;

void nhap(list &L) {     
	printf("So phan tu danh sach N= ");
	scanf("%d",&L.n);
	for(int i=1; i<=L.n; i++) { 
	printf("Phan tu thu %d: ",i);
	scanf("%d",&L.pt[i]);
	}  
}

void xuat(list L){
	for(int i=1;i<=L.n;i++){
	printf("n[%d]: %d\n",i,L.pt[i]);
	}
}


double TBC(list L){
    int avg,sum=0;
    double r;
    for(int i=1;i<=L.n;i++){
       sum+=L.pt[i];
    }
   return avg=(double)sum/L.n;
}

bool KTSNT(list L)
{
	if(L.n<2)
		return false;
	for(int i=2; i<L.n/2; i++){
		if(L.n%i==0){
			return false;
			}
	return true;
}	
}

int TongPTSNT(list L){
	int tong=0;
	for(int i=2; i<=L.n; i++){
		if(KTSNT(L) == true){
			tong += L.pt[i];
		}
	}
	return tong;
}

/*int tichscp(list L){
	int tich;
	for(int i=1; i<=L.n; i++){
		if(i*i == L.pt[i]){
			tich *= L.pt[i];
		}
	}
	return tich;	
}
*/

int main(){
	int i,avg,snt;
	list L;	 
	nhap(L);
	xuat(L);
	printf("TBC = %.2f\n", TBC(L));
	printf("Tong SNT = %d\n", TongPTSNT(L));
	//printf("Tich so chinh phuong: %d\n", tichscp(L));
	
	
}

bác nào giúp em fix với ạ.

Nhập n: 1 , 2, 3 , 4 ,5
Đúng là tổng = 10
Nhưng chương trình chạy = 15

Bạn đang kiểm tra xem L.n có phải là số nguyên tố không, để làm gì. :question: :question:

Ngoài ra thì code của bạn còn rất nhiều vấn đề cần phải nói. :slight_smile:

1/ Bạn viết code C mà dùng syntax của C++. void nhap(list &L)
2/ Mảng trong C bắt đầu từ 0.
3/ struct List khá lớn, bạn nên xài pointer khi pass vô các hàm để tránh lãng phí bộ nhớ.
4/ Hàm tính trung bình cộng mà trả về kiểu int.
5/ Kiểm tra số nguyên tố thiếu trường hợp số 2.
6/ Hàm TongPTSNT() thì lúc check là L.n mà lại đi cộng L.pt[i].

Chắc có v th. :kissing:

2 Likes

double TBC(list L) double mà bác @Sherly1001 @@

@@ giảng viên yêu cầu viết theo Danh sách tuyến tính @@ này syntax của C mà . mà mình thấy syntax C và C++ tựa tựa nhau thôi.

@@ trường hợp 2 nào nữa bạn

Nếu ý của ở đây là vòng lặp for thì nếu i = 0; thì phải nhập thêm 1 phần tử nữa. VD: chọn số phần tử là 5 nếu i =0 thì phải nhập là từ 0 đến 5 là đến 6 phần tử ròi. nhưng bắt đầu vòng lặp bằng = 0 hay 1 không quan trọng cho lắm

Nhưng trước khi trả về thì bạn có gán kết quả của phép chia cho avg một biến kiểu int. :v :v

2 cũng là số nguyên tố mà, sao hắt hủi nó vậy. :kissing:

list &L cái này là tham chiếu, thuộc về C++ nhé, nếu mình đoán không sai thì bạn biên dịch bằng DEV C++ nên nó mới cho chạy. :slight_smile:

Khác hoàn toàn nhé. :kissing:

Thì xài từ 0 đến 4. :kissing:

for (int i = 0; i < 5; ++i) scanf("%d", &L.pt[i]);

Vẫn cái class list đó nhưng thay vì 1 thì mình khai báo một tỷ => bạn đã lãng phí mất 109 * 4 byte = 3,906,250 MB = 3,814.697265625‬ GB. :slight_smile:

2 Likes

Okey. Thật sự thì mình mới học. Giảng viên demo thế nào thì mình dựa theo giảng viên viết thôi. Nếu bạn có lòng giúp mình thì bạn có thể demo sửa lại toàn bộ bài mình được không ak. Để mình có thể học hỏi rút kinh nghiệm . Chứ bạn nói không như vậy cũng khó cho newbie như mình. Cảm ơn

@Sherly1001 đã chỉ những điểm chưa ổn/sai, bạn cứ dựa theo đó mà sửa lại. Cần gì sửa tận tay cho bạn chứ.
Vd:

Thì sửa thành:

double TBC(list L){
    int sum=0; // <===
    double r;
    for(int i=1;i<=L.n;i++){
       sum+=L.pt[i];
    }
   return (double)sum/L.n; // Không cần gán cho int avg, điều này sẽ làm sai lệch giá trị.
}

Nếu vẫn theo cách dùng avg (một cách vô nghĩa):

double TBC(list L){
    double avg; // <===
    int sum=0; //<===
    double r;
    for(int i=1;i<=L.n;i++){
       sum+=L.pt[i];
    }
   return avg=(double)sum/L.n;
}
2 Likes

Cái mình muốn là bạn có thể tự sửa được bài này cũng như các bài khác gặp lỗi tương tự.

Còn bạn chỉ cần sửa cho xong bài này và gửi bài cho thầy rồi bỏ đó thì thôi, mình cũng đành chịu.

Code cho bạn đây. :kissing:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int n;
    int pt[50];
} list;

void nhap(list *L) { // Dùng con trỏ chứ không phải tham chiếu
	printf("So phan tu danh sach N = ");
	scanf("%d", &L->n); // vì L là con trỏ nên không thể truy cập các biến thành viên theo kiểu thông thường (L.n) mà phải dùng `->`
    for (int i = 0; i < L->n; ++i) {
        printf("Phan tu thu %d: ", i + 1);
        scanf("%d", &L->pt[i]);
    }
}

void xuat(const list *L) { // Cũng dùng con trỏ luôn, để tránh việc copy toàn bộ danh sách L, gây mất thời gian
    for (int i = 0; i < L->n; ++i) printf("n[%d]: %d\n", i, L->pt[i]);
}

double TBC(const list *L) {
    double sum = 0; // sum phải là kiểu double
    for (int i = 0; i < L->n; ++i) sum += L->pt[i];
    return sum / L->n;
}

int KTSNT(int a) { // Chỉ kiểm tra một số chứ không phải cả danh sách
    if (a < 2) return 0;
    if (a == 2) return 1; // 2 cũng là số nguyên tố. :v :v 
    for (int i = 2; i * i <= a; ++i) {
        if (a % i == 0) return 0;
    }
    return 1;
}

int TongPTSNT(const list *L) {
    int sum = 0;
    for (int i = 0; i < L->n; ++i) {
        if (KTSNT(L->pt[i])) { // kiểm tra phần tử L->pt[i] là số nguyên tố thì mới cộng
            sum += L->pt[i];
        }
    }
    return sum;
}

int main() {
    list L;
    nhap(&L); // ở trên khai báo là con trỏ thì dưới này phải truyên vào là địa chỉ
    xuat(&L); // đây cũng vậy
	printf("TBC = %g\n", TBC(&L)); // đây nữa
	printf("Tong SNT = %d\n", TongPTSNT(&L)); // vả cả đây nữa
    return 0;
}
intput
10
1 2 3 4 5 6 7 8 9 10
output
n[0]: 1
n[1]: 2
n[2]: 3
n[3]: 4
n[4]: 5
n[5]: 6
n[6]: 7
n[7]: 8
n[8]: 9
n[9]: 10
TBC = 5.5
Tong SNT = 17
2 Likes

Okey. Lần sau mình sẽ cố gắng hơn

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