Truyền tham số mảng cho hàm

Một phần của tài liệu Đề Cương Môn Kỹ Thuật Lập Trình Trường Cao Đẳng Công Nghiệp Hà Nội (Trang 55 - 59)

Trong C++, cho phép viết các hàm có đối số là mảng như sác đối số thông thường. Tuy nhiên, khi truyền tham số là mảng, ta thường truyền thêm cả các biến là kích thước của mảng.

VD1: Viết chương trình thực hiện việc nhập một dãy số nguyên,

tính tổng các phần tử lẻ và in kết quả đó lên màn hình.

#include “stdio.h”

long Tong(int a[100], int n) {

long T=0;

for (int i=0; i<n; i++) if(a[i]%2==0) T+=a[i]; return T; } void main() { int b[100]; int n; cout<<”Nhập n”; cin>>n;

for(int i=0; i<n; i++) {

cout<<”Nhập b[“<<i<<”]”; cin>>b[i];

cout<<”Tổng các phần tử lẻ “<<Tong(b, n); getch(); } VD2: Viết chương trình nhập một ma trận n hàng, m cột. Tìm phần tử lớn nhất của ma trận và in ma trận vừa nhập cùng phần tử lớn nhất ra màn hình. #include…

double Max(double a[100][100], n, m) {

Max = a[0][0]; for(int i=0; i<n; i++) for(int j=0; j<m; j++) if (a[i][j]>Max) Max=a[i][j]; return Max; } void main() { double b[100][100]; int m, n; cout<<”Nhập n”; cin>>n; cout<<”Nhập m”; cin>>m; for(int i=0; i<n; i++)

for(int j=0; j<m; j++) { cout<<”b[“<<i<<”]= “; cin>>b[i][j]; } cout<<”Ma trận vừa nhập là “; for(int i=0; i<n; i++)

for(int j=0; j<m; j++)

cout<<”b[“<<i<<”]= “<<b[i][j];

cout<<”Phần tử lớn nhất : “<<Max(b, n, m); getch();

}

3. Các bài toán cơ bản về mảng

1. Bài toán trên mảng một chiều.

Bài 1: Viết chương trình nhập vào mảng n số nguyên và một số nguyên c. Cho biết có bao nhiêu số nguyên c trong mảng và vị trí của nó.

Bài 2: Viết chương trình nhập vào một mảng n phần tử nguyên. tính tổng các phần tử lẻ, chẵn, chia hết cho 3 trong mảng.

Biªn so¹n: NguyÔn M¹nh Cêng Trang 5 6

2. Bài toán trên mảng hai chiều.

Bài 1: Viết chương trình nhập vào 2 ma trận A, B cùng kích thước m x n các số nguyên. Tính và in ma trận C = A+B.

Bài 2: Ma trận B gọi là ma trận chuyển vị của A nếu B[i][j] = A[j][i]. Viết chương trình nhập vào một ma trận A có n dòng, m cột các phần tử thực. Tính và in ra ma trận chuyển vị của A.

4. Các giải thuật tìm kiếm, sắp xếp trên mảng

Bài toán tìm kiếm cơ bản được phát biểu như sau:

- Cho một mảng a gồm n phần tử và một khoá c. Hãy cho biết khoá c có xuất hiện trong a không? Nếu có, hãy chỉ ra một vị trí của c trong a.

Bài toán sắp xếp được phát biểu rất đơn giản:

- Cho một mảng a gồm n phần tử. Hãy sắp xếp mảng a theo thứ tự tăng dần (hoặc giảm dần).

Với hai bài toán đặc thù trên mảng như trên, việc tìm ra các phương pháp khác nhau để giải quyết là rất quan trọng. Sau đây sẽ lần lượt trình bày một số giải thuật cơ bản để giải quyết hai bài toán trên.

1. Tìm kiếm tuần tự

Một phương pháp đơn giản nhất để giải quyết bài toán tìm kiếm là tìm kiếm tuần tự. Theo phương pháp này, ta chỉ cần duyệt từ đầu đến cuối mảng. Nếu gặp khoá c, sẽ in ra vị trí của c (tức là chỉ số của phần tử c trong mảng). Ngược lại, khi duyệt hết mảng mà không tìm thấy c, tức là c không xuất hiện trong mảng. Như vậy, độ phức tạp của thuật giải là O(n).

int d=0;

ìor (i =0; i< n; i++) if (a[i]==c)

{

cout<<” Vị trí tìm được c “<<i+1; d++;

} if (d==0)

Đôi khi, cần phải nắm được tất cả các vị trí xuất hiện c, ta sử dụng một mảng VT[] đồng hành để lưu các vị trí đã tìm được c. Như vậy, thay bằng việc in vị trí tìm được ra màn hình, ta lưu vị trí đó trong mảng VT: VT[d] = i+1;

2. Tìm kiếm nhị phân trên mảng được sắp

Phương pháp này chỉ áp dụng trên mảng đã được sắp. ý tưởng có thể hình dung như sau:

Giả sử ta cần tìm kiếm c trong một đoạn từ vị trí L tới vị trí R trên một mảng a được sắp:

Khi đó, ta chia mảng a làm hai phần bởi điểm chia M: M = (L+R)/ 2

Ta áp dụng tìm kiếm trên 2 nửa của a. Tuy nhiên, do a đã được sắp nên chỉ có thể sảy ra 3 trường hợp sau:

[1]. Nếu a[M] = c thì ta đã tìm được c trong mảng. Vị trí của c là M. [2]. Nếu a[M] > c thì c thuộc về nửa trái của mảng a. Khi đó ta áp dụng tìm kiếm trên nửa trái, tức là từ vị trí L tới M-1.

[3]. Nếu a[M] < c thì c thuộc về nửa phải của mảng a. Khi đó ta áp dụng tìm kiếm trên nửa phải, tức là từ vị trí M+1 tới R.

Việc tìm kiếm trên các nửa của a cũng áp dụng phương pháp chia đôi tương tự như trên. Như vậy, ngay từ đầu ta áp dụng tìm kiếm nhị phân trên toàn mảng a (L=0; R=n-1). Hàm tìm kiếm nhị phân lặp sau đây trả về giá trị -1 nếu không tìm thấy c trong a; ngược lại, nó trả về vị trí của c trong a.

int TKNP_Lap(int a[100], int n, int c) { int L, R, M; L =0; R = n-1; do { M = (L+R)/2; if (a[M] > c) L = M+1;

Biªn so¹n: NguyÔn M¹nh Cêng Trang 5 8

L mảng a R

if (a[M] < c) R = M-1; }

while (L<R && a[M]!=c);

if (a[M] ==c) return M; else

return -1; }

Rõ ràng là trong trường hợp này, việc áp dụng đệ quy là rất phù hợp. Sau đây ta xem xét khả năng áp dụng đệ quy với thiết kế sau:

B1: Suy biến trong trường hợp L > R hoặc a[M] = c. Khi đó

Một phần của tài liệu Đề Cương Môn Kỹ Thuật Lập Trình Trường Cao Đẳng Công Nghiệp Hà Nội (Trang 55 - 59)