Cách xoá phần tử trong mảng c++ | Code đơn giản

Việc xóa phần tử trong mảng c++ không hề đơn giản bởi vì mảng có kích thước cố định và không thể thay đổi trong quá trình chạy chương trình. Do đó, thay vì xóa trực tiếp, chúng ta thường xử lý bằng cách di chuyển phần tử cần xóa đến cuối mảng và giảm kích thước của mảng. Trong bài viết này, chúng ta sẽ học cách xóa một giá trị khỏi mảng trong C++.

Ví dụ minh hoạ:

Đầu vào:
Mảng arr[] = {3, 1, 2, 5, 90}, giá trị cần xóa val = 2
Đầu ra:
3 1 5 90
Giải thích: Phần tử có giá trị 2 đã được xóa khỏi mảng.

Đầu vào:
Mảng arr[] = {3, 1, 2, 5, 90}, giá trị cần xóa val = 90
Đầu ra:
3 1 2 5
Giải thích: Phần tử có giá trị 90 đã được xóa khỏi mảng.

Xem thêm:

hàm setprecision trong c++

tách mảng c++

thuật toán kruskal c++

1. Hàm xóa phần tử trong mảng c++

Hàm này cho phép xóa phần tử tại một vị trí bất kỳ (đầu, giữa, hoặc cuối) bằng cách dịch chuyển các phần tử còn lại trong mảng và giảm kích thước logic của mảng.

#include <iostream>
using namespace std;

// Hàm xóa phần tử tại vị trí index
void xoaPhanTu(int arr[], int &n, int index) {
    if (index < 0 || index >= n) {
        cout << "Vi tri khong hop le.\n";
        return;
    }

    // Dịch chuyển các phần tử bên phải vị trí index sang trái
    for (int i = index; i < n - 1; i++) {
        arr[i] = arr[i + 1];
    }

    // Giảm kích thước logic của mảng
    n--;
}

