Ỹ
Ậ
Ậ
K THU T L P TRÌNH Chương 2 Kỹ thuật xử lý dữ liệu có cấu trúc (12 tiết)
minhthai@huflit.edu.vn, www.minhthai.edu.vn
Ầ Ạ
phamducthanh@huflit.edu.vn,
TR N MINH THÁI – Ứ PH M Đ C THÀNH – www.phamthao.com
1 9/17/16 Trần Minh Thái - Phạm Đức Thành
Nội dung
v 2.1. Giới thiệu v 2.2. Kỹ thuật xử lý và tổ chức dữ liệu biểu
diễn danh sách
v 2.3. Kỹ thuật xử lý mảng v 2.4. Thuật toán xử lý chuỗi v 2.5. Phương pháp biểu diễn đồ thị và
thuật toán cơ bản
v 2.6. Tổ chức dữ liệu biểu diễn cấu trúc
cây
v 2.7. Tóm tắt chương
2 9/17/16 Trần Minh Thái - Phạm Đức Thành
[2.1] Giới thiệu
v Tìm hiểu về các kỹ thuật xử lý trên kiểu dữ diệu người dùng tự định nghĩa như: danh sách (list), mảng (array), chuỗi (string), cây (tree)..
v C# hỗ trợ rất tốt về dữ liệu có cấu trúc và các
thao tác trên đó thông qua: Ø Namespace System.Collections. Ø Namespace System.Collections.Generic.
3 9/17/16 Trần Minh Thái - Phạm Đức Thành
[2.2] Kỹ thuật xử lý và tổ chức dữ liệu biểu diễn danh sách
v Khái niệm. v Tổ chức dữ liệu bằng danh sách (list). v Kỹ thuật xử lý danh sách.
4 9/17/16 Trần Minh Thái - Phạm Đức Thành
Khái niệm danh sách
v Một tập sắp theo thứ tự các phần tử có cùng
kiểu.
v Cấu trúc dữ liệu tuyến tính, trong đó các phần tử dữ liệu được sắp theo một thứ tự xác định.
5 9/17/16 Trần Minh Thái - Phạm Đức Thành
Khái niệm danh sách
v Một số thao tác:
Ø Kiểm tra danh sách có rỗng không. Ø Đếm số phần tử theo tiêu chí xác định
trước.
Ø Tìm một phần tử trong danh sách. Ø Chèn một phần tử vào danh sách. Ø Xóa một phần tử khỏi danh sách. Ø Sắp xếp theo tiêu chí nào đó...
v Các phép toán trên danh sách không phụ thuộc vào kiểu dữ liệu của phần tử trong danh sách.
6 9/17/16 Trần Minh Thái - Phạm Đức Thành
Khái niệm danh sách
v Ví dụ:
Ø Danh sách sinh viên. Ø Danh sách diện thoại (danh bạ điện thoại). Ø Danh sách môn học. Ø Danh sách nhân viên. Ø Danh sách hàng hóa (danh mục hàng hóa).
7 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu bằng danh sách
v Cú pháp: Danh sách
List list = new List();
v Ví dụ, khai báo danh sách số nguyên
List list = new List();
8 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu bằng danh sách
v Ví dụ, khai báo danh sách có tên list là danh
sách chứa các sinh viên.
struct sinhVien
{
public string maSV, hoTen;
public DateTime ngaySinh;
public string diaChi, maLop;
}
List list = new List();
9 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu bằng danh sách
linkList
=
new
v Danh sách liên kết:
class Node
{
int key;
Node next;
}
LinkedList
LinkedList();
10 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Kiểm tra danh sách rỗng: if (list.Count == 0)
Console.WriteLine("Danh sách rỗng");
else
Console.WriteLine("Danh sách không rỗng");
11 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Thêm một phần tử vào danh sách:
list.Add(100);
v Thêm nhiều phần tử vào danh sách:
list.AddRange(new int[] { 33, 44, 55 });
12 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Chèn phần tử vào cuối danh sách: list.Insert(list.Count, 9999); v Truy xuất đến các phần tử trong danh sách: foreach (int x in list)
Console.WriteLine(x);
13 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Đếm số phần tử bằng giá trị X cho trước: int X = 5, dem = 0; foreach (int ai in list) if (ai == X) dem++; Console.WriteLine("Co {0} phan tu bang {1}", dem, X);
14 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Tìm một phần tử có giá trị X cho trước: int index=list.IndexOf(X); if (index == -1) Console.WriteLine("Tim khong thay"); else Console.WriteLine("Tim thay");
15 9/17/16 Trần Minh Thái - Phạm Đức Thành
Kỹ thuật xử lý danh sách
v Chèn một phần tử vào danh sách:
list.Insert(3, 5); v Xóa một phần tử khỏi danh sách tại vị trí xác
định:
list.RemoveAt(4);
v Sắp xếp danh sách:
list.Sort();
16 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Cho danh sách các mặt hàng, mỗi mặt hàng gồm các thông tin: mã hàng, tên hàng, số lượng, đơn giá, ngày nhập hàng. Hãy viết các hàm: v Nhập danh sách các mặt hàng v In danh sách các mặt hàng được nhập vào
cách đây ít nhất 10 ngày
v Sắp xếp danh sách các mặt hàng theo thứ tự
tăng dần của tên hàng
17 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Khai báo cấu trúc mặt hàng
struct MatHang {
public string maHang; public string tenHang; public DateTime ngayNhap;
public int soLuong;
public int donGia; }
18 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Nhập thông tin của một mặt hàng
static void NhapMatHang(out MatHang x) {
Console.Write("- Nhap ma hang: "); x.maHang = Console.ReadLine(); Console.Write("- Nhap ten hang: "); x.tenHang = Console.ReadLine(); Console.Write("- Nhap so luong: "); x.soLuong = int.Parse(Console.ReadLine()); Console.Write("- Nhap don gia: "); x.donGia = int.Parse(Console.ReadLine()); Console.Write("- Nhap vao ngay nhap hang (dd/mm/yyyy):
");
string ngay = Console.ReadLine(); x.ngayNhap = DateTime.Parse(ngay);
19 } 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Nhập danh sách mặt hàng
static void NhapDanhSach(List
MatHang x; char nhap; do {
NhapMatHang(out x); dshang.Add(x); Console.Write("Nhap tiep mat hang (Y/N)?: "); nhap = char.Parse(Console.ReadLine());
} while (nhap == 'Y' || nhap == 'y');
}
20 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Xuất thông tin mặt hàng
static void XuatMatHang(MatHang mh) {
Console.Write("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}", mh.maHang, mh.tenHang, mh.soLuong, mh.donGia,
mh.ngayNhap.ToShortDateString());
}
static void XuatDanhSach(List
Console.WriteLine("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}",
"Ma hang", "Ten hang", "So luong", "Don gia", "Ngay nhap");
foreach (MatHang x in dsmh)
{
XuatMatHang(x); Console.WriteLine();
}
}
21 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
Xuất mặt hàng được nhập ít nhất 10 ngày & sắp xếp theo tên hàng
static void XuatMHNhapTu10Ngay(List
Console.WriteLine("{0, 8}|{1, 15}|{2, 8}|{3, 8}|{4, 8}",
"Ma hang", "Ten hang", "So luong", "Don gia", "Ngay nhap"); foreach (MatHang mh in dsmh)
{
if ((DateTime.Now - mh.ngayNhap).Days >= 10)
{
XuatMatHang(mh);
Console.WriteLine();
}
}
} static int SoSanhMhTheoTen(MatHang x, MatHang y) {
return x.tenHang.CompareTo(y.tenHang);
22 } 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập ví dụ
static void Main(string[] args) {
List
it nhat 10 ngay:");
ắ ế ầ
XuatMHNhapTu10Ngay(dsmh); //S p x p danh sách mặt hàng tăng d n theo tên hàng dsmh.Sort(SoSanhMhTheoTen); Console.WriteLine("\nDanh sach mat hang duoc sap tang
theo ten hang:");
XuatDanhSach(dsmh);
}
23 9/17/16 Trần Minh Thái - Phạm Đức Thành
ả ử Gi s ngày ươ ạ ch y ch ng trình là 23/02/2016
24 9/17/16 Trần Minh Thái - Phạm Đức Thành
Bài tập về nhà
Bổ sung vào chương trình của bài tập ví dụ một số chức năng sau: v Nhập vào mã số mặt hàng x, tìm và in ra thông tin mặt hàng và tổng tiền có mã số x (nếu có)
v Chèn thêm thông tin một mặt hàng p sao cho danh sách mặt hàng vẫn có thứ tự tăng dần theo tên hàng
v Cập nhật giá mới cho mặt hàng có mã số x
sao cho tăng thêm 15% so với giá cũ
v Xóa mặt hàng có ngày nhập vào là d (nếu có) v Sắp xếp danh sách mặt hàng giảm dần theo Trần Minh Thái - Phạm Đức Thành
25 9/17/16
số lượng
[2.3] Kỹ thuật xử lý mảng
v Mảng một chiều. v Array và ArrayList. v Mảng hai chiều (ma trận – matrix). v Mảng hai chiều vuông. v Jagged Array.
26 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Chứa các biến có cùng kiểu dữ liệu. v Truy xuất phần tử thông qua chỉ số (index). v Chỉ số bắt đầu bằng 0.
Chi số
0
1
2
3
4
Ph n tầ ử A[0] A[1] A[2] A[3] A[4]
̉
27 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Khai báo:
Datatype[ ] array-name;
Ví d 1:ụ
int [ ] myArr = new int [5]; string [ ] myStr = new string[5]; string [] myStr2 = {“abc”, “def”};
28 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void Main(string[] args) { int[] Arr = new int[] { 2, 3, 4, 1, 6, 5 }; for (int i = 0; i < Arr.Length; i++) Console.Write("{0,4}", Arr[i]); Console.ReadLine(); }
29 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kỹ thuật liệt kê: void LietKeXXX(int [ ]a) {
for (int i = 0; i
Xuất a[i];
}
30 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Liệt kê các phần tử có giá trị chẵn trong
mảng:
static void lietKeChan(int []A)
{
foreach (int ai in A)
if (ai % 2 == 0)
Console.Write("{0,4}", ai);
}
31 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kỹ thuật liệt kê:
void LietKeXXX(int [ ]a, int x)
{
for (int i = 0; i
if (a[i] thỏa điều kiện so với x)
Xuất a[i];
}
32 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Liệt kê các phần tử có giá trị lớn hơn x trong
mảng:
static void lietKeLonHonX(int[] A,int X)
{
foreach (int ai in A)
if (ai > X)
Console.Write("{0,4}", ai);
}
33 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng/tích:
int TongXXX(int []A)
int s = 0;
{
for (int i = 0; i
s += a[i];
return s;
}
34 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng các phần tử có giá trị lẻ trong
mảng:
static int tongLe(int[] A)
{ int S = 0;
foreach (int ai in A)
if (ai % 2 != 0)
S += ai;
return S;
}
35 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt cờ hiệu :
Ø Kĩ thuật áp dụng cho những bài toán “kiểm
tra” hay “đánh dấu”.
Ø Ví dụ: Viết hàm kiểm tra xem mảng các số
nguyên có thứ tự tăng dần không?
(Hàm này trả về true nếu mảng tăng dần,
ngược lại trả về false).
36 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static bool kiemTraTang(int[] A)
{ bool flag = true;
for(int i=0; iA[i+1]) //vi phạm điều kiện tăng
dần
{
flag = false;
break;
37
}
return flag;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A)
int d = 0;
{
for (int i = 0; i
d++;
return d;
}
38 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demAm(int[] A)
{ int dem = 0;
foreach (int ai in A)
if (ai % 2 != 0)
dem++;
return dem;
}
39 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A, int x)
{
int d = 0;
for (int i = 0; i
if (A[i] thỏa điều kiện so với x)
d++;
return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demNhoHonX(int []a, int x)
{ int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < x)
d++;
return d;
}
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int []a)
{ int vtmax = 0;
for (int i = 1; i < a.Length; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh:
Ví dụ: Viết hàm tìm phần tử x có xuất hiện
trong mảng một chiều các số nguyên hay
không? Nếu có trả về vị trí đầu tiên của x trong
mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x)
{
int i = 0;
while (i < a.Length && a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x)
{
a[a.Length] = x; // đặt lính canh
int i = 0;
while (a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử
trong mảng thỏa điều kiện nào đó cho trước
tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a)
{
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
Xuất a[i];
}
30 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Liệt kê các phần tử có giá trị chẵn trong
mảng:
static void lietKeChan(int []A) { foreach (int ai in A) if (ai % 2 == 0) Console.Write("{0,4}", ai); }
31 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kỹ thuật liệt kê: void LietKeXXX(int [ ]a, int x) {
for (int i = 0; i
if (a[i] thỏa điều kiện so với x)
Xuất a[i];
}
32 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Liệt kê các phần tử có giá trị lớn hơn x trong
mảng:
static void lietKeLonHonX(int[] A,int X)
{
foreach (int ai in A)
if (ai > X)
Console.Write("{0,4}", ai);
}
33 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng/tích:
int TongXXX(int []A)
int s = 0;
{
for (int i = 0; i
s += a[i];
return s;
}
34 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng các phần tử có giá trị lẻ trong
mảng:
static int tongLe(int[] A)
{ int S = 0;
foreach (int ai in A)
if (ai % 2 != 0)
S += ai;
return S;
}
35 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt cờ hiệu :
Ø Kĩ thuật áp dụng cho những bài toán “kiểm
tra” hay “đánh dấu”.
Ø Ví dụ: Viết hàm kiểm tra xem mảng các số
nguyên có thứ tự tăng dần không?
(Hàm này trả về true nếu mảng tăng dần,
ngược lại trả về false).
36 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static bool kiemTraTang(int[] A)
{ bool flag = true;
for(int i=0; iA[i+1]) //vi phạm điều kiện tăng
dần
{
flag = false;
break;
37
}
return flag;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A)
int d = 0;
{
for (int i = 0; i
d++;
return d;
}
38 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demAm(int[] A)
{ int dem = 0;
foreach (int ai in A)
if (ai % 2 != 0)
dem++;
return dem;
}
39 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A, int x)
{
int d = 0;
for (int i = 0; i
if (A[i] thỏa điều kiện so với x)
d++;
return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demNhoHonX(int []a, int x)
{ int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < x)
d++;
return d;
}
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int []a)
{ int vtmax = 0;
for (int i = 1; i < a.Length; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh:
Ví dụ: Viết hàm tìm phần tử x có xuất hiện
trong mảng một chiều các số nguyên hay
không? Nếu có trả về vị trí đầu tiên của x trong
mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x)
{
int i = 0;
while (i < a.Length && a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x)
{
a[a.Length] = x; // đặt lính canh
int i = 0;
while (a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử
trong mảng thỏa điều kiện nào đó cho trước
tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a)
{
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
if (a[i] thỏa điều kiện so với x)
Xuất a[i];
}
32 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Liệt kê các phần tử có giá trị lớn hơn x trong
mảng:
static void lietKeLonHonX(int[] A,int X) { foreach (int ai in A) if (ai > X) Console.Write("{0,4}", ai); }
33 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng/tích:
int TongXXX(int []A)
int s = 0;
{
for (int i = 0; i
s += a[i];
return s;
}
34 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng các phần tử có giá trị lẻ trong
mảng:
static int tongLe(int[] A)
{ int S = 0;
foreach (int ai in A)
if (ai % 2 != 0)
S += ai;
return S;
}
35 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt cờ hiệu :
Ø Kĩ thuật áp dụng cho những bài toán “kiểm
tra” hay “đánh dấu”.
Ø Ví dụ: Viết hàm kiểm tra xem mảng các số
nguyên có thứ tự tăng dần không?
(Hàm này trả về true nếu mảng tăng dần,
ngược lại trả về false).
36 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static bool kiemTraTang(int[] A)
{ bool flag = true;
for(int i=0; iA[i+1]) //vi phạm điều kiện tăng
dần
{
flag = false;
break;
37
}
return flag;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A)
int d = 0;
{
for (int i = 0; i
d++;
return d;
}
38 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demAm(int[] A)
{ int dem = 0;
foreach (int ai in A)
if (ai % 2 != 0)
dem++;
return dem;
}
39 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A, int x)
{
int d = 0;
for (int i = 0; i
if (A[i] thỏa điều kiện so với x)
d++;
return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demNhoHonX(int []a, int x)
{ int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < x)
d++;
return d;
}
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int []a)
{ int vtmax = 0;
for (int i = 1; i < a.Length; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh:
Ví dụ: Viết hàm tìm phần tử x có xuất hiện
trong mảng một chiều các số nguyên hay
không? Nếu có trả về vị trí đầu tiên của x trong
mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x)
{
int i = 0;
while (i < a.Length && a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x)
{
a[a.Length] = x; // đặt lính canh
int i = 0;
while (a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử
trong mảng thỏa điều kiện nào đó cho trước
tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a)
{
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
s += a[i];
return s;
}
34 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tính tổng các phần tử có giá trị lẻ trong
mảng:
static int tongLe(int[] A) { int S = 0; foreach (int ai in A) if (ai % 2 != 0) S += ai; return S; }
35 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt cờ hiệu :
Ø Kĩ thuật áp dụng cho những bài toán “kiểm
tra” hay “đánh dấu”.
Ø Ví dụ: Viết hàm kiểm tra xem mảng các số
nguyên có thứ tự tăng dần không?
(Hàm này trả về true nếu mảng tăng dần, ngược lại trả về false).
36 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static bool kiemTraTang(int[] A)
{ bool flag = true;
for(int i=0; iA[i+1]) //vi phạm điều kiện tăng
dần
{
flag = false; break;
37
} return flag; } 9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A)
int d = 0;
{
for (int i = 0; i
d++;
return d;
}
38 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demAm(int[] A)
{ int dem = 0;
foreach (int ai in A)
if (ai % 2 != 0)
dem++;
return dem;
}
39 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm:
int DemXXX(int []A, int x)
{
int d = 0;
for (int i = 0; i
if (A[i] thỏa điều kiện so với x)
d++;
return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demNhoHonX(int []a, int x)
{ int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < x)
d++;
return d;
}
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int []a)
{ int vtmax = 0;
for (int i = 1; i < a.Length; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh:
Ví dụ: Viết hàm tìm phần tử x có xuất hiện
trong mảng một chiều các số nguyên hay
không? Nếu có trả về vị trí đầu tiên của x trong
mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x)
{
int i = 0;
while (i < a.Length && a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x)
{
a[a.Length] = x; // đặt lính canh
int i = 0;
while (a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử
trong mảng thỏa điều kiện nào đó cho trước
tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a)
{
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
d++; return d;
}
38 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm: static int demAm(int[] A) { int dem = 0; foreach (int ai in A) if (ai % 2 != 0) dem++; return dem; }
39 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm: int DemXXX(int []A, int x) {
int d = 0;
for (int i = 0; i
if (A[i] thỏa điều kiện so với x)
d++;
return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm:
static int demNhoHonX(int []a, int x)
{ int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < x)
d++;
return d;
}
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int []a)
{ int vtmax = 0;
for (int i = 1; i < a.Length; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh:
Ví dụ: Viết hàm tìm phần tử x có xuất hiện
trong mảng một chiều các số nguyên hay
không? Nếu có trả về vị trí đầu tiên của x trong
mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x)
{
int i = 0;
while (i < a.Length && a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x)
{
a[a.Length] = x; // đặt lính canh
int i = 0;
while (a[i] != x) i++;
if (i < a.Length) return i;
return -1;
}
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử
trong mảng thỏa điều kiện nào đó cho trước
tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a)
{
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
if (A[i] thỏa điều kiện so với x)
d++; return d;
}
40 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Đếm các phần tử có giá trị là số âm: static int demNhoHonX(int []a, int x) { int d = 0; for (int i = 0; i < a.Length; i++) if (a[i] < x) d++; return d; }
41 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Tìm kiếm: vị trí phần tử lớn nhất trong mảng. static int TimVTMax(int []a) { int vtmax = 0; for (int i = 1; i < a.Length; i++) if (a[i] > a[vtmax]) vtmax = i; return vtmax; }
42 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kĩ thuật đặt lính canh: Ví dụ: Viết hàm tìm phần tử x có xuất hiện trong mảng một chiều các số nguyên hay không? Nếu có trả về vị trí đầu tiên của x trong mảng, ngược lại trả về -1.
43 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int Tim_x(int []a, int x) { int i = 0; while (i < a.Length && a[i] != x) i++; if (i < a.Length) return i; return -1; }
44 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static int tim_X(int []a, int x) {
a[a.Length] = x; // đặt lính canh
int i = 0; while (a[i] != x) i++; if (i < a.Length) return i; return -1; }
45 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 1: kiểm tra tồn tại một phần tử trong mảng thỏa điều kiện nào đó cho trước tìm phần tử thỏa điều kiện để kết luận.
46 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraTonTaiXXX(int []a) {
for (int i = 0; i
return true;
return false;
}
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không?
static bool kiemTraTonTaiLe(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] % 2 != 0)
return true;
return false;
}
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa
điều kiện nào đó cho trước tìm phần tử
không thỏa điều kiện để kết luận mảng không
thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a)
{
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
return true;
return false; }
47 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có tồn tại số lẻ không? static bool kiemTraTonTaiLe(int []a) { for (int i = 0; i < a.Length; i++) if (a[i] % 2 != 0) return true; return false; }
48 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
v Kiểm tra xem mảng có thỏa điều kiện cho
trước:
Trường hợp 2: kiểm tra tất cả các phần tử thỏa điều kiện nào đó cho trước tìm phần tử không thỏa điều kiện để kết luận mảng không thỏa điều kiện.
49 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
bool KiemTraXXX(int []a) {
for (int i = 0; i
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm
không?
static bool kiemTraToanAm(int []a)
{
for (int i = 0; i < a.Length; i++)
if (a[i] >= 0)
return false;
return true;
}
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a)
{
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
if (a[i] không thỏa điều kiện)
return false;
return true;
}
50 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
Kiểm tra xem mảng có toàn bộ là giá trị âm không? static bool kiemTraToanAm(int []a) { for (int i = 0; i < a.Length; i++) if (a[i] >= 0) return false; return true; }
51 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình có điều kiện
float TrungBinhXXX(int []a) {
int d = 0;
float s = 0;
for (int i = 0; i
if (d==0) return 0;
return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong
mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho
trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16
}
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k
cho trước
static void chenXTaiViTri(ref int []a, int X,
int k)
{ int[] tam = new int[a.Length + 1];
int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn).
Tách mảng a thành 2 mảng b và c sao cho: b
có ½ phần tử đầu của mảng a, ½ phần tử còn
lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int
[]c)
{ int k = a.Length / 2;
b = new int[k]; c = new int[k];
int m = 0, l = 0;
for (int i = 0; i < k; i++)
{ b[m++] = a[i];
c[l++] = a[k + i];
}
}
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết
chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b)
{ int[] tam = new int[a.Length + b.Length];
int i;
for (i = 0; i < a.Length; i++)
tam[i] = a[i];
for (i = 0; i < b.Length; i++)
tam[i+a.Length] = b[i];
a = tam;
}
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử
dụng giống như mảng một chiều, chỉ khác là
mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
static void xuatMang(Array A)
{
foreach (int ai in A)
Console.Write("{0,4}",
ai);
Console.WriteLine();
}
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A)
{
int n;
Console.Write("Moi nhap so phan tu=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for (int i = 0; i < A.Length; i++)
{
Console.Write("A[{0}]=", i);
A.SetValue(int.Parse(Console.ReadLine()),
i);
}
}
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i
65 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
Ý nghĩa
ươ
ứ
ng th c
ư
ữ
ng item đang l u tr
ố ượ
ư
ph
Count
Capacity
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
ng item mà AL l u
Add
Remove
trữ
Thêm item vào cu iố
Xóa m t itemộ
66 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
67 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
68 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Giống như mảng một chiều. Chỉ khác có kích
thước dòng, kích thước cột
v Truy xuất phần tử thông qua chỉ số (index)
dòng, chỉ số cột.
v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho
chỉ số dòng, j cho chỉ số cột.
69 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
70 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Khai báo:
Datatype[,] array-
name;
v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột
int[,] myMatrix = new int[2, 3];
71 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
v Có thể khởi gán
Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6},
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
72 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
73 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
74 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
75 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
76 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
77 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
78 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
79 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
80 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
81 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
82 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
83 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
84 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
85 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
86 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
87 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
88
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
Trần Minh Thái - Phạm Đức Thành
,
tam = new
int[a.GetLength(0)
89 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
90 Trần Minh Thái - Phạm Đức Thành
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
91
}9/17/16
Trần Minh Thái - Phạm Đức Thành
92
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
0
1
2
3
4
0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4]
1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4]
2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4]
3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4]
4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4]
93 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo chính:
Ø Chỉ số dòng bằng chỉ số cột: i = j.
0,0
1,1
2,2
3,3
4,4
94 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Liệt kê các phần tử nằm trên đường chéo
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
95 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
96 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
97 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đường chéo phụ :
Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j-
1.
0,4
1,3
2,2
3,1
4,0
98 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
99 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
v Đếm các phần tử nhỏ hơn x nằm phía dưới
đường chéo phụ (kể cả chéo phụ).
0,4
1,3
2,2
3,1
4,0
100 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
101 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Jagged là mảng C# cung cấp, mà mỗi phần
tử là một mảng có kích thước khác nhau
v Những mảng con này phải được khai báo
riêng .
Datatype[ ][ ] array-
name
102 9/17/16 Trần Minh Thái - Phạm Đức Thành
Jagged Array
v Khai báo mảng 3 dòng, mỗi dòng là một
mảng 1 chiều
int[][] a = new int[3][];
1
2
a[0] = new int[4];
3
a[1] = new int[3];
4
a[2] = new int[1];
103 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
104 9/17/16 Trần Minh Thái - Phạm Đức Thành
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
105 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Trong C# string là kiểu dữ liệu cơ bản thể
hiện mảng tuần tự các ký tự.
v Một hằng chuỗi có thể được khai báo trong
code bằng cách đặt trong nháy đôi.
v Ví dụ: Console.WriteLine("Khoa Cong nghe
Thong tin - Huflit");
106 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Nhập chuỗi:
string S = Console.ReadLine();
v Xuất chuỗi:
Console.WriteLine(S);
v Truy cập đến các ký tự trong chuỗi:
foreach (char c in S)
Console.Write(c);
107 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
108 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức:
(t. 55)
109 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo
ra các bản copy để thực hiện.
v Thay
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
v Các phương thức của StringBuilder bao
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
110 9/17/16 Trần Minh Thái - Phạm Đức Thành
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
111 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Khái niệm:
Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh
và các cạnh nối nhau.
Ø Được mô tả hình thức sau: G=(V,E).
Trong đó:
– G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges).
112 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng sau:
D
B
A
F
C
E
113 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị có hướng sau:
D
B
A
F
C
E
114 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ ta có đồ thị vô hướng, có trọng số sau:
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
115 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ma trận kề: ma trận vuông có kích thước là
số đỉnh.
v Ma trận A, với A[i,j] ta định nghĩa như sau:
Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0)
E.
E.
v Với (cid:0)
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
116 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 146.
117 9/17/16 Trần Minh Thái - Phạm Đức Thành
PP biểu diễn đồ thị & thuật
toán cơ bản
v Ví dụ: Để biểu diễn cho hình slide 147.
118 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ma trận trọng số: giống ma trận kề, khác ở
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
Ø A[i,j] = 0 (hoặc (cid:0)
) nếu (i,j) (cid:0)
E.
119 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Ví dụ: Để biểu diễn cho hình slide 148.
120 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Là danh sách chứa các
cạnh của đồ thị.
v Ví dụ: Để biểu diễn cho hình slide 146 ta có
danh sách cạnh như sau:
(A,B)
0
(A,C)
1
(B,C)
2
(B,D)
3
(C,D)
4
(C,E)
5
(D,E)
6
(D,F)
7
(E,F)
8
121 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List list = new List();
122 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
123 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
124 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
125 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
126 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
127 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
5
6
0
4
3
1
2
128 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét:
Ø Những đỉnh gần với s nhất sẽ được viếng
thăm trước
Ø Các đỉnh chỉ được viếng thăm duy nhất 1
lần
v Cài đặt thuật toán: Ta dùng hàng đợi:
Queue q = new Queue();
129 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều rộng
v Thuật toán cài đặt bằng hàng đợi như sau:
Ø Bước 1: Khởi tạo
§ Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s
Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng
§ Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với
đỉnh u
– Tham đỉnh v (Đánh dấu đỉnh v đã viếng
thăm)
– Đẩy đỉnh v vào hàng đợi
130 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s.
Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
v Quá trình này được thực hiện cho đến khi không
131
thể quay về đỉnh trước đó
9/17/16
Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
132 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
133 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
134 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
135 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
136 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
137 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm kiếm theo chiều sâu: Thuật toán DFS:
D
B
A
F
C
E
138 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tìm kiếm theo chiều sâu
v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng.
§ B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề
u.
– B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3
139 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
140 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
141 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Thuật toán Ford – Bellman: chu trình âm hay trả về
cây đường đi.
v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0)
v(cid:0) V. d0(s)=0,
k=0
v Bước 2: [Lặp]
§ k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
v Bước 3: Nếu k=n thì đồ thị có chu trình âm
142 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm.
Ø Input: G=(V, E)
Ø Output:
§ Ma trận đường đi ngắn nhất giữa các cặp
đỉnh
– d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i
đến đỉnh j
§ Ma trận ghi nhận đường đi
– p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong
đường đi ngắn nhất từ đỉnh i đến đỉnh j
143 9/17/16 Trần Minh Thái - Phạm Đức Thành
Các thuật toán cơ bản
v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo]
§ d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp]
§ Cho k, i, j chạy từ 0 đến n-1
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
144 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
v Cây rỗng (null tree) là cây không có nút nào
cả.
145 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
146 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc
3, H bậc 2.
v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây.
Cây ở hình trên là cây bậc 3.
147 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Ví dụ ứng dụng thực tế:
Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File
Explorer/Windows Explorer.
Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học.
148 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề:
ỉ
ề
4
0
Đ nh k
9
6
1
3
(cid:0)
(cid:0)
9
1
4
7
5
2
(cid:0)
(cid:0)
8
3
6
7
5
2
(cid:0)
Đ nhỉ
0
1
2
3
4
5
6
7
8
9
8
(cid:0)
149 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách kề: Cài đặt trên máy:
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
150 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết:
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
151 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Biểu diễn bằng danh sách liên kết: Cài đặt trên
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
152 Trần Minh Thái - Phạm Đức Thành
LinkedList(dinhS0);
int[] dinhS1 = { 3,6 };
LinkedList(dinhS1);
int[] dinhS2 = null;
LinkedList(dinhS2);
int[] dinhS3 = null;
9/17/16
LinkedList
listAdj3
= new
LinkedList(dinhS3);
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
153 9/17/16 Trần Minh Thái - Phạm Đức Thành
int[] dinhS4 = { 7,5,2 };
LinkedList(dinhS4);
int[] dinhS5 = { 1, 9, 4 };
LinkedList(dinhS5);
int[] dinhS6 = null;
LinkedList(dinhS6);
int[] dinhS7 = null;
LinkedList(dinhS7);
int[] dinhS8 = null;
LinkedList
listAdj8
= new
LinkedList(dinhS8);
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
154 9/17/16 Trần Minh Thái - Phạm Đức Thành
LinkedList
LinkedList(dinhS9);
List>
List>();
Graphs.Add(listAdj0);
Graphs.Add(listAdj1);
Graphs.Add(listAdj2);
Graphs.Add(listAdj3);
Graphs.Add(listAdj4);
Graphs.Add(listAdj5);
Graphs.Add(listAdj6);
Graphs.Add(listAdj7);
Graphs.Add(listAdj8);
Graphs.Add(listAdj9);
Biểu diễn cây trên máy tính
v Biểu diễn bằng mảng các đỉnh kề:
0
1
2
3
4
5
6
7
8
9
a
1
9
4
3
6
7
5
2
8
previous
0
1
4
9
3
8
8
8
8
index
0
5
5
5
8
v Trong đó:
v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8
155 9/17/16 Trần Minh Thái - Phạm Đức Thành
Biểu diễn cây trên máy tính
v Mảng các đỉnh kề: công thức tính đỉnh kề với i:
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
156 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Kiểu dữ liệu + các thao tác xử lý được định nghĩa
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
v Dữ liệu kiểu mảng dùng cho việc biểu diễn những
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
157 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
158 9/17/16 Trần Minh Thái - Phạm Đức Thành
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
v Biểu diễn cây: dùng mảng, danh sách kề và danh
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
159 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện
cuối cùng trong mảng.
v Viết hàm tìm vị trí của phần tử lớn nhất trong
mảng các số thực.
v Viết hàm in vị trí các phần tử nguyên tố trong
mảng các số nguyên.
v Viết hàm tìm vị trí phần tử âm đầu tiên trong
mảng. Nếu không có phần tử âm trả về –1.
v Viết hàm tìm vị trí phần tử âm lớn nhất trong
mảng.
160 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm đếm số lần xuất hiện của phần tử x
trong mảng.
v Viết hàm đếm các phần tử là số hoàn thiện trong
mảng.
v Viết hàm tính tổng các phần tử nguyên tố trong
mảng.
v Viết hàm tính tích các phần tử nằm ở vị trí chẵn
trong mảng các số nguyên.
v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng.
161 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập vào giá trị X. Viết hàm xóa tất cả các phần
tử có giá trị nhỏ hơn X.
v Viết hàm chèn phần tử có giá trị X vào vị trí đầu
tiên của mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
162 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10
Ø
Ø
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Ø
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
Ø
9/17/16
163 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT nhập vào một chuỗi ký tự, đếm số ký tự có
trong chuỗi.
v VCT đếm có bao nhiêu khoảng trắng trong
chuỗi.
v VCT nhập vào một chuỗi, hãy loại bỏ những
khoảng trắng thừa trong chuỗi.
v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2
vào s1. Xuất chuỗi s1 ra màn hình.
v Đổi tất cả các ký tự có trong chuỗi thành chữ
thường (không dùng hàm strlwr).
v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa
(không dùng hàm struppr).
164 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v VCT đếm một ký tự xuất hiện bao nhiêu lần
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
v VCT đảo vị trí của từ đầu và từ cuối.
Ø Ví dụ: nhập “bo an co” xuat ra “co an bo”
v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
165 9/17/16 Trần Minh Thái - Phạm Đức Thành
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
166 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
167 9/17/16 Trần Minh Thái - Phạm Đức Thành
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
if (d==0) return 0; return s / d;
}
52 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vTính giá trị trung bình giá trị âm trong mảng
static float trungBinhAm(int []a)
{ float s = 0; int d = 0;
for (int i = 0; i < a.Length; i++)
if (a[i] < 0)
{ s += a[i]; d++; }
if (d == 0) return 0;
53 9/17/16 Trần Minh Thái - Phạm Đức Thành
return s / d;
}
Mảng một chiều
vSắp xếp:
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
54 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void SapTang(int []a) { for (int i = 0; i < a.Length - 1; i++) for (int j = i + 1; j < a.Length; j++) if (a[i] > a[j]) Hoanvi(ref a[i],ref a[j]); }
55 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vXóa: phần tử đầu tiên của mảng
static void xoaDau(ref int []a)
{
int[] tam = new int[a.Length - 1];
for (int i = 0; i < a.Length-1; i++)
tam[i] = a[i + 1];
a=tam;
56
} 9/17/16
Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vHàm xóa phần tử tại vị trí (vitri) cho trước.
static void xoaTaiViTri(ref int []a, int vitri)
{
int[] tam = new int[a.Length - 1];
for (int i = vitri; i < a.Length - 1; i++)
tam[i] = a[i + 1];
a = tam;
57 Trần Minh Thái - Phạm Đức Thành
9/17/16 }
Mảng một chiều
vChèn: Thêm X vào cuối mảng
static void themCuoi(ref int []a, int X)
{
int[] tam = new int[a.Length + 1];
for (int i = 0; i < a.Length; i++)
tam[i] = a[i];
tam[a.Length] = X;
a = tam;
58 Trần Minh Thái - Phạm Đức Thành
9/17/16 }
Mảng một chiều
vChèn: phần tử X vào mảng tại vị trí k cho trước
static void chenXTaiViTri(ref int []a, int X, int k)
{ int[] tam = new int[a.Length + 1]; int i;
for (i = 0; i < k; i++)
tam[i] = a[i];
59 9/17/16 Trần Minh Thái - Phạm Đức Thành
tam[k] = X;
for (; i < a.Length; i++)
tam[i+1] = a[i];
a = tam;
}
Mảng một chiều
vTách mảng :
v Ví dụ: Cho mảng a kích thước n (n chẵn). Tách mảng a thành 2 mảng b và c sao cho: b có ½ phần tử đầu của mảng a, ½ phần tử còn lại đưa vào mảng c.
60 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void tachMang(int []a, out int []b, out int []c) { int k = a.Length / 2; b = new int[k]; c = new int[k]; int m = 0, l = 0; for (int i = 0; i < k; i++) { b[m++] = a[i]; c[l++] = a[k + i]; } }
61 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
vGhép mảng:
v Ví dụ: Cho 2 mảng số nguyên a và b. Viết chương trình nối mảng b vào cuối mảng a.
62 9/17/16 Trần Minh Thái - Phạm Đức Thành
Mảng một chiều
static void noiMang(ref int []a, int []b) { int[] tam = new int[a.Length + b.Length]; int i; for (i = 0; i < a.Length; i++) tam[i] = a[i]; for (i = 0; i < b.Length; i++) tam[i+a.Length] = b[i]; a = tam; }
63 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
Array: C# cung cấp sẵn lớp Array giúp ta sử dụng giống như mảng một chiều, chỉ khác là mỗi thành phần của Array là kiểu Object.
Array Arr = new int[5];
int[] A = new int[5];
static void xuatMang(int []A) { foreach (int ai in A) Console.Write("{0,4}", ai); Console.WriteLine();
static void xuatMang(Array A) { foreach (int ai in A) Console.Write("{0,4}", ai); Console.WriteLine(); }
}
64 9/17/16 Trần Minh Thái - Phạm Đức Thành
Array và ArrayList
void nhapMang(out Array A) { int n; Console.Write("Moi nhap so phan tu="); n = int.Parse(Console.ReadLine()); A = new int[n]; for (int i = 0; i < A.Length; i++) { Console.Write("A[{0}]=", i); A.SetValue(int.Parse(Console.ReadLine()), i); } }
void nhapMang(out int []A)
{
int n;
Console.Write("nhap n=");
n = int.Parse(Console.ReadLine());
A = new int[n];
for(int i=0; i 65 9/17/16 Trần Minh Thái - Phạm Đức Thành Ý nghĩa ng item đang l u tr ph
Count
Capacity ng item mà AL l u Add
Remove trữ
Thêm item vào cu iố
Xóa m t itemộ 66 9/17/16 Trần Minh Thái - Phạm Đức Thành 67 9/17/16 Trần Minh Thái - Phạm Đức Thành v Giống như mảng một chiều. Chỉ khác có kích v Truy xuất phần tử thông qua chỉ số (index) v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho 68 9/17/16 Trần Minh Thái - Phạm Đức Thành v Giống như mảng một chiều. Chỉ khác có kích v Truy xuất phần tử thông qua chỉ số (index) v Chỉ số bắt đầu bằng 0. Thường ta dùng i cho 69 9/17/16 Trần Minh Thái - Phạm Đức Thành 0 1 2 3 4 0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4] 1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4] 2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4] 3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4] 70 9/17/16 Trần Minh Thái - Phạm Đức Thành v Khai báo: v Ví dụ 1: Khai báo mảng int 2 dòng 3 cột 71 9/17/16 Trần Minh Thái - Phạm Đức Thành v Có thể khởi gán Ø int[,] matrix1 = new int[,] {{1,2},{3,4},{5,6}, 72 9/17/16 Trần Minh Thái - Phạm Đức Thành 73 9/17/16 Trần Minh Thái - Phạm Đức Thành 74 9/17/16 Trần Minh Thái - Phạm Đức Thành 75 9/17/16 Trần Minh Thái - Phạm Đức Thành 76 9/17/16 Trần Minh Thái - Phạm Đức Thành 77 9/17/16 Trần Minh Thái - Phạm Đức Thành 78 9/17/16 Trần Minh Thái - Phạm Đức Thành 79 9/17/16 Trần Minh Thái - Phạm Đức Thành 80 9/17/16 Trần Minh Thái - Phạm Đức Thành 81 9/17/16 Trần Minh Thái - Phạm Đức Thành 82 9/17/16 Trần Minh Thái - Phạm Đức Thành 83 9/17/16 Trần Minh Thái - Phạm Đức Thành 84 9/17/16 Trần Minh Thái - Phạm Đức Thành 85 9/17/16 Trần Minh Thái - Phạm Đức Thành 86 9/17/16 Trần Minh Thái - Phạm Đức Thành 87 9/17/16 Trần Minh Thái - Phạm Đức Thành 88 Trần Minh Thái - Phạm Đức Thành 89 Trần Minh Thái - Phạm Đức Thành 90 Trần Minh Thái - Phạm Đức Thành 91 Trần Minh Thái - Phạm Đức Thành 92 Trần Minh Thái - Phạm Đức Thành 0 1 2 3 4 0 A[0,0] A[0,1] A[0,2] A[0,3] A[0,4] 1 A[1,0] A[1,1] A[1,2] A[1,3] A[1,4] 2 A[2,0] A[2,1] A[2,2] A[2,3] A[2,4] 3 A[3,0] A[3,1] A[3,2] A[3,3] A[3,4] 4 A[4,0] A[4,1] A[4,2] A[4,3] A[4,4] 93 9/17/16 Trần Minh Thái - Phạm Đức Thành v Đường chéo chính: Ø Chỉ số dòng bằng chỉ số cột: i = j. 0,0 1,1 2,2 3,3 4,4 94 9/17/16 Trần Minh Thái - Phạm Đức Thành v Liệt kê các phần tử nằm trên đường chéo 95 9/17/16 Trần Minh Thái - Phạm Đức Thành 96 9/17/16 Trần Minh Thái - Phạm Đức Thành 97 9/17/16 Trần Minh Thái - Phạm Đức Thành v Đường chéo phụ : Ø Cs dòng = kt mtrận vuông – cs cột -1: i=n-j- 0,4 1,3 2,2 3,1 4,0 98 9/17/16 Trần Minh Thái - Phạm Đức Thành 99 9/17/16 Trần Minh Thái - Phạm Đức Thành v Đếm các phần tử nhỏ hơn x nằm phía dưới 0,4 1,3 2,2 3,1 4,0 100 9/17/16 Trần Minh Thái - Phạm Đức Thành 101 9/17/16 Trần Minh Thái - Phạm Đức Thành v Jagged là mảng C# cung cấp, mà mỗi phần v Những mảng con này phải được khai báo 102 9/17/16 Trần Minh Thái - Phạm Đức Thành v Khai báo mảng 3 dòng, mỗi dòng là một int[][] a = new int[3][]; 1 2 a[0] = new int[4]; 3 a[1] = new int[3]; 4 a[2] = new int[1]; 103 9/17/16 Trần Minh Thái - Phạm Đức Thành 104 9/17/16 Trần Minh Thái - Phạm Đức Thành 105 9/17/16 Trần Minh Thái - Phạm Đức Thành v Trong C# string là kiểu dữ liệu cơ bản thể v Một hằng chuỗi có thể được khai báo trong v Ví dụ: Console.WriteLine("Khoa Cong nghe 106 9/17/16 Trần Minh Thái - Phạm Đức Thành v Nhập chuỗi: v Xuất chuỗi: v Truy cập đến các ký tự trong chuỗi: 107 9/17/16 Trần Minh Thái - Phạm Đức Thành 108 9/17/16 Trần Minh Thái - Phạm Đức Thành v Các hàm do C# cung cấp sẵn: (trang 54)
v string của C# hỗ trợ hai dạng phương thức: 109 9/17/16 Trần Minh Thái - Phạm Đức Thành v Chuỗi trong C# là giá trị không thể modify
v Do đó nếu dùng để modify string thì phải tạo v Thay v Các phương thức của StringBuilder bao 110 9/17/16 Trần Minh Thái - Phạm Đức Thành 111 9/17/16 Trần Minh Thái - Phạm Đức Thành v Khái niệm: Ø Đồ thị là một cấu trúc rời rạc gồm các đỉnh Ø Được mô tả hình thức sau: G=(V,E). – G là đồ thị (Graph).
– V là tập các đỉnh (Vertices).
– E là tập các cạnh (Edges). 112 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ ta có đồ thị vô hướng sau: 113 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ ta có đồ thị có hướng sau: 114 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ ta có đồ thị vô hướng, có trọng số sau: 115 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ma trận kề: ma trận vuông có kích thước là v Ma trận A, với A[i,j] ta định nghĩa như sau: Ø A[i,j] = 1 nếu (i,j) (cid:0)
Ø A[i,j] = 0 nếu (i,j) (cid:0) v Với (cid:0) 116 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ: Để biểu diễn cho hình slide 146. 117 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ: Để biểu diễn cho hình slide 147. 118 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ma trận trọng số: giống ma trận kề, khác ở Ø A[i,j] = 0 (hoặc (cid:0) 119 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ: Để biểu diễn cho hình slide 148. 120 9/17/16 Trần Minh Thái - Phạm Đức Thành v Danh sách cạnh: Là danh sách chứa các v Ví dụ: Để biểu diễn cho hình slide 146 ta có (A,B)
0 (A,C)
1 (B,C)
2 (B,D)
3 (C,D)
4 (C,E)
5 (D,E)
6 (D,F)
7 (E,F)
8 121 9/17/16 Trần Minh Thái - Phạm Đức Thành 122 9/17/16 Trần Minh Thái - Phạm Đức Thành 123 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: 124 9/17/16 Trần Minh Thái - Phạm Đức Thành 125 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: 126 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: 127 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều rộng: Thuật toán [BFS]: 128 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
v Nhận xét: Ø Những đỉnh gần với s nhất sẽ được viếng Ø Các đỉnh chỉ được viếng thăm duy nhất 1 v Cài đặt thuật toán: Ta dùng hàng đợi: 129 9/17/16 Trần Minh Thái - Phạm Đức Thành v Thuật toán cài đặt bằng hàng đợi như sau: Ø Bước 1: Khởi tạo § Đánh dấu mọi đỉnh chưa được viếng thăm
§ Thăm đỉnh s (Đánh dấu đỉnh s đã viếng thăm)
§ Khởi tạo hàng đợi q chỉ chứa s Ø Bước 2: Lặp cho đến khi hàng đợi q rỗng § Lấy đỉnh u ra khỏi hàng đợi q
§ Tìm tất cả đỉnh v chưa viếng thăm và kề với – Tham đỉnh v (Đánh dấu đỉnh v đã viếng – Đẩy đỉnh v vào hàng đợi 130 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS:
v Cho G=(V, E) và 1 đỉnh xuất phát s. Ø Bước 1: Viếng thăm đỉnh s
Ø Bước 2: Tìm đỉnh u chưa được viếng thăm và kề v Quá trình này được thực hiện cho đến khi không 131 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 132 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 133 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 134 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 135 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 136 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 137 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm kiếm theo chiều sâu: Thuật toán DFS: 138 9/17/16 Trần Minh Thái - Phạm Đức Thành v Cài đặt thuật toán: Stack s = new Stack();
v Thuật toán cài đặt bằng stack như sau:
Ø Bước 1. Đánh dấu s đã viếng thăm.
Ø Bước 2. Đưa s vào stack.
Ø Bước 3. Trong khi stack chưa rỗng. § B3.1 Lấy 1 đỉnh u từ stack.
§ B3.2 Tìm 1 đỉnh v chưa được viếng thăm và kề – B3.2.1 Đánh dấu v đã viếng thăm.
– B3.2.2 Đẩy u vào lại stack.
– B3.2.3 Đẩy v vào stack.
– B3.2.4 Quay lại bước 3 139 9/17/16 Trần Minh Thái - Phạm Đức Thành v Thuật toán Dijkstra: Tìm đường đi từ s đến t.
v Ý tưởng: xây dựng dần các đỉnh đi từ s và 140 9/17/16 Trần Minh Thái - Phạm Đức Thành 141 9/17/16 Trần Minh Thái - Phạm Đức Thành v Thuật toán Ford – Bellman: chu trình âm hay trả về v Bước 1 [Khởi tạo]: d0(v) = +∞, (cid:0) v Bước 2: [Lặp] § k = k+1
§ [Cập Nhật] Với mọi đỉnh u kề v v Bước 3: Nếu k=n thì đồ thị có chu trình âm 142 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Hoặc chỉ ra đồ thị có chu trình âm. Ø Input: G=(V, E)
Ø Output: § Ma trận đường đi ngắn nhất giữa các cặp – d[i, j]: độ dài đường đi ngắn nhất từ đỉnh i § Ma trận ghi nhận đường đi – p[i, j]: ghi nhận đỉnh đi trước đỉnh j trong 143 9/17/16 Trần Minh Thái - Phạm Đức Thành v Tìm đường đi ngắn nhất: Thuật toán Floyd.
v Bước 1: [Khởi tạo] § d[i, j]=a[i, j]
§ p[i, j] = j;
v Bước 2: [Lặp] § Cho k, i, j chạy từ 0 đến n-1 144 9/17/16 Trần Minh Thái - Phạm Đức Thành v Cây rỗng (null tree) là cây không có nút nào 145 9/17/16 Trần Minh Thái - Phạm Đức Thành 146 9/17/16 Trần Minh Thái - Phạm Đức Thành v Nút A là gốc, là cha của B, C, D.
v Nút G, H, I là con của nút D.
v Số các nút con là bậc của nút đó. Ví dụ: nút D bậc v Nút có bậc bằng 0 là nút là (leaf). Ví dụ: nút C, E, F.
v Nút không phải là gốc hoặc lá gọi là nhánh.
v Bậc cao nhất của tất cả các nút gọi là bậc của cây. 147 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ ứng dụng thực tế: Ø Mục lục của một cuốn sách.
Ø Cấu trúc thư mục trên đĩa trong cửa sồ File Ø Gia phả của một họ tộc.
Ø Một biểu thức toán học. 148 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn bằng danh sách kề: Đ nh k
9
6 1
3 (cid:0) (cid:0) 7 5 2 (cid:0) (cid:0) (cid:0) Đ nhỉ
0
1
2
3
4
5
6
7
8
9 8 (cid:0) 149 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn bằng danh sách kề: Cài đặt trên máy: 150 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn bằng danh sách liên kết: 151 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn bằng danh sách liên kết: Cài đặt trên 152 Trần Minh Thái - Phạm Đức Thành 9/17/16 153 9/17/16 Trần Minh Thái - Phạm Đức Thành 154 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn bằng mảng các đỉnh kề: 0 1 2 3 4 5 6 7 8 9 a 1 9 4 3 6 7 5 2 8 previous 0 1 4 9 3 8 8 8 8 index 0 5 5 5 8 v Trong đó: v Đỉnh kề với 0: 0-2 Đỉnh kề với 1: 3-4
v Đỉnh kề với 4: 5-7 Đỉnh kề với 9: 8-8 155 9/17/16 Trần Minh Thái - Phạm Đức Thành v Mảng các đỉnh kề: công thức tính đỉnh kề với i: 156 9/17/16 Trần Minh Thái - Phạm Đức Thành v Kiểu dữ liệu + các thao tác xử lý được định nghĩa v Dữ liệu kiểu mảng dùng cho việc biểu diễn những 157 9/17/16 Trần Minh Thái - Phạm Đức Thành 158 9/17/16 Trần Minh Thái - Phạm Đức Thành v Biểu diễn cây: dùng mảng, danh sách kề và danh 159 9/17/16 Trần Minh Thái - Phạm Đức Thành v Viết hàm tìm vị trí phần tử có giá trị x xuất hiện v Viết hàm tìm vị trí của phần tử lớn nhất trong v Viết hàm in vị trí các phần tử nguyên tố trong v Viết hàm tìm vị trí phần tử âm đầu tiên trong v Viết hàm tìm vị trí phần tử âm lớn nhất trong 160 9/17/16 Trần Minh Thái - Phạm Đức Thành v Viết hàm đếm số lần xuất hiện của phần tử x v Viết hàm đếm các phần tử là số hoàn thiện trong v Viết hàm tính tổng các phần tử nguyên tố trong v Viết hàm tính tích các phần tử nằm ở vị trí chẵn v Viết hàm sắp xếp các phần tử chẵn giảm dần.
v Viết hàm xóa phần tử tại vị trí lẻ trong mảng. 161 9/17/16 Trần Minh Thái - Phạm Đức Thành v Nhập vào giá trị X. Viết hàm xóa tất cả các phần v Viết hàm chèn phần tử có giá trị X vào vị trí đầu v Viết hàm chèn phần tử có giá trị X vào phía sau 162 9/17/16 Trần Minh Thái - Phạm Đức Thành v Ví dụ: Mảng ban đầu a: 1 3 8 2 7 5 9 0 10 Ø Ø Ø Ø
9/17/16 163 Trần Minh Thái - Phạm Đức Thành v VCT nhập vào một chuỗi ký tự, đếm số ký tự có v VCT đếm có bao nhiêu khoảng trắng trong v VCT nhập vào một chuỗi, hãy loại bỏ những v VCT nhập vào hai chuỗi s1 và s2, nối chuỗi s2 v Đổi tất cả các ký tự có trong chuỗi thành chữ v Đổi tất cả các ký tự trong chuỗi sang chữ in hoa 164 9/17/16 Trần Minh Thái - Phạm Đức Thành v VCT đếm một ký tự xuất hiện bao nhiêu lần v VCT đảo vị trí của từ đầu và từ cuối. Ø Ví dụ: nhập “bo an co” xuat ra “co an bo” v Viết hàm cắt chuỗi họ tên thành chuỗi họ lót và 165 9/17/16 Trần Minh Thái - Phạm Đức Thành 166 9/17/16 Trần Minh Thái - Phạm Đức Thành 167 9/17/16 Trần Minh Thái - Phạm Đức ThànhArray và ArrayList
ArrayList: Khác với Array, ArrayList là mảng
động đối tượng không cùng kiểu dữ liệu và
được chứa dưới dạng Object (kiểu đối tượng).
Sử dụng indexer để xác định item.
ộ
Thu c tính/
ươ
ứ
ng th c
ư
ữ
ố ượ
ư
ế ố ượ
Cho bi
t s l
Cho phép get/set s l
Array và ArrayList
using System.Collections;
int i = 100;
float f = 99.99f;
ArrayList arraylist = new ArrayList();
arraylist.Add("Ha Nam");
arraylist.Add(i);
arraylist.Add(f);
for (int index = 0; index < arraylist.Count; index+
+)
Console.WriteLine(arraylist[index]);
Mảng hai chiều
thước dòng, kích thước cột
dòng, chỉ số cột.
chỉ số dòng, j cho chỉ số cột.
Mảng hai chiều
thước dòng, kích thước cột
dòng, chỉ số cột.
chỉ số dòng, j cho chỉ số cột.
Mảng hai chiều
Mảng hai chiều
Datatype[,] array-
name;
int[,] myMatrix = new int[2, 3];
Mảng hai chiều
{7,8}};
Ø int[,] matrix2 = {{1,2},{3,4},{5,6},{7,8}};
Ø string[,] beatleName =
{"Lennon","John"},
{
{"McCartney","Paul"},
{"Harrison","George"},
{"Starkey","Richard"}
};
Mảng hai chiều
static void Main(string[] args)
{ double[,] matrix = new double[5, 4]; int
count = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix[i, j] = ++count;
foreach (double d in matrix)
Console.Write("{0,4}", d);
Console.ReadLine();
}
Mảng hai chiều
Liệt kê các phần tử có giá trị chẵn trong mảng:
static void lietKeDuong(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j]>0)
Console.Write("{0,4}", A[i, j]);
}
Mảng hai chiều
Tính tổng các phần tử có giá trị lẻ trong mảng :
static int tongLe(int[,] A)
{ int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += ai;
return S;
}
Mảng hai chiều
Kĩ thuật đặt cờ hiệu:
Ví dụ: Viết hàm kiểm tra xem trong mảng các số
nguyên có tồn tại số nguyên chẵn lớn hơn 10 hay
không? (Trả về 1: Nếu có tồn tại số chẵn và lớn
hơn 10, ngược lại trả về 0).
Mảng hai chiều
static bool Ktra_chanLH10(int[,] A)
{ bool flag = false;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(A[i,j] % 2 == 0 && A[i,j] > 10)//Gặp ptử thỏa
đk
{ flag = true; break;
}
return flag;
}
Mảng hai chiều
if (A[i,j] % 2 != 0)
dem++;
Đếm: các phần tử có giá trị là số âm.
static int demAm(int[,] A)
{ int dem = 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return dem;
}
Mảng hai chiều
Tìm kiếm: vị trí phần tử lớn nhất trong mảng.
static int TimVTMax(int[,] a, out int vtd,out int vtc)
{ vtd = vtc= 0;
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] > a[vtd,vtc])
{ vtd = i; vtc = j; }
return a[vtd,vtc];
}
Mảng hai chiều
if (A[i,j] % 2 != 0)
return true;
Kiểm tra xem mảng có tồn tại số lẻ không.
static bool kiemTraTonTaiLe(int [,]A)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
return false;
}
Mảng hai chiều
float s = 0; int d = 0;
Tính trung bình phần tử có giá trị âm trong mảng.
static float trungBinhAm(int [,]a)
{
for (int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
if (a[i,j] < 0)
{ s+=a[i,j]; d++; }
if( d==0 ) return 0;
return s/d;
}
Mảng hai chiều
Sắp xếp.
static void Hoanvi(ref int a,ref int b)
{
int tam = a;
a = b;
b = tam;
}
Mảng hai chiều
static void SapTang(int []a)
{
for (int i = 0; i < a.Length - 1; i++)
for (int j = i + 1; j < a.Length; j++)
if (a[i] > a[j])
Hoanvi(ref a[i],ref a[j]);
}
Mảng hai chiều
static void Copy(int [,]a,out int []b)
{
b = new int[a.GetLength(0) * a.GetLength(1)];
int i = 0;
foreach (int ai in a)
b.SetValue(ai,i++);
}
Mảng hai chiều
static void Copy(int[] a,ref int[,] b)
{
int k = 0;
for (int i = 0; i < b.GetLength(0); i++)
for (int j = 0; j < b.GetLength(1); j++)
b[i,j]=a[k++];
}
Mảng hai chiều
static void sapTang(int [,]a)
{
int[] b;
Copy(a, out b);
SapTang(b);
Copy(b, ref a);
}
Mảng hai chiều
xóa dòng đầu tiên của mảng
static void xoaDongDau(ref int[,] a)
{
int[,] tam = new int[a.GetLength(0) –
1,a.GetLength(1)];
for (int i = 1; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1,j] = a[i,j];
a = tam;
}
Mảng hai chiều
- 1,
int[,]tam=new
int[a.GetLength(0)
static void xoaDongTaiViTri(ref int[,] a,int vitri)
{
a.GetLength(1)];
int i;
for (i = 0; i < vitri; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i , j] = a[i, j];
for (i++; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i-1, j] = a[i, j];
a = tam;
}9/17/16
,
tam = new
int[a.GetLength(0)
Mảng hai chiều
static void xoaCotTaiViTri(ref int[,] a, int vitri)
int[,]
{
a.GetLength(1)-1];
int j;
for (j = 0; j < vitri; j++)
for (int i = 0; i < a.GetLength(0); i++)
tam[i, j] = a[i, j];
for (j++; j < a.GetLength(1); j++)
for (int i=0; i < a.GetLength(0); i++)
tam[i , j-1] = a[i, j];
a = tam;
9/17/16
}
int[,] tam = new
int[a.GetLength(0) + 1,
static void themDongTaiVT(ref int[,] a, int[] b, int
vt)
{
a.GetLength(1)];
int i;
for (i = 0; i < vt; i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = b[j];
for (; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i+1, j] = a[i, j];
9/17/16
a = tam;
}
static void tachMang(int[,] a, out int[,] b, out int[,]
c)
{ int k = a.GetLength(0) / 2;
b = new int[k,a.GetLength(1)];
c = new int[k,a.GetLength(1)];
int i = 0, j = 0;
for (i = 0; i < k; i++)
for (j = 0; j < a.GetLength(1); j++)
{
b[i, j] = a[i, j];
c[i, j] = a[k + i, j];
}
}9/17/16
static void noiMang(ref int[,] a, int[,] b)
{int[,]tam=new
int[a.GetLength(0)+b.GetLength(0),a.GetLength(1)
];
int i;
for (i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
tam[i, j] = a[i, j];
for (int k = 0; k < b.GetLength(0); k++,i++)
for (int j = 0; j < b.GetLength(1); j++)
tam[i, j] = b[k, j];
a = tam;
}
9/17/16
Mảng hai chiều vuông
Mảng hai chiều vuông
Mảng hai chiều vuông
chính:
static void lietKeCheoChinh(double[,] A)
{
for (int i = 0; i < A.GetLength(0); i++)
for (int j = 0; j < A.GetLength(1); j++)
if(i == j)
Console.Write("{0,4}", A[i, j]);
}
Mảng hai chiều vuông
v Tổng giá trị lẻ nằm phía trên chéo chính
trong ma trận vuông số nguyên (không kể
chéo chính).
Mảng hai chiều vuông
static int tongLe(int[,] A)
{
int S = 0;
for (int i = 0; i < A.GetLength(0); i++)
for (int j = i+1; j < A.GetLength(1); j++)
if (A[i,j] % 2 != 0)
S += A[i,j];
return S;
}
Mảng hai chiều vuông
1.
Mảng hai chiều vuông
v Đếm các phần tử âm trên chéo phụ:
static int demAm(int[,] A)
{ int dem = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
if (A[i,n-i-1] < 0)
dem++;
return dem;
}
Mảng hai chiều vuông
đường chéo phụ (kể cả chéo phụ).
Mảng hai chiều vuông
static int demNhoHonX(int [,]a, int x)
{
int d = 0, n= A.GetLength(0);
for (int i = 0; i < n; i++)
for (int j = n-i-1; j < n; j++)
if (a[i,j] < x)
d++;
return d;
}
Jagged Array
tử là một mảng có kích thước khác nhau
riêng .
Datatype[ ][ ] array-
name
Jagged Array
mảng 1 chiều
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
for (int i = 0; i < softwares.GetLength(0); i++)
for (int j = 0; j < softwares[i].GetLength(0); j++)
Console.WriteLine(softwares[i][j]);
Console.ReadLine();
}
static void Main(string[] args)
{ string[][] softwares = new string[3][];
softwares[0] = new string[] { "Bitdefender",
"Karperky", "NAV" };
softwares[1] = new string[] { "IE", "Mozilla",
"Opera", "Avant" };
softwares[2] = new string[] { "MS Word",
"OpenOffice" };
foreach(string[] srr in softwares)
foreach(string s in srr)
Console.WriteLine(s);
Console.ReadLine();
}
Thuật toán xử lý chuỗi
hiện mảng tuần tự các ký tự.
code bằng cách đặt trong nháy đôi.
Thong tin - Huflit");
Thuật toán xử lý chuỗi
string S = Console.ReadLine();
Console.WriteLine(S);
foreach (char c in S)
Console.Write(c);
Thuật toán xử lý chuỗi
v Đếm số khoảng trắng trong chuỗi:
static int demKhoangTrang(string S)
{
int dem = 0;
for (int i = 0; i < S.Length; i++)
if (S[i] == 32)
dem++;
return dem;
}
Thuật toán xử lý chuỗi
(t. 55)
Thuật toán xử lý chuỗi
ra các bản copy để thực hiện.
đó
vào
thể
có
dùng
System.Text.StringBuilder để modify chuỗi
mà không phải tạo ra bản copy như là string
thực hiện.
gồm:
Ø Append( ), AppendFormat( ),
Insert( ),
Remove( ) và Replace( ).
Thuật toán xử lý chuỗi
v Ví dụ:
StringBuilder S =new StringBuilder( "Hello");
S.Append(" Everybody");
Console.WriteLine(S);
PP biểu diễn đồ thị & thuật
toán cơ bản
và các cạnh nối nhau.
Trong đó:
PP biểu diễn đồ thị & thuật
toán cơ bản
D
B
A
F
C
E
PP biểu diễn đồ thị & thuật
toán cơ bản
D
B
A
F
C
E
PP biểu diễn đồ thị & thuật
toán cơ bản
1
D
B
3
5
5
A
F
6
2
2
4
C
E
3
PP biểu diễn đồ thị & thuật
toán cơ bản
số đỉnh.
E.
E.
i, A[i,i] = 0. Tùy theo mục đích có thể
đặt giá trị khác nhau, khi lập trình tìm đường
đi ngắn nhất, giá trị A[i,i]=(cid:0)
(vô cực).
PP biểu diễn đồ thị & thuật
toán cơ bản
PP biểu diễn đồ thị & thuật
toán cơ bản
Biểu diễn đồ thị trên máy
tính
định nghĩa A[i,j] như sau:
Ø A[i,j] = x nếu (i,j) (cid:0)
E, x là trọng số của
cạnh (i,j).
) nếu (i,j) (cid:0)
E.
Biểu diễn đồ thị trên máy
tính
Biểu diễn đồ thị trên máy
tính
cạnh của đồ thị.
danh sách cạnh như sau:
Biểu diễn đồ thị trên máy
tính
v Danh sách cạnh: Cài đặt bằng C# như sau:
public struct Canh
{
public int dinhdau;
public int dinhcuoi;
}
List
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
Cho G=(V, E) và 1 đỉnh xuất phát s.
Bước 1: Viếng thăm đỉnh s.
Bước 2: Tìm các đỉnh (gọi là S1) chưa được
viếng thăm và kề với s, rồi viếng thăm các đỉnh
trong S1.
Bước 3: Tìm các đỉnh (gọi là S2) chưa được
viếng thăm và kề với S1, rồi viếng thăm các
đỉnh trong S2.
Bước 4: Quá trình này thực hiện cho đến khi
không thể tìm được các đỉnh kế tiếp.
Các thuật toán cơ bản
5
6
0
4
3
1
2
Các thuật toán cơ bản
v Tìm kiếm theo chiều rộng: Thuật toán [BFS]:
6
5
0
4
3
1
2
Các thuật toán cơ bản
5
6
0
4
3
1
2
Các thuật toán cơ bản
5
6
0
4
3
1
2
Các thuật toán cơ bản
5
6
0
4
3
1
2
Các thuật toán cơ bản
thăm trước
lần
Queue q = new Queue();
Tìm kiếm theo chiều rộng
đỉnh u
thăm)
Các thuật toán cơ bản
với s
§ Nếu có đỉnh u thì đặt s=u và quay về Bước 1
§ Nếu không có đỉnh u thì quay về đỉnh k là
đỉnh trước của đỉnh s, đặt s=k và quay về
bước 2
thể quay về đỉnh trước đó
9/17/16
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Các thuật toán cơ bản
D
B
A
F
C
E
Tìm kiếm theo chiều sâu
u.
Các thuật toán cơ bản
gần s nhất.
v Thuật toán Dijkstra không thể thực hiện khi
đồ thị có cạnh âm (đồ thị vô hướng) hay đồ
thị có chu trình âm (đồ thị có hướng)
Các thuật toán cơ bản
v Thuật toán Dijkstra:
Bước 1 [Khởi tạo]:
d(v) = +∞, (cid:0)
v(cid:0) V. d(s)=0 và tập S=V.
S sao cho d(u) có giá trị
Bước 2: [Lặp]
[Chọn Min] Chọn đỉnh u (cid:0)
min.
[Cập Nhật] Với mọi đỉnh v kề u.
d(v) = min{d(v), d(u) + w(u,v)}
S = S - {u}
Lặp cho đến khi t (cid:0)
S
Các thuật toán cơ bản
cây đường đi.
v(cid:0) V. d0(s)=0,
k=0
dk(s) = 0. dk(v) = min{dk-1(u) + w(u,v)}
§ [Kiểm tra] Nếu dk(v) = dk-1(v), (cid:0) v, thì dừng.
Lặp cho đến khi k=n
Các thuật toán cơ bản
đỉnh
đến đỉnh j
đường đi ngắn nhất từ đỉnh i đến đỉnh j
Các thuật toán cơ bản
Nếu (d[i, j] > d[i, k] + d[k, j]) thì
d[i, j] = d[i, k] + d[k, j]
p[i, j] = k
Tổ chức dữ liệu biểu diễn
cấu trúc cây
v Khái niệm cơ bản.
v Cây là một cấu trúc dữ liệu gồm tập hữu hạn
các nút, giữa các nút có một quan hệ phân
cấp “cha - con”. Có một nút đặc biệt gọi là
gốc (root).
cả.
Tổ chức dữ liệu biểu diễn
cấu trúc cây
A
Mức
0
C
B
D
Mức
1
I
E
F
G
H
Mức
2
K
J
Mức
3
Tổ chức dữ liệu biểu diễn
cấu trúc cây
3, H bậc 2.
Cây ở hình trên là cây bậc 3.
Tổ chức dữ liệu biểu diễn
cấu trúc cây
Explorer/Windows Explorer.
Biểu diễn cây trên máy tính
ỉ
ề
4
0
9
1
4
8
3
6
7
5
2
Biểu diễn cây trên máy tính
int sodinh = 10;
Vertices[3] = null;
int[][] Vertices = new int[sodinh][];
Vertices[0] = new int[] { 1,9, 4 };
Vertices[1] = new int[] { 3,6 };
Vertices[2] = null;
Vertices[4] = new int[] { 7,5,2 };
Vertices[5] = null; Vertices[6] = null;
Vertices[7] = null; Vertices[8] = null;
Vertices[9] = new int[] { 8 };
Biểu diễn cây trên máy tính
null
adj[0]
1
9
4
null
adj[1]
3
6
adj[2] null
adj[3] null
null
adj[4]
7
5
2
Biểu diễn cây trên máy tính
máy:
int[] dinhS0 = { 1, 9, 4 };
LinkedList
listAdj0
= new
LinkedList
listAdj1
= new
LinkedList
listAdj2
= new
LinkedList
LinkedList
listAdj3
= new
LinkedList
Biểu diễn cây trên máy tính
LinkedList
listAdj4
= new
LinkedList
listAdj5
= new
LinkedList
listAdj6
= new
LinkedList
listAdj7
= new
int[] dinhS4 = { 7,5,2 };
LinkedList
LinkedList
listAdj8
= new
LinkedList
int[] dinhS9 = { 8 };
listAdj9
=
new
Graphs
=
new
LinkedList
Biểu diễn cây trên máy tính
Biểu diễn cây trên máy tính
Đỉnh kề với i:
a[index[i]] a[index[i+1]-1]
v Cài đặt trên máy:
int n = 10;
int[] a = new int[n];
int[] index = new int[n];
Tóm tắt chương
trên nó.
v Danh sách là một tập thứ tự các phần tử có cùng
kiểu. Danh sách là cấu trúc dữ liệu tuyến tính, các
phần tử dữ liệu được sắp thứ tự xác định.
thông tin có cùng kiểu dữ liệu liên tiếp nhau.
v Khi cài đặt bài tập mảng một chiều nên xây dựng
thành những hàm chuẩn để dùng lại cho các bài
tập khác.
Tóm tắt chương
v Các thao tác mảng theo quy tắc nhất định, ứng
dụng mảng trong việc biểu diễn số lớn, dùng bảng
tra, khử đệ qui, …
v Giống mảng một chiều, thao tác truy xuất trên
mảng hai chiều, trên chuỗi hoàn toàn tương tự.
Bên cạnh đó, kiểu chuỗi còn được cài đặt sẵn một
số hàm thư viện rất hữu ích, khi cài đặt, cố gắng
tận dụng tối đa hàm thư viện này.
v C# hỗ trợ cho người lập trình rất nhiều trong
và
System.Collections
namespace
System.Collections.Generic.
Tóm tắt chương
v Biểu diễn đồ thị: dùng ma trận kề, ma trận trọng
số và danh sách mà giáo trình trình bày ở chương
này. Với các thuật toán tìm đường đi...
sách liên kết.
v Đồ thị và cây trong tài liệu chỉ giới thiệu tổ chức
dữ liệu là chính. Tìm hiểu sâu hơn, các bạn tìm
hiểu ở 2 giáo trình khác là: Lý thuyết đồ thị, Cấu
trúc Dữ liệu và Thuật toán.
BÀI TẬP
cuối cùng trong mảng.
mảng các số thực.
mảng các số nguyên.
mảng. Nếu không có phần tử âm trả về –1.
mảng.
BÀI TẬP
trong mảng.
mảng.
mảng.
trong mảng các số nguyên.
BÀI TẬP
tử có giá trị nhỏ hơn X.
tiên của mảng.
phần tử có giá trị lớn nhất trong mảng.
v Viết hàm chèn phần tử có giá trị X vào phía sau
tất cả các phần tử có giá trị chẵn trong mảng.
BÀI TẬP
v Viết hàm tách 1 mảng a các số nguyên thành 2
mảng b và c, sao cho mảng b chứa toàn số lẻ
và mảng c chứa số chẵn.
Mảng b: 1 3 7 5 9
Mảng c: 8 2 10
v Viết hàm ghép 2 mảng a và b các số nguyên đã
được sắp tăng thành mảng c, sao cho mảng c
cũng được sắp tăng.
v Ví dụ: Mảng a:2 8 10
Mảng b:1 3 5 7 9
Mảng c:1 2 3 5 7 8 9 10
BÀI TẬP
trong chuỗi.
chuỗi.
khoảng trắng thừa trong chuỗi.
vào s1. Xuất chuỗi s1 ra màn hình.
thường (không dùng hàm strlwr).
(không dùng hàm struppr).
BÀI TẬP
trong chuỗi.
v VCT tìm kiếm tên trong chuỗi họ tên. Nếu có thì
xuất ra là tên này đã nhập đúng, ngược lại
thông báo là đã nhập sai.
chuỗi tên.
Ø Ví dụ: chuỗi họ tên là:”Nguyễn Văn A” cắt ra 2
chuỗi là chuỗi họ lót:”Nguyễn Văn”,chuỗi tên
là:”A”
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.
BÀI TẬP
v Nhập một chuỗi bất kỳ, sau đó hỏi người dùng
cần tách bắt đầu từ đâu trong chuỗi trở về sau.
Ø Ví dụ: Nhập chuỗi S1: “Trường Đại học Ngoại
ngữ Tin học TPHCM”. Người nhập muốn tách
bắt đầu từ chữ “học” thì sẽ xuất ra chuỗi
“Ngoại ngữ Tin học TPHCM” ra màn hình.
v Viết hàm kiểm tra xem chuỗi có đối xứng hay
không?.
v Viết hàm kiểm tra xem trong chuỗi có ký tự số
hay không nếu có tách ra thành một mảng số
riêng.
v Nhập một chuỗi bất kì, yêu cầu nhập 1 ký tự
muốn xóa. Thực hiện xóa tất cả những ký tự đó
trong chuỗi.

