Giới thiệu
Trong 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 ngôn ngữ lập trình C++.
Nội dung
Để hiểu bài học này tốt nhất, bạn nên có kiến thức cơ bản về:
- Vòng lặp for trong C++
- Mảng một chiều trong C++
Trong bài học này, chúng ta sẽ tìm hiểu về các vấn đề sau:
- Truyền mảng vào hàm
- Nhập và xuất mảng một chiều
- Sao chép mảng một chiều
- Tìm kiếm phần tử trong mảng
- Sắp xếp mảng một chiều
- Thêm và xóa một phần tử trong mảng
Truyền mảng vào hàm (passing arrays to functions)
Trong bài TRUYỀN GIÁ TRỊ CHO HÀM (Passing Arguments by Value), chúng ta đã biết rằng khi một biến được 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à một bản sao, việc thay đổi giá trị tham số không làm thay đổi giá trị đối số ban đầu.
Tuy nhiên, đối với kiểu dữ liệu mảng, việc sao chép một 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. Do đó, 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.
- 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.
- Số lượng phần tử thực sự truyền qua biến khác nhau.
Dưới đây là một ví dụ về truyền mảng vào hàm:
void NhapMang(int a[100]); void NhapMang(int a[]); void NhapMang(int *a); 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 một chiều
Dưới đây là một ví dụ về nhập, xuất dữ liệu cho mảng một 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 user nhập // nhập xuất mảng tự động nhapMang(myArray, nSize); 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 << "Nhap so luong phan tu 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ử cho mảng từ chỉ số 0 đến n - 1 for (int i = 0; i < n; i++) { cout << "arr[" << i << "] = " << arr[i] << endl; } }
Output:
Sao chép mảng một 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.
Dưới đây là một ví dụ về sao chép mảng một chiều:
#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 user 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 << "Nhap so luong phan tu 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ử cho 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:
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 có kích thước n hay không? Nếu có, 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.
Dưới đây là một ví dụ về tìm kiếm phần tử trong mảng:
#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 user 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 << "Nhap phan tu x can tim: "; 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 nam tai vi tri thu " << 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 << "Nhap so luong phan tu 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ử cho 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:
Output 2:
Sắp xếp mảng một chiều
Yêu cầu: Cho trước mảng myArray có 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 i và j để 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ự).
Dưới đây là một ví dụ về sắp xếp mảng một chiều:
#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 user 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 << "Nhap so luong phan tu 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ử cho 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]); } } }
Output:
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 có 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ị.
Dưới đây là một ví dụ về thêm một phần tử vào mảng:
#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 user 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 << "Nhap so luong phan tu 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ử cho 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:
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 có 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ị.
Dưới đây là một ví dụ về xóa một phần tử trong mảng:
#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 user 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 << "Nhap so luong phan tu 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ử cho 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:
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++. Tuy còn rất nhiều thao tác khác trên mảng một chiều, trong phạm vi bài học không thể đề cập hết được. Hãy tự mình tìm hiểu và bình luận dưới đây để chia sẻ cho mọi người nhé.
Trong bài tiếp theo, chúng ta sẽ giới thiệu 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 hoặc 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.