Xem thêm

Các thao tác trên Mảng một chiều trong C++

Huy Erick
Ở bài học trước, chúng ta đã tìm hiểu về khái niệm và cách sử dụng Mảng một chiều trong C++. Hôm nay, chúng ta sẽ đi sâu vào các thao tác trên mảng một...

Ở bài học trước, chúng ta đã tìm hiểu về khái niệm và cách sử dụng Mảng một chiều trong C++. Hôm nay, chúng ta sẽ đi sâu vào các thao tác trên mảng một chiều trong C++.

Các thao tác trên mảng một chiều

Để có thể hiểu rõ bài này, chúng ta nên có kiến thức cơ bản về:

  • Vòng lặp for trong C++ (For statements)
  • Mảng một chiều trong C++

Trong bài này, chúng ta sẽ tìm hiểu các vấn đề sau:

  • Truyền mảng vào hàm (passing arrays to functions)
  • Nhập và xuất mảng 1 chiều
  • Sao chép mảng 1 chiều
  • Tìm kiếm phần tử trong mảng
  • Sắp xếp mảng 1 chiều
  • Thêm và xóa một phần tử trong mảng

Truyền mảng vào hàm

Trong bài TRUYỀN GIÁ TRỊ CHO HÀM (Passing Arguments by Value), bạn đã biết khi một biến truyền vào hàm theo phương pháp truyền giá trị, C++ sẽ sao chép giá trị của đối số vào tham số của hàm. Vì tham số hàm là 1 bản sao, nên việc thay đổi giá trị tham số không làm thay đổi giá trị đối số ban đầu.

Đối với kiểu dữ liệu mảng, việc sao chép 1 số lượng lớn các phần tử sẽ gây tốn rất nhiều vùng nhớ và giảm hiệu suất. Nên khi truyền mảng vào hàm, tham số của hàm chính là địa chỉ vùng nhớ của phần tử đầu tiên trong mảng. Vì vậy, mảng có thể thay đổi nội dung sau khi thực hiện hàm.

Lưu ý khi truyền mảng vào hàm:

  • Tham số kiểu mảng trong khai báo hàm giống như khai báo biến mảng. void NhapMang(int a[100]);
  • Tham số kiểu mảng truyền cho hàm chính là địa chỉ của phần tử đầu tiên của mảng.
    • Có thể bỏ số lượng phần tử hoặc sử dụng con trỏ.
    • Mảng có thể thay đổi nội dung sau khi thực hiện hàm. void NhapMang(int a[]); void NhapMang(int *a);
  • Số lượng phần tử thực sự truyền qua biến khác. void NhapMang(int a[100], int n); void NhapMang(int a[], int n); void NhapMang(int *a, int n)

Tất cả các ví dụ bên dưới sẽ sử dụng phương pháp truyền mảng vào hàm.

Nhập và xuất mảng 1 chiều

Dưới đây là ví dụ về nhập, xuất dữ liệu cho mảng 1 chiều:

#include 
#include  // for srand() and rand()
#include  // for time()

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng tự động
  nhapMang(myArray, nSize);

  // xuất mảng
  xuatMang(myArray, nSize);

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "arr[" << i << "] = " << arr[i] << endl;
  }
}

Output:

arr[0] = 9892
arr[1] = 9537
arr[2] = 5368
...

Sao chép mảng 1 chiều

Ý tưởng: Để tạo ra một bản sao từ một mảng, bạn cần khai báo thêm một mảng khác có cùng kích thước với mảng ban đầu.

Chương trình:

#include 
#include  // for srand() and rand()
#include  // for time()
#include 

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);
void saoChepMangMotChieu(int arrDest[], int arrSource[], int n);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng myArray tự động
  nhapMang(myArray, nSize);

  // xuất mảng myArray
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  int myArray2[MAX]; // mảng myArray2 có MAX phần tử

  // sao chép mảng myArray sang myArray2
  saoChepMangMotChieu(myArray2, myArray, nSize);

  // xuất mảng myArray2 sau khi sao chép
  cout << "myArray2: " << endl;
  xuatMang(myArray2, nSize);

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "array[" << i << "] = " << arr[i] << endl;
  }
}

