Code sắp xếp danh sách học sinh theo thứ tự bảng chữ cái ra kết quả không chính xác

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

struct HS
{
	char Hoten[30];
};
void Nhap(HS a[],int n)
{
	for(int i=0;i<n;i++)
	{
	  fflush(stdin);
	  printf("\nNhap ten: ");
	  gets(a[i].Hoten);
	}
}
void Sapxep(HS a[],int n)
{
	for(int i=0;i<n-1;i++)
	{
		for(int j=i+1;j<n;j++)
		{
		   if(strcmp(a[i].Hoten,a[j].Hoten)<0)
		  {
			HS k=a[i];
            a[i]=a[j];
            a[j]=k;
		  }
		}
	} 
}
void Xuat(HS a[],int n)
{
	for(int i=0;i<n;i++)
	{
		printf("\n%s",a[i].Hoten);
	}
}
void main()
{
	HS a[100];
	int n=3;
	Nhap(a,n);
	Sapxep(a,n);
	Xuat(a,n);
	getch();

}

Kết quả ra không chính xác, Ai giúp em sữa với.

2 Likes

chỗ strcmp “== 1” chứ không phải “< 0”

struct sinhVien{
	char hoten[255];
};
void tachten(char hoten[],char ten[]){
	for(int i=strlen(hoten)-1;i>=0;i--){
		if(hoten[i]==' '){
			strcpy(ten,hoten+1+i);
			break;
		}
	}
}
void sapxep(sinhVien danhsach[],int soSinhVien){
	for(int i=0;i<soSinhVien;i++){
		for(int j=i+1;j<soSinhVien;j++){
			char ten1[255]="",ten2[255]="";
			tachten(danhsach[i].hoten,ten1);
			tachten(danhsach[j].hoten,ten2);
			int check1=strcmpi(ten1,ten2);
			if(check1>0){
				sinhVien tam=danhsach[i];
				danhsach[i]=danhsach[j];
				danhsach[j]=tam;
			}
			else if(check1==0){
		int check2=strcmpi(danhsach[i].hoten,danhsach[j].hoten);
					if(check2>0){
						sinhVien tam=danhsach[i];
						danhsach[i]=danhsach[j];
						danhsach[i]=tam;
					}
			}
		}
	}
}
2 Likes

Mình nhớ không nhầm thì hàm strcmp(char string1[ ], string2[ ]) dùng để so sánh hai chuỗi ký tự với nhau nhưng không phân biệt chữ thường hay chữ in, trả về 3 giá trị: nhỏ hơn 0,bằng 0lớn hơn 0.Nếu muốn biết rõ hơn thì bạn cứ search google là được ngay.Nhưng để dễ hơn có thể định nghĩa lại như sau để trả về 3 giá trị -1,0, 1 :

int strcmp(char string1[], char string2[]){
int i = 0;
while(string1[i] != '\0'){
	if(string1[i] == string2[i])
		i++;
	else if(string1[i] != string2[i])
		return ((string1[i] - string2[i]) > 0)? 1 : -1;
}
    return 0;
}

Mình thấy bạn đang dùng thuật toán Selection sort để sắp xếp danh sách sinh viên theo thứ tự ABC
nên strcmp(a[ i ].Hoten, a[ j ].Hoten)==1) nếu bạn định nghĩa lại hàm strcmp như trên hoặc strcmp(a[ i ].Hoten, a[ j ].Hoten) > 0) thì code của bạn mới đúng được. Nhưng để chính xác hơn khi bạn sắp xếp theo thứ tự ABC thì bạn nên tách tên từ chuỗi hoten của mỗi sinh viên để so sánh, nếu như hai tên trùng nhau thì so sánh cả chuỗi họ tên và nên dùng hàm stricmp(char string1[ ], string2[ ]) để so sánh vì hàm này không phân biệt chữ in hay chữ thường. Bạn có thể tham khảo code của mình ,mình đã post ở trên.
–Nếu có gì sai nhờ bạn sửa giúp mình.

1 Like

b có thể giải thích lại hàm void tachten() hộ mình đk k

Lấy từ cuối cùng thôi. Để thuật toán này đúng thì phải bỏ hết số khoảng trắng bên phải trước.

Nếu từng thành phần có ý nghĩa quan trọng thì nên tách chúng ra và cho hẳn một struct để dễ thao tác. Cái này thể hiện tính abstraction rất cao :slight_smile: Thiết đặt một “<” lên chúng là được.

1 Like

nếu bh tên của 2 sv giống nhau thì so sánh đệm và họ kiểu j đk b

Nếu bạn đã xác định được thứ tự < thì nói nhanh là nhiều tên có hai họ :slight_smile: nên tên đệm lấy chữ tiếp theo ngay trước tên thôi.

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