1. Trang chủ
  2. » Công Nghệ Thông Tin

Kỹ thuật lập trình - Mảng và các giải thuật với mảng pot

9 358 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 110,96 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Chương 4Mảng & các giải thuật với mảng Đặt vấn đề Trong rất nhiều bài toán chúng ta cần thao tác trên một dãy hoặc một bảng, .... gồm hữu hạn các phần tử cùng kiểu.. - một ma trận: có c

Trang 1

Chương 4

Mảng & các giải thuật với mảng

Đặt vấn đề

 Trong rất nhiều bài toán chúng ta cần thao tác trên một dãy (hoặc một bảng, ) gồm hữu hạn các phần tử cùng kiểu Chẳng hạn:

- một lớp học: có các phần tử là sinh viên.

- một ma trận: có các phần tử là số thực.

chính là mảng.

có cùng một kiểu dữ liệu.

Đặt vấn đề (tt)

Thông tin về sinh viên được lưu trữ trong một phần tử

dãy sinh viên

ma trận

Khai báo mảng

 Ví dụ:

//mảng 1 chiều gồm 10 ptử a[0]->a[9]:

int a[10];

//mảng 2 chiều gồm 12 phần tử b[0][0]->b[2][3]: float b[3][4];

<kiểu phần tử> <tênbiếnmảng>[giớihạnchiều1] [giớihạnchiềuk]

Trang 2

Lưu trữ mảng

 Mảng được lưu trữ ở một vùng nhớ liên

tục trong RAM.

 Hệ thống sẽ quản lý địa chỉ phần tử đầu

tiên (thứ 0) của mảng, từ đó có thể truy

xuất đến phần tử bất kỳ bằng cách tính

ra địa chỉ của phần tử đó.

 Theo quy ước: tên mảng chính là địa chỉ

của phần tử đầu tiên của mảng.

a == &a[0]

Lưu trữ mảng (tt)

thể hiện logic

thể hiện vật lý trong RAM

Địa chỉ gốc của mảng

Truy xuất mảng

 Quy tắc: truy xuất mảng thông qua từng phần

tử của nó.

 Ví dụ 1: Giả sử có int a[10], b[3][4];

khi đó:

- để truy xuất đến phần tử thứ i của a ta dùng

cú pháp sau: a[i]

- tương tự: cú pháp b[i][j] để truy xuất đến phần

tử ở dòng i, cột j của ma trận b.

<tênbiếnmảng>[chỉ số1] [chỉ sốk]

Truy xuất mảng (tt)

 Ví dụ 2: Hàm sau đây sẽ nhập dữ liệu cho mảng n số nguyên (giả sử a và n được khai báo toàn cục) void nhapDL()

{ int i;

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

printf(“\nphan tu thu %d = “,i);

scanf(“%d”,&a[i]);

} }

Trang 3

Mảng và con trỏ

 Trong trường hợp mảng dùng làm tham số cho một hàm ta có 2

cách sử dụng sau:

 Cách 1: Sử dụng khai báo hình thức.

 Ví dụ 1:

void nhapDL(int a[], int n)

{

int i;

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

{

printf(“\nphan tu thu %d = “,i);

scanf(“%d”,&a[i]);

}

}

Khai báo hình thức (không cần chỉ rõ kích thước)

Mảng và con trỏ (tt)

 Ví dụ 2: hàm in ma trận b, n dòng, m cột ra màn hình (giả sử b được khai báo số cột là 10).

void inMT(int b[][10], int n, int m) {

int i,j;

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

for(j=0;j<m;++j)printf(“%5d”,a[i][j]);

printf(“\n”);//xuống dòng mới }

}

Đối với mảng 2 chiều, cần chỉ

rõ số cột khai báo (tại sao?)

Mảng và con trỏ (tt)

 Khi đó các hàm trên có thể sử dụng như

sau:

 int a1[100], a2[10][10], n, dong, cot;