// sao chép mảng nguồn sang mảng đích
void saoChepMangMotChieu(int arrDest[], int arrSource[], int n) {
  for (int i = 0; i < n; i++) {
    arrDest[i] = arrSource[i];
  }
}

Output:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...

myArray2:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...

Tìm kiếm phần tử trong mảng

Yêu cầu: Tìm xem phần tử x có nằm trong mảng myArray kích thước n hay không? Nếu có thì nó nằm ở vị trí đầu tiên nào?

Ý tưởng: Xét từng phần tử của mảng myArray. Nếu phần tử đang xét bằng x thì trả về vị trí đó. Nếu không tìm được thì trả về -1.

Chương trình:

#include 
#include  // for srand() and rand()
#include  // for time()
#include 

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);
int timKiemPhanTuDauTien(int arr[], int n, int x);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng myArray tự động
  nhapMang(myArray, nSize);

  // xuất mảng myArray
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  int x;
  cout << "Nhập phần tử x cần tìm: ";
  cin >> x;

  // tìm kiếm phần tử x đầu tiên trong mảng
  int idx = timKiemPhanTuDauTien(myArray, nSize, x);
  if (idx != -1)
    cout << "x nằm tại vị trí thứ " << idx << endl;

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "array[" << i << "] = " << arr[i] << endl;
  }
}

// tìm kiếm phần tử x đầu tiên trong mảng
int timKiemPhanTuDauTien(int arr[], int n, int x) {
  for (int i = 0; i < n; i++) {
    if (arr[i] == x)
      return i;
  }
  return -1;
}

Output 1:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...
Nhập phần tử x cần tìm: 9537
x nằm tại vị trí thứ 1

Output 2:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...
Nhập phần tử x cần tìm: 1000

Sắp xếp mảng 1 chiều

Yêu cầu: Cho trước mảng myArray kích thước n. Hãy sắp xếp mảng a đó sao cho các phần tử có giá trị tăng dần.

Ý tưởng: Sử dụng 2 biến ij để so sánh tất cả cặp phần tử với nhau và hoán vị các cặp nghịch thế (sai thứ tự).

Chương trình:

#include 
#include  // for srand() and rand()
#include  // for time()
#include 

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);
void hoanVi(int &a, int &b);
void sapXepTang(int arr[], int n);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng myArray tự động
  nhapMang(myArray, nSize);

  // xuất mảng myArray
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  // sắp xếp mảng tăng
  sapXepTang(myArray, nSize);

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "array[" << i << "] = " << arr[i] << endl;
  }
}

// hoán vị giá trị 2 biến số
void hoanVi(int &a, int &b) {
  int temp = a;
  a = b;
  b = temp;
}

// sắp xếp mảng tăng dần bằng thuật toán interchange sort
void sapXepTang(int arr[], int n) {
  for (int i = 0; i < n - 1; i++) {
    for (int j = i + 1; j < n; j++) {
      if (arr[i] > arr[j])
        hoanVi(arr[i], arr[j]);
    }
  }

  // xuất mảng sau khi sắp xếp
  cout << "myArray (sau khi sắp xếp): " << endl;
  xuatMang(myArray, nSize);
}

Output:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...

myArray (sau khi sắp xếp):
array[0] = 1002
array[1] = 1503
array[2] = 1684
...

Thêm và xóa một phần tử trong mảng

Thêm một phần tử vào mảng

Yêu cầu: Thêm phần tử x vào mảng myArray kích thước n tại vị trí idx.

Ý tưởng:

  • "Đẩy" các phần tử bắt đầu tại vị trí idx sang phải 1 vị trí.
  • Đưa x vào vị trí idx trong mảng.
  • Tăng n lên 1 đơn vị.

Chương trình:

