dsdac1 - HOA CUONG

Download Report

Transcript dsdac1 - HOA CUONG

•Xin vui lòng yên lặng
1
Chương 1:
Các kiểu dữ liệu cơ bản và cấu trúc
2
Định nghĩa và các phép toán trên
danh sách đặc
• Định nghĩa
• Cách biểu diễn và các phép toán trên danh sách
đặc
-
Khởi tạo danh sách
Thêm một phần tử vào danh sách
Loại bỏ một phần tử của danh sách
Tìm kiếm một phần tử của danh sách
Duyệt danh sách
3
1. Mảng (Array) – Định nghĩa
• Định nghĩa: Mảng là cấu trúc bao gồm các thành
phần cùng kiểu dữ liệu, mỗi thành phần được
gọi là phần tử và xác định qua chỉ số.
Trong C/C++ khai báo:
elem a[spt];
Trong đó elem là kiểu phần tử (element type); spt là số
phần tử.
Ví dụ:
int a[10];
float b[20];
//mảng a gồm 10 phần tử kiểu int
//mảng b gồm 20 phần tử kiểu float
4
Tổ chức lưu trữ
• Mảng được quản lý bằng một địa chỉ trong
bộ nhớ máy tính và các phần tử được bố
trí tuần tự liên tiếp theo chỉ số
0
1
2
9
a
• Chính vì vậy dãy dữ liệu lưu trữ trong
mảng còn được gọi là danh sách đặc
5
Truy xuất
• Truy xuất mảng: Truy xuất qua các phần
tử của mảng theo chỉ số i.
Trong C/C++:
<tên mảng>[i]
Bằng cách tính địa chỉ:
@a + i * sizeof(elem)
0
1
2
3
9
a
1000
1006
Ví dụ: a[3] truy xuất đến địa chỉ: 1000+3*2
6
Ví dụ
• Viết đoạn chương trình cộng dồn n giá trị
của mảng vào a[0]
for (i=1; i<n; i++)
a[0] = a[0]+a[i];
Viết lại
t = a[0];
for (i=1; i<n; i++)
t = t+a[i];
a[0] = t;
7
Mảng nhiều chiều
• Là mảng bao gồm các phần tử có kiểu là
mảng
vd: int a[3][4];
0
1
2
3
0
1
a
a[0]
a[1]
a[2]
Vd: viết hàm tìm max của mảng số nguyên
8
int max( int a[ ], int n)
{
int m = a[0];
for (int i=1; i<n; i++)
if (a[i]>m)
m = a[i];
return m;
}
9
0
1
2
3
0
1
b
b[0]
b[1]
b[2]
void main()
{
int b[3][4] = { { 7, 12, 6, 8},
{ 32, 17, 21, 23},
{ 1, 5, 35, 32}};
int a[] = {9, 7, 18, 6, 1, 3, 2, 5, 11, 4};
printf("\nMax cua b: %d", max(b[0], 12));
printf("\nMax cua a: %d", max(a, 10));
printf("\nMax : %d", max(a+5, 5));
}
10
Con trỏ?
• Con trỏ: Là kiểu dữ liệu dang địa chỉ bộ nhớ
máy tính
• Biến con trỏ: Lưu trữ địa chỉ của vùng nhớ
máy tính
• Khai báo:
<type> *<pointer_var>
Ví dụ:
float *pa, a, b;
*pa
pa
11
Các phép toán
• Toán tử &:
Lấy địa chỉ của 1 đối tượng
&<object>
Ví dụ:
float *pa, a, b;
pa = &a;
*pa
a
pa
12
Các phép toán
• Toán tử *:
Truy xuất đến vùng nhớ mà con trỏ trỏ đến
*<pointer>
Ví dụ:
float *pa, a, b;
pa = &a;
*pa = 5;
5
*pa
a
pa
13
Mảng và con trỏ
• Mảng được quản lý bằng địa chỉ
• Con trỏ lưu địa chỉ
Vì vậy, trong một số tình huống con trỏ được
đồng nhất với mảng và ngược lại
Ví dụ:
int a[10], *pa;
pa = a;
pa
0
1
2
3
9
a
14
Mảng và con trỏ - tt

*pa = 5;
a[0]=5
pa
0
a
1
2
3
9
5
pa = &a[5];
*pa = 7;

a[5]=7
pa
0
a
5
1
2
3
9
7
15
Phép toán +, -, ++, -• Phép +/-: Tăng hay giảm n đơn vị trỏ
<pointer> = <pointer> + n
<pointer> += n
n là số nguyên
• Phép ++/--: Tăng hay giảm 1 đơn vị trỏ
<pointer> ++
++<pointer>
Ví dụ:
pa = a;
16
Ví dụ:
pa = a;
pa
0
a
1
2
3
9
5
pa = pa+3;
pa
0
a
1
2
3
9
5
17
*pa=1;
 a[3]=1
*(pa+4) = 2
 a[7]=2
*(a+4) = 9
 a[4]=9
pa[5] = 6
 a[8]=6