int main() {
    int arr[] = {3, 1, 2, 5, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "Mang truoc khi xoa: ";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    int index = 2; // Vị trí cần xóa (ví dụ: xóa phần tử ở vị trí thứ 2)

    xoaPhanTu(arr, n, index);

    cout << "Mang sau khi xoa: ";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    return 0;
}

2. Cách xoá phần tử ở đầu mảng

Khi xóa phần tử ở đầu, ta cần dịch toàn bộ các phần tử còn lại về phía trước một vị trí, sau đó giảm kích thước logic của mảng đi 1.

Code mẫu:

#include <iostream>
using namespace std;

void xoaDau(int &n, int arr[]) {
    if (n == 0) {
        cout << "Mang rong, khong the xoa phan tu.\n";
        return;
    }

    for (int i = 0; i < n - 1; i++) {
        arr[i] = arr[i + 1];
    }
    n--; // Giảm kích thước mảng
}

int main() {
    int arr[] = {3, 1, 2, 5, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "Mang truoc khi xoa: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    xoaDau(n, arr);

    cout << "Mang sau khi xoa phan tu dau: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    return 0;
}

Output:

Mang truoc khi xoa: 3 1 2 5 90 
Mang sau khi xoa phan tu dau: 1 2 5 90

3. Cách xoá phần tử ở giữa mảng

Để xóa một phần tử ở giữa mảng, ta cần chỉ định vị trí phần tử cần xóa. Sau đó, dịch toàn bộ các phần tử nằm bên phải của nó về phía trước một vị trí và giảm kích thước mảng.

Code mẫu:

#include <iostream>
using namespace std;

void xoaGiua(int &n, int arr[], int viTri) {
    if (viTri < 0 || viTri >= n) {
        cout << "Vi tri khong hop le.\n";
        return;
    }

    for (int i = viTri; i < n - 1; i++) {
        arr[i] = arr[i + 1];
    }
    n--; // Giảm kích thước mảng
}

int main() {
    int arr[] = {3, 1, 2, 5, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "Mang truoc khi xoa: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    int viTri = 2; // Xóa phần tử ở vị trí thứ 2 (giá trị 2)
    xoaGiua(n, arr, viTri);

    cout << "Mang sau khi xoa phan tu o giua: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    return 0;
}

Output:

Mang truoc khi xoa: 3 1 2 5 90 
Mang sau khi xoa phan tu o giua: 3 1 5 90

4. Cách xoá phần tử ở cuối mảng

Khi xóa phần tử ở cuối, ta chỉ cần giảm kích thước logic của mảng đi 1, không cần dịch chuyển phần tử.

Code mẫu:

#include <iostream>
using namespace std;

void xoaCuoi(int &n, int arr[]) {
    if (n == 0) {
        cout << "Mang rong, khong the xoa phan tu.\n";
        return;
    }
    n--; // Giảm kích thước mảng
}

int main() {
    int arr[] = {3, 1, 2, 5, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "Mang truoc khi xoa: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    xoaCuoi(n, arr);

    cout << "Mang sau khi xoa phan tu cuoi: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    return 0;
}

Output:

Mang truoc khi xoa: 3 1 2 5 90 
Mang sau khi xoa phan tu cuoi: 3 1 2 5

5. Xóa nhiều phần tử trong mảng c++

Để xóa nhiều phần tử khỏi mảng trong C++, chúng ta cần thực hiện các bước sau:

  1. Xác định các phần tử cần xóa: Dựa trên vị trí hoặc giá trị.
  2. Duyệt qua mảng: Loại bỏ các phần tử cần xóa bằng cách dịch các phần tử không bị xóa về phía trước.
  3. Cập nhật kích thước logic của mảng.

Code mẫu:

#include <iostream>
using namespace std;

// Hàm xóa các phần tử có giá trị "value"
void xoaNhieuGiaTri(int arr[], int &n, int value) {
    int j = 0; // Chỉ số để lưu các phần tử không bị xóa

    for (int i = 0; i < n; i++) {
        if (arr[i] != value) {
            arr[j++] = arr[i]; // Giữ lại phần tử không bị xóa
        }
    }

    n = j; // Cập nhật kích thước mảng
}

int main() {
    int arr[] = {3, 1, 2, 5, 2, 90, 2};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "Mang truoc khi xoa: ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    int value = 2; // Giá trị cần xóa
    xoaNhieuGiaTri(arr, n, value);

    cout << "Mang sau khi xoa cac phan tu co gia tri " << value << ": ";
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    cout << endl;

    return 0;
}

Output:

Mang truoc khi xoa: 3 1 2 5 2 90 2 
Mang sau khi xoa cac phan tu co gia tri 2: 3 1 5 90

5. Bài tập ví dụ xoá phần tử trong mảng c++

Bài 20 (TH-CSLT-05): Thực hiện lần lượt các yêu cầu sau

  1. Nhập một dãy không quá 100 phần tử là các số thực cho đến khi gặp số 0 thì dừng.
  2. Hiện dãy vừa nhập.
  3. Hiện tổng của các phần tử không âm trong mảng và trung bình cộng các phần tử âm.
  4. Sắp xếp các phần tử trong dãy theo trật tự giảm dần của giá trị. Hiện dãy sau khi sắp xếp.
  5. Giảm giá trị các phần tử ở vị trí chẵn trong dãy đi 10%. Hiện dãy sau khi thực hiện giảm giá trị.
  6. Xoá các phần tử ở vị trí lẻ trong dãy (VD: vị trí 1, 3, 5, …). Hiện dãy sau khi xoá.

5.1. Hàm nhập dãy số nguyên, dừng khi nhập giá trị 0

Để thực hiện Nhập một dãy không quá 100 phần tử là các số thực cho đến khi gặp số 0 thì dừng ta sử dụng vòng lặp do..while với điều kiện phần tử khác 0.

void nhap(int & n, int a[]) {
  int b;
  do {
    cout << "Nhap phan tu thu " << n + 1 << ": ";
    cin >> b;
    a[n] = b;
    n++;
    if (n >= 100) {
      cout << "Khong qua 100 phan tu";
      break;
    }
  } while (b != 0);
}

Bạn có thể xem chi tiết code tham khảo tại đường dẫn: kiểm tra số chính phương c++

5.2. Tính tổng các phần tử không âm và trung bình cộng các phần tử âm

Thực hiện duyệt lần lượt các phần tử của mảng:

  • Nếu phần tử không âm thì sum=sum+a[i]
  • Nếu phần tử âm thì: tăng biến đếm dem++, avg = avg +a[i]. Trung bình = avg/dem.
void tinhTongTrungBinh(int n, float a[]) {
    float tongKhongAm = 0, tongAm = 0;
    int demAm = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] >= 0) {
            tongKhongAm += a[i];
        } else {
            tongAm += a[i];
            demAm++;
        }
    }
    cout << "Tong cac phan tu khong am: " << tongKhongAm << endl;
    if (demAm > 0) {
        cout << "Trung binh cong cac phan tu am: " << tongAm / demAm << endl;
    } else {
        cout << "Khong co phan tu am trong mang.\n";
    }
}

5.3. Sắp xếp mảng theo thứ tự giảm dần

  • Với cách sắp xếp giảm dần từ trái qua phải, mục đích của chúng ta là đưa dần các số lớn nhất về đầu dãy.
  • Vòng lặp bên ngoài (i) duyệt qua từng phần tử của mảng (từ vị trí 0 đến n-1). Vòng lặp bên trong (j) duyệt qua các phần tử còn lại từ vị trí i+1 đến n-1. Mục đích là so sánh các phần tử liền kề nhau và đổi chỗ nếu phần tử bên phải nhỏ hơn phần tử bên trái.
  • Nếu a[i] < a[j], tức là phần tử a[j] có giá trị lớn hơn phần tử a[i], thì ta thực hiện đổi chỗ hai phần tử này. Để đổi chỗ, ta sử dụng biến tạm tg để lưu giá trị của a[i], sau đó gán a[i] bằng a[j] và a[j] bằng giá trị trong biến tạm tg.
void sapXepGiamDan(int n, float a[]) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (a[i] < a[j]) {
                swap(a[i], a[j]);
            }
        }
    }
}

