Hợp lại các phần tử trùng nhau trong mảng thành một phần tử

Câu hỏi của em ở dưới phần code ạ. Câu hỏi hơi dài mọi người thông cảm ạ.

#include <iostream> 
using namespace std; 
void nhap (int a[100],int &sl) { 
    cout << "\n nhap so luong phan tu "; 
    cin >> sl; 
    for ( int i = 0; i < sl; i++) {
        cout << "\n a["<<i<<"]= "; 
        cin >> a[i]; 
    } 
} 
int giongnhau(int a[100],int sl,int &dem) { 
     dem=0; 
    for ( int i = 0; i<sl; i++) { 
     for ( int j = 0; j<sl; j++) { 
         if ( i != j) {
        if (a[i]==a[j]) { 
            dem ++; 
            sl--; 
           for ( int m = i; m<sl;m++) { 
                a[m]=a[m+1]; 
		   }
		} 
    }     
	 }
	}
}

 


    void xuat ( int a[100], int sl,int dem) { 
        for (int i = 0; i < sl-dem; i++) { 
            cout << "\n a["<<i<<"]= " << a[i]; 
        }
    
} 
int main () { 
 int a[100], sl,dem;
 nhap (a,sl); 
 giongnhau (a,sl,dem);
 xuat (a,sl,dem); 
 return 0; 
}

Em chỉ hiểu sơ sơ quy luật nên em viết phần này có phần đại khái. Khi em input chỉ 5 phần tử thì nó lại đúng hết, còn lúc em input hơn 15 phần tử luôn thì nó vẫn output ra cái trùng nhau ạ(nhưng rất ít).Mọi người sửa giúp em với ạ, em nghĩ em sai phần này. Em cảm ơn :D.

   for ( int i = 0; i<sl; i++) { 
     for ( int j = 0; j<sl; j++) { 

Cái này là do chỉ duyệt mảng 2 lần. Nếu số phần tử trùng nhau lớn hơn 2 thì sẽ xuất hiện lặp. Hiện tại em có giải pháp thay cho việc viết cả tỉ cái vòng lặp lồng nhau ra là đưa các phần tử đã xuất hiện ra 1 mảng khác:

int arr[];
int appeared[];
bool isAppeared ;
for(i){
    isAppeared = false;
    for(j){
        if(arr[i] == appeared [j]){
            isAppeared = true;
            break;
        }
    }
    if(!isAppeared){
        //Thêm phần tử arr[i] vào mảng appeared
    }
}

Đại khái ý tưởng là thế.
Còn 1 cách nữa là tìm đc phần tử nào thì duyệt mảng 1 lần rồi xoá phần tử đó khỏi mảng nhưng type trên điện thoại nên hơi mất thời gian. Anh tự nghĩ nhé.
P/s: Ai thấy sai gì edit giùm em. Em để tạm wiki.

5 Likes

Cho mình hỏi là for (i) là gì ạ

Mình chưa gặp bao giờ luôn ạ :frowning: , mong bạn chỉ giáo

À cái này là cái khung thôi bạn nhé. Bạn tự thêm bớt vào. Cái đó tượng trưng cho vòng for biến chạy i ấy mà. Còn chạy trong mảng nào, từ bao nhiêu đến bao nhiêu thì bạn tự thêm vào. Mình type trên điện thoại nên hơi lười.
Thực ra đầy đủ là

for(int i = 0 ; i < sizeof(arr) / sizeof(int) ; i++)
4 Likes

Okkk Cảm ơn nhiều ạ :smiley:

1 Like

À còn cách nữa là sắp xếp mảng theo thứ tự tăng hoặc giảm dần nữa nha. Nãy quên mất cách này. Cách này nhanh hơn 2 cách kia rất nhiều.
Sắp xếp xong thì duyệt.

for(i)
    if(arr[i] == arr[i + 1]) continue;
    else cout << arr[i];

Duyệt đến < n - 1 thôi nhé.

5 Likes

Cái này giống y như bài xóa phần tử trùng nhau.

6 Likes

Wow cách này nhanh ghê , em cảm ơn :smiley:

Cái này bạn chỉ là duyệt ở trên cái code trên comment hay là duyệt trên hàm sắp xếp ạ

Duyệt đối với mảng đã được sắp xếp từ trước bạn nhé.

3 Likes

Ở vòng lặp biến j bạn lấy phần tử a_i làm chuẩn rồi dồn mảng phía sau nó, bỏ qua những phần tử bằng a_i. (ta hình tượng là lấy cho hết rồi mới dồn mảng) Cách này bảo toàn thứ tự ban đầu và ko sử dụng những cấu trúc phức tạp :smiley:

Nếu bạn có thể sử dụng thì nếu rơi vào giá trị có trước thì ta cũng dồn mảng như trên, nhưng chỉ duyệt mảng 1 lần.

6 Likes

C++ thì có thể tham khảo data structure set

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