a++;
// Sai, a không thay đổi được
pa
0
a
5
1
2
3
1
9
9
2
6
18
Cấp phát/thu hồi bộ nhớ
• Cấp phát bộ nhớ động
– C: hàm malloc()
(void *)malloc(int size)
Cấp vùng nhớ có size byte trả về địa chỉ của vùng nhớ
được cấp phát
– C++: toán tử new
new <type>[size]
[size] là thành phần nhiệm ý
Cấp vùng nhớ có size phần tử trả về địa chỉ của
vùng nhớ được cấp phát
Ví dụ cấp phát mảng 10 phần tử nguyên
19
int *pa = new int[10];
Cấp phát/thu hồi bộ nhớ - tt
• Thu hồi bộ nhớ
– C: hàm free()
void free(<pointer>)
– C++: toán tử delete
delete [size]<type>
[size] là thành phần nhiệm ý
Thu hồi vùng nhớ mà con trỏ trỏ đến
Ví dụ thu hồi vùng nhớ mà con trỏ pa trỏ đến
delete pa [10]int;
20
Chuỗi ký tự (String)
• Định nghĩa: Là 1 dãy các ký tự chọn lọc
• Cài đặt: Dựa trên mảng các ký tự, có 2 cách
cài đặt
– Cách 1: Sử dụng byte đầu tiên để lưu chiều dài
chuỗi (Pascal sử dụng cách này).
Ví dụ chuỗi “TIN HOC”
0
1
2
3
#7
T
I
N
S[8]=‘A’
S[2]=‘A’
4
5
H
6
7
O
C
 S=“TIN HOC”
 S=“TAN HOC”
8
21
–Cách 2: Sử dụng 1 ký tự đặc biệt làm
ký tự kết thúc chuỗi (C/C++ sử dụng
cách này).
Ví dụ chuỗi “TIN HOC”
0
1
2
T
I
N
3
4
5
6
7
H
O
C
\0
8
‘\0’: kí tự có mã ASCii là 0
S[1]=‘A’
 S=“TAN HOC”
22
Các thao tác trên chuỗi
•
•
•
•
•
•
Sao chép chuỗi (strcpy)
So sánh chuỗi (strcmp)
Chiều dài chuỗi (strlen)
Ghép chuỗi (strcat)
Tìm kiếm vị trí chuỗi trong chuỗi (strstr)
…..
23
VD sao chép chuỗi
void strcpy(char s1[], char s2[])
{
int i = 0;
while (s2[i] != ‘\0’)
{
s1[i] = s2[i];
i++;
}
s1[i] = ‘\0’;
}
24
VD sao chép chuỗi – viết lại
void strcpy(char s1[], char s2[])
{
int i = 0;
while (s1[i] = s2[i])
i++;
}
25
VD sao chép chuỗi – viết lại lần cuối
void strcpy(char *s1, char *s2)
{
while (*s1++ = *s2++);
}
• Ghép s2 vào cuối s1
void strcat(char *s1, char *s2)
{
while (*s1) s1++;
while (*s1++ = *s2++);
}
26
Ghép chuỗi – viết theo bản 2
void strcat(char s1[], char s2[])
{
int i = 0, j=0;
while (s1[i]) i++;
while (s1[i++] = s2[j++]);
}
27
Đổi chuỗi thành số
int atoi(char *s)
{
int P = 0;
while (*s)
P = P*10 + *s++ -’0’;
return P;
}
28
So sánh 2 chuỗi
int strcmp(char *s1, char *s2)
{
while (*s1 == *s2 && *s1)
{
s1++;
s2++;
}
return *s1-*s2;
}
29
Trừu tượng hóa dữ liệu
• Thiết kế 1 cấu trúc dữ liệu cần đạt được tính
trừu tượng hóa dữ liệu:
– Dữ liệu phải được đóng gói: Người lập trình chỉ biết
kiểu dữ liệu qua tên gọi và ngữ nghĩa của nó mà
không quan đến tổ chức vật lý
– Che chắn tốt: Người lập trình chỉ truy xuất đến nó
thông qua các thao tác (hàm) mà kiểu dữ liệu cung
cấp.
• Người thiết kế phải thiết kế kiểu dữ liệu tổng
quát nhất
30
Ví dụ: Thiết kế kiểu tập hợp
#define MAX …
// do người sử dụng xác định
#define N (MAX/8+1)
typedef unsigned char taphop[N];
//============== Tao tap rong =========
void taprong(taphop s)
{
int i;
for (i=0; i<N; i++)
s[i] = 0;
}
31
//========== Dua phan tu x vao tap hop s
void thempt(taphop s, int x)
{
s[x/8] = s[x/8] | (1<<(x%8));
}
//========== Loai phan tu x ra khoi tap hop s
void loaipt(taphop s, int x)
{
unsigned char k = 1<<(x%8);
s[x/8] = s[x/8] & ~k;
}
32
//========== Kiem tra phan tu x thuoc tap hop s
int thuocve (taphop s, int x)
{
return s[x/8] & (1<<(x%8));
}
//========== Hội 2 tap hop
void hoi(taphop a, taphop b, taphop c)
{
int i;
for (i=0; i<N; i++)
c[i] = a[i] | b[i];
}
Các hàm này lưu vào tập tin “TAPHOP.CPP” và không compile
33
Ví dụ: Tìm các số nguyên tố<=n
#include <iostream.h>
#include <iomanip.h>
#define MAX 10000
#include "TAPHOP.CPP"
void main()
{
int n, i, k;
taphop s;
cout<<"\nNhap n:";
cin>>n;
taprong(s);
for (i=2; i<=n; i++)
thempt(s, i);
i = 2;
while (i*i<=n)
{
k = i*i;
while (k<=n)
{
loaipt(s, k);
k = k+i;
}
do
i++;
while (!thuocve(s, i));
}
cout<<"\nKet qua:\n";
for (i=2; i<=n; i++)
if (thuocve(s, i))
cout<<setw(4)<<i;
}
34
35