You are on page 1of 8

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN ĐỀ THI GIỮA KỲ

BAN HỌC TẬP KHOA HỌC VÀ KỸ THUẬT HỌC KỲ 2 – NĂM HỌC 2021 - 2022
THÔNG TIN MÔN: CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
BAN HỌC TẬP HỆ THỐNG THÔNG TIN Thời gian: 75 phút
Đề thi số: 1A

(Lưu ý: sinh viên không được tham khảo tài liệu – Đề thi gồm có 2 trang)

Câu 1 (2.5 điểm):

a. Hãy trình bày ý tưởng giải thuật tìm kiếm tuyến tính và cho biết độ phức tạp của
giải thuật (1 điểm)
b. Trình bày các bước (vẽ từng bước) giải thuật tìm kiếm tuyến tính thực hiện tìm
kiếm giá trị X = 24 trong mảng số nguyên có 6 phần tử: 1, 90, 23, 50, 16, 2000
(1.5 điểm)

Câu 2 (3.5 điểm):

Trường Đại học A cần quản lí điểm của một lớp sinh viên gồm N thành viên (1<N<100) ,
với các thông tin như: Mã số sinh viên, họ và tên, giới tính (1: nam, 2: nữ), lớp, điểm
trung bình chung (thang điểm 10).

a. Định nghĩa cấu trúc dữ liệu lưu danh sách các thông tin trên, sử dụng cấu trúc
danh sách liên kết. (0.5 điểm)
b. Viết hàm nhập vào danh sách điểm tổng kết của M sinh viên từ bàn phím
(0<M<N), sử dụng cấu trúc dữ liệu ở câu 2a. Biết rằng, khi nhập vào thông tin
sinh viên sẽ thêm vào đầu danh sách (1.5 điểm)
c. Viết hàm xuất danh sách thành viên của lớp, mỗi thành viên xuất riêng thành từng
dòng. (0.5 điểm)
d. Viết hàm tìm kiếm số sinh viên có điểm trung bình là X trong danh sách với X
được nhập từ bàn phím. Nếu có thì in ra số học sinh được X điểm, nếu không thì
in ra “None”. (1 điểm)
Câu 3 (4 điểm):
Cho xâu S gồm các ký tự “( , { , [ , ) , } , ]”. Hãy xây dựng và sử dụng cấu trúc ngăn xếp
(stack) với các yêu cầu sau:
a. Định nghĩa cấu trúc ngăn xếp để lưu trữ xâu S (0.5 điểm).