nhapDL(a,n);

inMT(b,dong,cot);

Mảng và con trỏ (tt)

 Cách 2: Sử dụng con trỏ làm tham số hình thức cho

mảng.

 Ví dụ 1:

void nhapDL(int *p, int n) {

int i;

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

printf(“\nphan tu thu %d = “,i);

scanf(“%d”, p+i );

} }

Trang 4

Mảng và con trỏ (tt)

 Giải thích:

int x[100], n;

lời gọi hàm nhập dữ liệu sẽ có dạng:

nhapDL(x,n);

Suy ra:

p=x=&x[0]

p+i = &x[i]

*(p+i) = x[i]

p[i] = x[i]

Mảng và con trỏ (tt)

void inMT(int *p, int n, int m) {

int i,j;

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

for(j=0;j<m;++j)printf(“%5d”,*(p+10*i+j)); printf(“\n”);

} }

Mảng và con trỏ (tt)

2 0 1 4

4 5 10 3

lưu trữ logic của a2

giải thích:

Mảng và con trỏ (tt)

lưu trữ vật lý trong RAM của a2

2 0 1 4 4 5 10 3

Trang 5

Các giải thuật trên mảng

 Tính toán trên mảng:

 Ví dụ 1: Tính tổng các phần tử dương

của mảng nguyên a, n phần tử.

int tongDuong(int *p, int n) {

int i,t=0;

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

if(p[i]>0)t+=p[i];

return t;

}

Các giải thuật trên mảng (tt)

i=2 t=2+a[2]=3 i=3 t=3+a[3]=7

i=5 t=7+a[5]=9

i=7 t=9+a[7]=10

2 0 1 4 -3 2 -8 1

0 1 2 3 4 5 6 7

Các giải thuật trên mảng (tt)

 Tìm max-min:

 Cho mảng a, n số nguyên Hãy tìm chỉ

số của phần tử lớn nhất.

int max(int *p, int n) {

int i,m=0;

for(i=1;i<n;++i)

if(p[m]<p[i])m=i;

return m;

}

Các giải thuật trên mảng (tt)

 Giải thích:

2 0 1 4 -3 2 -8 1

0 1 2 3 4 5 6 7

i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7

m=0 m=0 m=0 m=3 m=3 m=3 m=3 m=3

Trang 6

Các giải thuật trên mảng (tt)

 Tìm kim:

 Cho mảng a, n số nguyên Tìm vị trí xuất

hiện phần tử x.

int timKiem(int *p, int n, int x)

{

int i=0;

while(i<n&&p[i]!=x)++i;

if(i<n) return i;

else return -1; //quy ước.

}

Các giải thuật trên mảng (tt)

 Giải thích:

2 0 1 4 -3 2 -8 1

0 1 2 3 4 5 6 7

i=0 i=1 i=2

x!=a[0]

x!=a[1]

x=a[2]

x=1

Các giải thuật trên mảng (tt)

 Sắp xếp:

 Cho dãy a, n số nguyên Yêu cầu sắp

xếp các phần tử của dãy theo thứ tự

tăng dần.

 Ở đây trình bày 2 phương pháp sắp xếp:

- Phương pháp chọn (selection).

- Phương pháp hoán đổi trực tiếp

(interchange).

Phương pháp sắp xếp chọn

a[0] -> a[n-1] rồi hoán vị min với a[0].

a[1] -> a[n-1] rồi hoán vị min với a[1].



 Bước i: Tìm phần tử min trong các phần tử a[i] -> a[n-1] rồi hoán vị min với a[i].



a[n-1] rồi hoán vị min với a[n-2].

Trang 7

Phương pháp sắp xếp chọn (tt)

2 0 1 4 -3 2 -8 1

0 1 2 3 4 5 6 7

-8 0 1 4 -3 2 2 1

0 1 2 3 4 5 6 7

-8 0 1 4 -3 2 2 1

