Giải thích code loại bỏ phần tử trùng nhau của mảng trong C

Mọi người giải thích hộ em code này với, em suy nghĩ mà không hiểu ý nghĩa của nó là gì

#include<stdio.h>
#include<conio.h>
int a[100];
void main()
{
	int i, j, n, k, dem = 0;
	printf("nhap so phan tu cua mang:");
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		printf("a[%d]=", i + 1);
		scanf("%d", &a[i]);
	}
	printf("mang da nhap:\n");
	for (i = 0; i < n; i++) 	
	{
		printf(" %d ", a[i]);
	}
	for (i = 1; i < n; i++)
	{
		for (j = 0; j < i; j++)
		{
			if (a[i] == a[j])
			{
				for (k = i; k < n; k++) 
				{
					a[k] = a[k + 1];
					n--;
					i--;
				}
			}
		}
	}
	printf("\nmang sau khi xoa la:\n");
	for (i = 0; i < n; i++) 
	{
		printf(" %d ", a[i]);
	}
 _getch();
1 Like

Vui lòng bỏ hết code vào markdown hoặc up lên codepad.org cho mọi người dễ nhìn nhé:
Cách post Code dùng Markdown trong Category Programming

1 Like

Chạy từ đầu đến cuối. Khi đến 1 phần tử nào đó sẽ xét từ đầu dãy đễn phần tử đó xem có phần tử nào giống không. Nếu có thì dịch mảng lên 1 phàn tử coi như là xóa phần tử đó đi

3 Likes

Chắc ba vòng for kia làm bạn không hiểu.
Bạn hãy thử lấy giấy ra và thực hiện tuần tự với một mảng tự cho trước.
Kết quả sẽ được
Vòng for đầu sẽ dùng để duyệt phần tử mảng
Vòng for 2 dùng để kiểm tra xem phần tử đang duyệt có trùng không.
Vòng for 3 dùng để xoá phần tử trùng đi, bản chất của nó là làm đè phần tử sau lên phần tử trước.

1 Like

cảm ơn bác, bác có thể giải thích rõ trong vòng lặp for thứ 3 cho em được không ạ. Nhất là n-- và i-- ạ.

Khi xóa phần tử thì số phần tử phải giảm nên n-- thôi. Còn i-- để giữ phần tử đang xét

1 Like

cho em hỏi sao khi em chạy chương trình này với n=5, dãy gồm 1 1 2 3 4 thì output lại chỉ có 1 2 3

n-- và i-- nằm trong vòng lặp k là sai rồi :slight_smile: chỉ cần hiệu chỉnh một lần.

2 Likes

có thể giải thích rõ cho em được không ạ?

Thực ra cách thớt đưa ra không hay vì có rất nhiều thao tác thừa. Còn hiệu chỉnh là do một phần tử đã bị xóa nên nếu để nguyên thì lần sau sẽ bỏ qua luôn (và n sẽ bị sai), nhưng nó lại dở ở chỗ này.

2 Likes

phải bỏ n-- ra ngoài vòng lặp for còn i-- thì bỏ đi như vậy phần tử cuối mới ko bị xóa

3 Likes
#include<stdio.h>
#include<conio.h>
int a[100];
main()
{
	int i, j, n, k, dem = 0;
	printf("nhap so phan tu cua mang:");
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		printf("a[%d]=", i + 1);
		scanf("%d", &a[i]);
	}
	printf("mang da nhap:\n");
	for(i=0;i<n;++i)
	
	{
		printf(" %d ", a[i]);
	}
	// xoa phan tu trung
	for (i=0;i<n-1;i++)
	{
    	j=i+1;
    	while (j<n)
    	if (a[i]==a[j])
		{
        	for (k=j;k<n-1;k++) 
				a[k]=a[k+1];
    	n=n-1;
    	}
    else j=j+1;
    }
    n--;
	printf("\nmang sau khi xoa la:\n");
	for (i = 0; i < n+1; i++) 
	{
		printf(" %d ", a[i]);
	}
}

Có thể phân ra hai cách duyệt j-- ,i–
Trường( j–)
khi không có j-- (1 1 1 2 3 4 ) sẽ chuyển thành (1 1 2 3 4) vì lúc này a[2] dịch về a[1] và vị trí a[2] bây giời có giá trị =2 => a[0] sẽ so sánh với a[2]
có j-- (1 1 1 2 3 4) sẽ chuyển thành (1 2 3 4) lúc này a[2] dịch về a[1] tiếp đó lại là a[0] so sánh a[1] như vậy đến hết!
Trường hợp(i–)
khi không có i–(1 1 1 2 3 4) sẽ chuyển thành (1 1 2 3 4) vì lúc này a[2] dịch về a[1] và vị trí a[2] bây giời có giá trị =2 => a[0] sẽ so sánh với a[2]
Có i-- (1 1 1 2 3 4) sẽ chuyển thành (1 1 2 3 4 ) sau khi duyệt hết hết 1 vòng lặp của j kế tiếp , đến đấy i-- nó mới có tác dụng đưa a[i]=a[1] thành a[0] và như vậy (1 1 2 3 4) thành (1 2 3 4)!

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