Mã số sinh viên:…………………………….. 1
b. Viết các hàm thao tác với cấu trúc ngăn xếp trong câu 3a: push, pop, kiểm tra
stack rỗng, lấy phần tử ở đỉnh của stack, kiểm tra số phần tử trong stack.
(2.5 điểm)
c. Viết hàm nhập vào xâu S gồm có N kí tự. Sử dụng cấu trúc và các hàm đã được
định nghĩa ở câu 3a và 3b để kiểm tra xem S có phải dãy ngoặc đúng hay không?
Kết quả trả về là true nếu đúng và false nếu sai (Biết rằng cặp ngoặc được coi là
phù hợp nếu dấu ngoặc mở xuất hiện ngay bên trái dấu ngoặc đúng). (1 điểm)
Ví dụ mẫu:
(1) ({[)]}: sai
(2) (]: sai
(3) )()[](: sai
(4) ()[]{}: đúng
(5) (){{[(([{(())}]))]}}: đúng

--------------------------------------------- Hết ----------------------------------------

(Lưu ý: CBCT không giải thích gì thêm)

Mã số sinh viên:…………………………….. 2
ĐÁP ÁN THAM KHẢO ĐỀ 1A

Câu 1 (2.5 điểm):

a. Hãy trình bày ý tưởng giải thuật tìm kiếm tuyến tính và cho biết độ phức tạp của
giải thuật (1 điểm)
- Ý tưởng giải thuật (0.5 điểm): Xuất phát từ đầu mảng/danh sách để tìm kiếm
một phần tử X cho trước bằng cách duyệt lần lượt từng phần tử của mảng/danh
sách đó. Tại từng vị trí thực hiện so sánh với giá trị cần tìm. Nếu bằng nhau thì
dừng thuật toán và thông báo có giá trị cần tìm và kết thúc. Nếu không bằng thì
tiếp tục so sánh đến khi nào tìm được giá trị X. Nếu duyệt hết không có thì
thông báo không tồn tại X trong mảng/danh sách và kết thúc.
- Độ phức tạp thuật toán (0.5 điểm): O(N)
b. Trình bày các bước (vẽ từng bước) giải thuật tìm kiếm tuyến tính thực hiện tìm
kiếm giá trị X = 24 trong mảng số nguyên có 6 phần tử: 1, 90, 23, 50, 16, 2000
(1.5 điểm)
Mỗi bước thực hiện đúng được 0.25 điểm
Mảng A:
1 90 23 50 16 2000

- Bước 1: i = 0, so sánh A[i] với X = 24, A[0] = 1 != X = 24, chuyển qua xét
phần tử tiếp theo trong mảng A, i = i + 1.
- Bước 2: i = 1, so sánh A[i] với X = 90, A[0] = 1 != X = 24, chuyển qua xét
phần tử tiếp theo trong mảng A, i = i + 1.
- Bước 3: i = 2, so sánh A[i] với X = 23, A[0] = 1 != X = 24, chuyển qua xét
phần tử tiếp theo trong mảng A, i = i + 1.
- Bước 4: i = 3, so sánh A[i] với X = 50, A[0] = 1 != X = 24, chuyển qua xét
phần tử tiếp theo trong mảng A, i = i + 1.
- Bước 5: i = 4, so sánh A[i] với X = 16, A[0] = 1 != X = 24, chuyển qua xét
phần tử tiếp theo trong mảng A, i = i + 1.
- Bước 6: i = 5, so sánh A[i] với X = 2000, A[0] = 1 != X = 24. Đã xét phần tử
cuối cùng trong mảng, thông báo không có X trong mảng.

Câu 2 (3.5 điểm):

Trường Đại học A cần quản lí điểm của một lớp sinh viên gồm N thành viên (1<N<100) ,
với các thông tin như: Mã số sinh viên, họ và tên, giới tính (1: nam, 2: nữ), lớp, điểm
trung bình chung (thang điểm 10).

Mã số sinh viên:…………………………….. 3
a. Định nghĩa cấu trúc dữ liệu lưu danh sách các thông tin trên, sử dụng cấu trúc
danh sách liên kết. (0.5 điểm)
*Có nhiều cách định nghĩa, miễn đúng đều được trọn điểm.
*Định nghĩa được struct List (+0.25 điểm), định nghĩa được struct chứa thông
tin (+0.25 điểm)
struct ThongTin
{
string MSSV, HoTen, Lop;
int GioiTinh;
double DTB;
};

struct Node
{
ThongTin data;
Node *pNext;
};

struct List
{
Node *pHead = NULL;
Node *pTail = NULL;
};

b. Viết hàm nhập vào danh sách điểm tổng kết của M sinh viên từ bàn phím
(0<M<N), sử dụng cấu trúc dữ liệu ở câu 2a. Biết rằng, khi nhập vào thông tin
sinh viên sẽ thêm vào đầu danh sách (1.5 điểm)
*Viết được hàm thêm vào đầu danh sách (+0.75 điểm)
*Viết được hàm nhập (+0.75 điểm, viết hàm CreateNode trong hàm nhập nếu
đúng vẫn tính trọn điểm)
Node *Create_node(ThongTin x)
{
Node *p = new Node;
if (p == NULL)
return NULL;
p->data = x;
p->pNext = NULL;
return p;
}

Mã số sinh viên:…………………………….. 4
void add_first_node(List &list, Node *p)
{
if(list.pHead == NULL)
list.pHead = list.pTail = p;
else
{
p->pNext = list.pHead;
list.pHead = p;
}
}

void Nhap(List &list)


{
int n;
do {
cout << "So luong hoc sinh: ";
cin >> n;
} while (n < 0 || n > 100);

cout << "Nhap thong tin n hoc sinh: ";


for (int i = 0; i < n; i++)
{
ThongTin x;
cout << "Nhap MSSV: ";
cin.ignore();
getline(cin, x.MSSV);
cout << "Nhap ho ten: ";
getline(cin, x.HoTen);
cout << "Nhap gioi tinh (1: nam, 2: nu): ";
cin >> x.GioiTinh;
cin.ignore();
cout << "Nhap lop: ";
getline(cin, x.Lop);
cout << "Nhap DTB: ";
cin >> x.DTB;
Node *p = Create_node(x);
add_first_node(list, p);
}
}

Mã số sinh viên:…………………………….. 5
c. Viết hàm xuất danh sách thành viên của lớp, mỗi thành viên xuất riêng thành từng
dòng. (0.5 điểm)
void Xuat(List list)
{
for(Node* p = list.pHead; p!=NULL; p=p->pNext)
cout << p->data.MSSV << "\t"
<< p->data.HoTen << "\t"
<< p->data.GioiTinh << "\t"
<< p->data.Lop << "\t"
<< p->data.DTB << endl;
}

d. Viết hàm tìm kiếm số sinh viên có điểm trung bình là X trong danh sách với X
được nhập từ bàn phím. Nếu có thì in ra số học sinh được X điểm, nếu không thì
in ra “None”. (1 điểm)
void tim_diem_tong_ket(List list)
{
double diem, Count;
cout << "Nhap diem can tim: ";
cin >> diem;

for (Node* p = list.pHead; p!=NULL; p=p->pNext)


if (p->data.DTB == diem)
Count++;

if(Count == 0)
cout << "None";
else
cout << "Co " << Count << "sinh vien duoc " << diem;
}

Câu 3 (4 điểm):
Cho xâu S gồm các ký tự “( , { , [ , ) , } , ]”. Hãy xây dựng và sử dụng cấu trúc ngăn xếp
(stack) với các yêu cầu sau:
a. Định nghĩa cấu trúc ngăn xếp để lưu trữ xâu S (0.5 điểm).
*Có thể dùng mảng / danh sách liên kết để lưu trữ xâu S
Mảng DSLK
struct Stack

Mã số sinh viên:…………………………….. 6
{
char a[1000];
int n;
};

b. Viết các hàm thao tác với cấu trúc ngăn xếp trong câu 3a: khởi tạo, push, pop,
kiểm tra stack rỗng, lấy phần tử ở đỉnh của stack, đếm số phần tử trong stack.
(2.5 điểm)
*Với mỗi hàm đúng: +0,5 điểm
*Tham số truyền vào sai giữa tham trị / tham chiếu trong khởi tạo, push, pop
=> +0 điểm
Mảng DSLK
void Init(Stack &s)
{
s.n = 0;
}

bool empty(Stack s)
{
return (s.n==0); //(hoặc s.n==-1)
}

char top(Stack s)
{
return s.a[s.n-1];
}

void push(Stack &s, char data)


{
s.a[s.n++] = data;
}

char pop(Stack &s)


{
return s.a[--s.n];
}

int SoLuong(Stack s)
{
return s.n; //(hoặc s.n-1);
}

Mã số sinh viên:…………………………….. 7
c. Viết hàm nhập vào xâu S gồm N phần tử. Sử dụng cấu trúc và các hàm đã được
định nghĩa ở câu 3a và 3b để kiểm tra xem S có phải dãy ngoặc đúng hay không?
Kết quả trả về là true nếu đúng và false nếu sai (Biết rằng cặp ngoặc được coi là
phù hợp nếu dấu ngoặc mở xuất hiện ngay bên trái dấu ngoặc đúng). (1 điểm)
Ví dụ:
(1) ({[)]}: sai
(2) (]: sai
(3) )()[](: sai
(4) ()[]{}: đúng ()[]{}
(5) (){{[(([{(())}]))]}}: đúng
*Có thể dùng char* thay thế string.
*Nếu hướng giải quyết khác vẫn đúng thì vẫn cho trọn điểm.
Mảng DSLK
bool isBalanced(Stack &st, string s) {
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(' || s[i] == '[' || s[i] ==
'{')
push(st, s[i]);
else if (s[i] == ')' && pop(st) != '(')
return 0;
else if (s[i] == ']' && pop(st) != '[')
return 0;
else if (s[i] == '}' && pop(st) != '{')
return 0;
}
return 1;
}

**Lưu ý: Nếu viết thiếu dấu “;” hoặc cặp dấu “{}” dẫn đến sai lỗi cú pháp => -0.25
điểm / trường hợp.

HẾT

Mã số sinh viên:…………………………….. 8

You might also like