5.4. Giảm giá trị phần tử ở vị trí chẵn đi 10%

Thực hiện giảm giá trị các phần tử ở vị trí chẵn trong dãy đi 10%. Hiện dãy sau khi thực hiện giảm giá trị. Ta tiến hàng duyệt mảng, nếu vị trí của mảng chia 2 dư 0 thì giá trị của vị trí đó sẽ bị giảm đi 10%.

void giamGiaTriChan(int n, float a[]) {
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) { // Chỉ số chẵn
            a[i] *= 0.9;
        }
    }
}

5.5. Xoá phần tử tại vị trí lẻ

Có nhiều cách giải bài toán xoá các phần tử ở vị trí lẻ trong dãy, dưới đây mình sẽ giới thiệu xoá phần tử ở vị trí lẻ bằng cách thay đổi vị trí của các phần tử hay nói cách khác là chọn ra các phần tử ở vị trí chẵn rồi xuất ra màn hình.

Thuật toán xoá phần tử trong mảng:

– Giả sử xóa phần tử tại vị trí thứ i. Chúng ta thực hiện phép dồn các phần tử của mảng: A[i] = A[i+1].

Mô tả thuật toán xoá các phần tử ở vị trí lẻ trong mảng:

  • Tạo vị trí mới j=0
  • Duyệt qua mảng, nếu như vị trí là chẵn thì gán vị trí mới cho phần tử và tăng số lượng phần tử, nếu như vị trí lẻ thì bỏ qua
  • Cập nhập lại số lượng phần tử n mới: n=n/2
  • Xuất mảng mới ra màn hình
void xoaViTriLe(int &n, float a[]) {
    int j = 0;
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) { // Chỉ giữ lại vị trí chẵn
            a[j++] = a[i];
        }
    }
    n = j; // Cập nhật lại số lượng phần tử
}

5.6. Code mẫu hoàn chỉnh

#include<iostream>
#include<iomanip>

using namespace std;

//1 Nhập một dãy không quá 100 phần tử là các số thực cho đến khi gặp số 0 thì dừng
void nhap(int &n, int a[]){

    int b;

    do{
        cout<<"Nhap phan tu thu "<<n+1<<": "; cin>>b;
        a[n]=b;
        n++;
        if(n>=100){
            cout<<"Khong qua 100 phan tu";
            break;
        }
    }while(b!=0);
}

//2.Hiện dãy vừa nhập.

void hien(int &n, int a[]){

    for(int i=0;i<n-1;i++){
        cout<<setw(5)<<a[i];
    }
}