0 1 2 3 4 5 6 7

-8 -3 1 4 0 2 2 1

0 1 2 3 4 5 6 7

-8 -3 1 4 0 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 4 1 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 4 1 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 1 4 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 1 4 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

trước khi hoán vị sau khi hoán vị

Minh họa:

Phương pháp sắp xếp chọn (tt)

void selection(int a[], int n) {

int i,j,t,m;

for(i=0;i<n-1;++i) {

m=i;

for(j=i+1;j<n;++j)

if(a[m]>a[j])m=j;

if(m!=i) {

t=a[m];

a[m]=a[i];

a[i]=t;

} } }

Cài đặt

Phương pháp interchange

 Tư tưởng: tượng tự phương pháp

selection Nhưng tại mỗi bước thay vì

hoán vị a[i] với phần tử min tìm được thì

a[i] sẽ được hoán vị lần lượt với các

phần tử nhỏ hơn nó để cuối cùng a[i]

chính là min.

Phương pháp interchange (tt)

2 0 1 4 -3 2 -8 1

0 1 2 3 4 5 6 7

-8 2 1 4 0 2 -3 1

0 1 2 3 4 5 6 7

-8 -3 2 4 1 2 0 1

0 1 2 3 4 5 6 7

-8 -3 0 4 2 2 1 1

0 1 2 3 4 5 6 7

-8 -3 0 1 4 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 1 1 4 2 2

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 4 2

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 2 4

0 1 2 3 4 5 6 7

trước khi hoán vị sau khi hoán vị a[i] với các

phần tử nhỏ hơn

-8 2 1 4 0 2 -3 1

0 1 2 3 4 5 6 7

-8 -3 2 4 1 2 0 1

0 1 2 3 4 5 6 7

-8 -3 0 4 2 2 1 1

0 1 2 3 4 5 6 7

-8 -3 0 1 4 2 2 1

0 1 2 3 4 5 6 7

-8 -3 0 1 1 4 2 2

0 1 2 3 4 5 6 7

-8 -3 0 1 1 2 4 2

0 1 2 3 4 5 6 7 Minh họa:

Trang 8

Phương pháp interchange (tt)

void interchange(int a[], int n)

{

int i,j,t;

for(i=0;i<n-1;++i)

for(j=i+1;j<n;++j)

if(a[i]>a[j]) {

t=a[i];

a[j]=a[i];

a[i]=t;

} }

Cài đặt

Ví dụ về mảng 2 chiều

 Ví dụ 1: Cho ma trận nguyên A, n dòng,

m cột Hãy viết các hàm:

- Tính tổng các phần tử dương của A.

- Đếm số phần tử trên đường chéo chính

là số nguyên tố.

- Tìm phần tử max của mảng.

Ví dụ về mảng 2 chiều (tt)

//hàm tính tổng các phần tử dương:

int tongDuong(int *p, int n, int m, int M)

{

int i,j,t=0;

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

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

if(*(p+M*i+j)>0)t+=*(p+M*i+j);

return t;

}

Ví dụ về mảng 2 chiều (tt)

//hàm đếm số phần tử là số nguyên tố trên //đường chéo chính:

int demNT(int *p, int n, int m, int M) {

int i,j,d=0;

if(n!=m)return -1;//không có đường chéo

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

j=2;

while(*(p+M*i+i)%j)++j;

if(j==*(p+M*i+i))++d; //nếu là số nguyên tố thì đếm

} return d;

}

Trang 9

Ví dụ về mảng 2 chiều (tt)

//hàm tìm phần tử max:

int timMax(int *p, int n, int m, int M)

{

int i,j,d,c;

d=c=0;

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

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

if(*(p+i*M+j)>*(p+d*M+c)) {

d=i;

c=j;

} return *(p+M*d+c);

}

Hỏi đáp

Ngày đăng: 05/07/2014, 12:21

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w