#include 
#include  // for srand() and rand()
#include  // for time()
#include 

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);
void themMotPhanTuVaoMang(int a[], int &n, int idx, int x);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng myArray tự động
  nhapMang(myArray, nSize);

  // xuất mảng myArray
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  // thêm 1 phần tử vào mảng
  int idx;
  cout << "Nhap vi tri can them: ";
  cin >> idx;

  int x;
  cout << "Nhap gia tri can them: ";
  cin >> x;

  themMotPhanTuVaoMang(myArray, nSize, idx, x);

  // xuất mảng sau khi thêm
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "array[" << i << "] = " << arr[i] << endl;
  }
}

// thêm phần tử x vào mảng tại vị trí idx
void themMotPhanTuVaoMang(int a[], int &n, int idx, int x) {
  if (idx >= 0 && idx <= n) {
    for (int i = n; i > idx; i--) {
      a[i] = a[i - 1];
    }
    a[idx] = x;
    n++;
  }
}

Output:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...

Nhap vi tri can them: 2
Nhap gia tri can them: 1000
myArray:
array[0] = 9892
array[1] = 9537
array[2] = 1000
array[3] = 5368
...

Xóa một phần tử trong mảng

Yêu cầu: Xóa một phần tử trong mảng a kích thước n tại vị trí vt

Ý tưởng:

  • "Kéo" các phần tử bên phải vị trí idx sang trái 1 vị trí.
  • Giảm n xuống 1 đơn vị.

Chương trình:

#include 
#include  // for srand() and rand()
#include  // for time()
#include 

using namespace std;

// định nghĩa số phần tử mảng
#define MAX 1000

// khai báo prototype
void nhapMang(int arr[], int &n);
void xuatMang(int arr[], int n);
void xoaMotPhanTuTrongMang(int a[], int &n, int idx);

int main() {
  int myArray[MAX]; // mảng myArray có MAX phần tử
  int nSize; // nSize là số phần tử được sử dụng, do người dùng nhập

  // nhập mảng myArray tự động
  nhapMang(myArray, nSize);

  // xuất mảng myArray
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  // xóa một phần tử trong mảng tại vị trí idx
  int idx;
  cout << "Nhap vi tri can xoa: ";
  cin >> idx;

  xoaMotPhanTuTrongMang(myArray, nSize, idx);

  // xuất mảng sau khi xóa
  cout << "myArray: " << endl;
  xuatMang(myArray, nSize);

  return 0;
}

// hàm nhập mảng
void nhapMang(int arr[], int &n) {
  // khởi tạo số ngẫu nhiên
  srand(time(NULL));

  cout << "Nhập số lượng phần tử n: ";
  cin >> n;

  // khởi tạo ngẫu nhiên từng phần tử từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    arr[i] = rand();
  }
}

// hàm xuất mảng
void xuatMang(int arr[], int n) {
  // xuất từng phần tử của mảng từ chỉ số 0 đến n - 1
  for (int i = 0; i < n; i++) {
    cout << "array[" << i << "] = " << arr[i] << endl;
  }
}

// xóa một phần tử trong mảng tại vị trí idx
void xoaMotPhanTuTrongMang(int a[], int &n, int idx) {
  if (idx >= 0 && idx < n) {
    for (int i = idx; i < n - 1; i++) {
      a[i] = a[i + 1];
    }
    n--;
  }
}

Output:

myArray:
array[0] = 9892
array[1] = 9537
array[2] = 5368
...

Nhap vi tri can xoa: 1
myArray:
array[0] = 9892
array[1] = 5368
...

Kết luận

Qua bài học này, bạn đã biết được Các thao tác trên Mảng một chiều trong C++. Còn rất nhiều thao tác khác trên mảng 1 chiều, trong phạm vi bài học không thể đề cập hết được, các bạn hãy tự mình tìm hiểu và bình luận bên dưới để chia sẻ cho mọi người nhé.

Trong bài tiếp theo, mình sẽ giới thiệu cho các bạn về Mảng hai chiều (Multidimensional arrays) trong C++.

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập - Thử thách - Không ngại khó”.

Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần BÌNH LUẬN bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.

1