//3.Hiện Tổng của các phần tử không âm trong mảng và Trung bình cộng các phần tử âm.

void tongcacphantukhongam(int &n, int a[]){

    int sum=0, average=0, dem=0;
    for(int i=0;i<n-1;i++){
        if(a[i]<0){
            dem++;
            average+=a[i];
        }else{
            sum+=a[i];
        }
    }

    cout<<"Tong cac phan tu khong am la: "<<sum<<endl;
    cout<<"Trung binh cong cac phan tu am la: "<<average/dem<<endl;

}

//4.Sắp xếp các phần tử trong dãy theo trật tự giảm dần của giá trị. Hiện dãy sau khi sắp xếp.
void sapxepgiamdan(int &n, int a[]){

    int tg;
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n-1;j++){
            if(a[i]<a[j]){
                tg=a[i];
                a[i]=a[j];
                a[j]=tg;
            }
        }
    }
}

//5.Giảm giá trị các phần tử ở vị trí chẵn trong dãy đi 10%
void giamgiatriphantu(int &n, int a[]){
    for(int i=0;i<n-1;i++){
        if(i%2==0){
            a[i]=a[i]*0.1;
        }
    }
}

//6.Xoá các phần tử ở vị trí lẻ trong dãy(VD: vị trí 1, 3, 5, …)

void xoaphantu(int &n, int a[]){

    int j=0;
    for(int i=0;i<n-1;i++){
        if(i%2==0){
            a[j]=a[i];
            j++;
        }
    }
    n=n/2;

    for(int i=0;i<n;i++){
        cout<<setw(5)<<a[i];
    }

}

int main(){

    int i, n, chon, x, a[255],dem;

    do{
        cout<<"1. Nhap mang"<<endl;
        cout<<"2. Xuat mang"<<endl;
        cout<<"3. Hien Tong cua cac phan tu khong am trong mang va Trung binh cong cac phan tu am"<<endl;
        cout<<"4. Sap xep giam dan"<<endl;
        cout<<"5. Giamm gia tri cac phan tu o vi tri chan trong day di 10"<<endl;
        cout<<"6. Xoa cac so o vi tri le trong day"<<endl;
        cout<<"Lua chon: "; cin>>chon;

        switch(chon){
            case 1:{
                nhap(n,a);
                cout<<endl;
                break;
            }
            case 2:{
                hien(n,a);
                 cout<<endl;
                break;
            }
            case 3:{
                tongcacphantukhongam(n,a);
                 cout<<endl;
                break;
            }

            case 4:{
                sapxepgiamdan(n,a);
                hien(n,a);
                 cout<<endl;
                break;
            }

            case 5:{
                giamgiatriphantu(n,a);
                hien(n,a);
                 cout<<endl;
                break;
            }

            case 6:{
                xoaphantu(n,a);
                 cout<<endl;
                break;
            }

            default: exit(0);
        }
    }while(chon!=0);

}

Tổng kết, việc xoá phần tử trong mảng có thể được thực hiện theo nhiều cách khác nhau, tùy thuộc vào ngôn ngữ lập trình mà bạn đang sử dụng. Một cách phổ biến là sử dụng vòng lặp để tìm vị trí của phần tử cần xoá, sau đó di chuyển các phần tử sau nó để ghi đè lên phần tử đó. Cuối cùng, giảm kích thước của mảng đi 1.

Quá trình xoá phần tử trong mảng có thể phức tạp hơn nếu yêu cầu đặc biệt, ví dụ như xoá tất cả các phần tử trùng nhau, xoá phần tử ở vị trí cuối cùng, hoặc xoá phần tử khi không có thông tin về vị trí cụ thể. Trong những trường hợp này, cần có cách tiếp cận khác nhau và sử dụng các thuật toán phù hợp.

Nếu bạn cần thêm thông tin hoặc có câu hỏi khác, hãy để tôi biết. Tôi sẽ sẵn lòng hỗ trợ bạn! Cảm ơn bạn đã tham khảo trên ttnguyen.net

Tải full bài tập thực hành lập trình C/C++ có lời giải:

Bài tiếp theo:

thuật toán prim

file nhị phân c++

thuật toán cờ caro

Nguyễn Tiến Trường

Mình viết về những điều nhỏ nhặt trong cuộc sống, Viết về câu chuyện những ngày không có em