Professional Documents
Culture Documents
ĐỒ ÁN CƠ SỞ
Đề tài 319: SỬ DỤNG THAO TÁC LÀM VIỆC VỚI
DANH SÁCH LIÊN KẾT STACK VÀ FILE, GIẢI
PHƯƠNG TRÌNH BẬC CAO BẰNG PHƯƠNG PHÁP
DÂY CUNG.
Đà Nẵng, 7/2020
Đồ án Cơ sở
LỜI MỞ ĐẦU
Trước tiên em xin chân thành cảm ơn thầy Phạm Công Thắng, người đã từng
bước hướng dẫn, giúp đỡ em trong quá trình thực hiện đồ án cơ sở này.
Trong quá trình học tập, cũng như trong quá trình làm đồ án cơ sở không thể
tránh khỏi những thiếu sót không đáng có, em rất mong nhận được sự góp ý quý báu
của tất cả các Thầy Cô cũng như tất cả các bạn để đồ án cơ sở của em được hoàn thiện
hơn.
C là một ngôn ngữ nền tảng giúp bạn làm quen với việc lập trình. Khi đã học
vững được ngôn ngữ này bạn sẽ rất dễ dàng tiếp cận với các loại ngôn ngữ khác như
JAVA, PYTHON, C#… Vì vậy việc học C trở nên rất cấp thiết và quan trọng nếu bạn
là người yêu lập trình và muốn nó trở thành người bạn với nó. Nói nền tảng nhưng
không phải C là một ngôn ngữ dễ tiếp cận, điển hình như các phần như danh sách liên
kết, FILE,… cũng đang làm khó các bạn lập trình viên của chúng ta nếu chưa hiểu bản
chất của chúng. Ngoài ra việc sử dụng chúng để giải quyết các bài toán cũng trở nên
nan giải với chúng ta. Vì vậy trong khuôn khổ của đồ án cơ sở B này em xin sử dụng
các kiến thức mà thấy cô đã trang bị và sự tìm tòi từ sách vở và bạn bè để có thể làm
rõ một phần những khó khăn của các bạn sinh viên trong quá trình học tập. Cụ thể em
sẽ dùng kiến thức về danh sách liên kết kiểu stack và file để giải phương trình bậc cao
bằng phương pháp dây cung.
Em xin cam đoan rằng chuyên đề này là do chính em thực hiện, các số liệu thu
thập và kết quả phân tích trong đề án là trung thực, đề án không trùng với bất kỳ đề án
nào.
Một lần nữa em xin chân thành cảm ơn và kính chúc quý Thầy Cô dồi dào sức
khỏe và thành công trong cuộc sống.
MỤC LỤC
.............................................................................................................................. 1
LỜI MỞ ĐẦU.......................................................................................................2
MỤC LỤC............................................................................................................. 3
DANH MỤC HÌNH VẼ........................................................................................4
1. GIỚI THIỆU ĐỀ TÀI....................................................................................5
2. CƠ SỞ LÝ THUYẾT.....................................................................................5
2.1. Ý tưởng................................................................................................5
2.3. Cơ sở lý thuyết.....................................................................................5
3. TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN.............................15
3.1. Phát biểu bài toán...............................................................................15
3.2. Cấu trúc dữ liệu..................................................................................15
3.3. Thuật toán...........................................................................................16
4. CHƯƠNG TRÌNH VÀ KẾT QUẢ..............................................................16
4.1. Tổ chức chương trình.........................................................................16
4.2. Kết quả...............................................................................................17
4.2.1. Giao diện chính của chương trình...................................................17
4.2.2. Kết quả thực thi của chương trình...................................................19
4.2.3. Nhận xét..........................................................................................19
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN...........................................................19
a. Kết luận..................................................................................................19
b. Hướng phát triển....................................................................................20
TÀI LIỆU THAM KHẢO...................................................................................21
PHỤ LỤC ...........................................................................................................22
Hình 4: Giao diện của chương trình khi khởi động chương trình.
Hình 5: Giao diện của chương trình sau khi nhập một phím bất kì.
Hãy tìm các nghiệm của phương trình bằng phương pháp dây cung
(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.
Yêu cầu: Sử dụng danh sách liên kết kiểu ngắn xếp để thực hiện các công việc trên.
Dữ liệu đầu vào: file DAYSO.IN
Dữ liệu đầu ra: Kết quả thực hiện được lưu ở 2 file RESULT1.OUT, RESULT2.OUT.
2. CƠ SỞ LÝ THUYẾT
2.1. Ý tưởng
- Bắt đầu chương trình, một dãy số gồm N phần tử được đọc từ file DAYSO.IN.
- Sau khi đọc được được N phần tử số của danh sách liên kết từ file DAYSO.IN và in
ra màn hình, chương trình sẽ thực hiện xóa một phần tử trong danh sách này theo cơ
chế Last In- First Out, in kết quả sau khi xóa ra màn hình và lưu vào file
RESULT1.OUT.
- Tiếp theo, từ danh sách có được sau khi xóa một phần tử ( có M = N- 1 phần tử), các
phần tử này là hệ số của của đa thức G(x) = 0 bậc M-1, tìm nghiệm của đa thức này
bằng phương pháp dây cung, hiển thị kết quả và lưu vào file RESULT2.OUT.
2.2. Cơ sở lý thuyết
- Định nghĩa
Cấu trúc C tham chiếu trực tiếp một khối bộ nhớ vật lý liền kề, thường được phân
định (kích thước) theo các ranh giới độ dài từ. Nó tương ứng với tính năng có tên
tương tự có sẵn trong một số bộ lắp ráp cho bộ xử lý Intel. Việc triển khai ngôn
ngữ có thể sử dụng các ranh giới nửa từ hoặc byte ( cho việc đóng gói dày hơn,
sử dụng ít bộ nhớ hơn) được coi là tiến bộ vào giữa những năm 1980. Là một
khối bộ nhớ liền kề, mỗi trường trong một cấu trúc được đặt ở một độ lệch cố
định nhất định từ đầu[1].
Do nội dung của một cấu trúc được lưu trữ trong bộ nhớ liền kề, nên toán tử
sizeof phải được sử dụng để lấy số byte cần thiết để lưu trữ một loại cấu trúc cụ
thể, giống như nó có thể được sử dụng cho các nguyên hàm . Căn chỉnh của các
trường cụ thể trong cấu trúc (liên quan đến ranh giới từ ) là dành riêng cho việc
triển khai và có thể bao gồm phần đệm, mặc dù các trình biên dịch hiện đại
thường hỗ trợ lệnh #pragma pack, thay đổi kích thước theo byte được sử dụng để
căn chỉnh[1].
- Từ khóa typedef
Một kiểu dữ liệu có thể được định nghĩa bằng cách sử dụng từ khóa typedef.
Có thể sử dụng câu lệnh gán đơn giản để gán giá trị của một biến cấu trúc cho
một biến khác có cùng kiểu
Chẳng hạn, nếu books1 và books2 là các biến cấu trúc có cùng kiểu.
books2 = books1;
Các phần tử của cấu trúc được truy cập thông qua việc sử dụng toán tử
chấm(.),toán tử này còn được gọi là toán tử thành viên – membership.
Cú pháp: structure_name.element_name
2.2.2. FILE
· File văn bản – text files: File văn bản là file thường có đuôi là .txt. Những file
này bạn có thể dễ dàng tạo ra bằng cách dùng các text editer thông dụng như
Notepad, Notepad++, Sublime Text, …
· File nhị phân – binary file: File nhị phân thường có đuôi mở rộng là .bin.
· Để đọc ghi file trong C cũng như trong mọi ngôn ngữ lập trình, việc đầu tiên bạn
cần làm là mở file mà bạn muốn làm việc. Trong ngôn ngữ lập trình C, chúng ta
có thể mở file bằng cách sử dụng hàm fopen() trong thư viện stdio.h như sau: fptr
= fopen("fileopen", "mode");
r Mở file chỉ cho phép đọc Nếu file không tồn tại,
fopen() trả về NULL.
rb Mở file chỉ cho phép đọc Nếu file không tồn tại,
dưới dạng nhị phân fopen() trả về NULL.
w Mở file chỉ cho phép ghi. Nếu file đã tồn tại, nội
dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
wb Mở file chỉ cho phép ghi Nếu file đã tồn tại, nội
dưới dạng nhị phân dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
a Mở file ở chế độ ghi Nếu file không tồn tại,
“append”. Tức là sẽ ghi nó sẽ được tạo tự động.
vào cuối của nội dung đã
có.
ab Mở file ở chế độ ghi nhị Nếu file không tồn tại,
phân “append”. Tức là sẽ nó sẽ được tạo tự động.
ghi vào cuối của nội
dung đã có.
r+ Mở file cho phép cả đọc Nếu file không tồn tại,
và ghi. fopen() trả về NULL.
rb+ Mở file cho phép cả đọc Nếu file không tồn tại,
và ghi ở dạng nhị phân. fopen() trả về NULL.
w+ Mở file cho phép cả đọc Nếu file đã tồn tại, nội
và ghi. dung sẽ bị ghi đè. Nếu
file không tồn tại, nó sẽ
được tạo tự động.
wb+ Mở file cho phép cả đọc Nếu file đã tồn tại, nội
và ghi ở dạng nhị phân. dung sẽ bị ghi đè. Nếu
- Định nghĩa
Mảng là một tập hợp tuần tự các phần tử có cùng kiểu dữ liệu và các phần tử được
lưu trữ trong một dãy các ô nhớ liên tục trên bộ nhớ. Các phần tử của mảng được truy
cập bằng cách sử dụng “chỉ số”. Mảng có kích thước N sẽ có chỉ số từ 0 tới n-1. Hình
1 mô phỏng cho cấu trúc mảng một chiều [1,3].
Cú pháp khai báo mảng 1 chiều khác nhau với từng ngôn ngữ lập trình.
Chẳng hạn, trong C/C++, việc khai báo mảng cần 2 tham số sau:
Kích thước của mảng: Việc này xác định số lượng phần tử có thể được
Kiểu dữ liệu của mảng: Việc này chỉ định kiểu dữ liệu của các phần tử trong mảng; là
số nguyên, số thực, ký tự hay là kiểu dữ liệu nào đó.
Mảng có thể được khởi tạo ngay tại thời điểm khai báo mảng hoặc khởi
Mảng cũng có thể được khởi tạo sau khi khai báo xong, bằng cách gán
type arr[size]
arr[index] = 12
Ví dụ trên C
int arr[5];
arr[0] = 4;
arr[1] = 12;
- Định nghĩa:
Mảng hai chiều là một bảng các phần tử cùng kiểu, mảng cũng được đặt tên như mảng
một chiều, các phần tử cũng được đánh số thứ tự để quản lí. Tuy nhiên, mỗi phần tử
của mảng hai chiều được bằng hai chỉ số, chúng ta tạm gọi chúng là chỉ số dòng và chỉ
số cột. Hình 2 mô phỏng cho cấu trúc mảng hai chiều [1,4].
Để khai báo mảng 2 chiều, bạn phải chỉ định các tham số sau:
+Type of array: Kiểu dữ liệu của mảng 2 chiều. Việc này chỉ định kiểu dữ liệu của các
phần tử trong mảng; là số nguyên, số thực, ký tự hay là kiểu dữ liệu nào đó
Type arr[row_size][column_size]
Giống như mảng 1 chiều , mảng 2 chiều cũng có thể khởi tạo trong quá trình khai báo
hoặc khởi tạo sau khi khai báo.
Cú pháp khởi tạo của mảng 2 chiều trong khi khai báo như sau:
Type arr[row_size][column_size]={{elements},{elements}…}
Ví dụ: arr[3][5]={{1,2,3,3,4},{1,2,3,4,5,},{5,4,2,5,4,2}};
Định nghĩa :
Danh sách liên kết là một tập hợp tuyến tính các phần tử dữ liệu, với thứ tự không
được đưa ra bởi vị trí vật lí của chúng trong bộ nhớ. Thay vào đó, mỗi phần tử chỉ đến
phần tử tiếp theo. Nó là một cấu trúc dữ liệu bao gồm một tập hợp các nút cùng thể
hiện một dãy. Ở dạng cơ bản nhất, mỗi nút chứa: dữ liệu, và một tham chiếu (hay nói
cách khác là liên kết) tới nút kế tiếp trong dãy. Cấu trúc này cho phép chèn hay loại bỏ
bất kì phần tử nào trong chuỗi một cách hiệu quả. Các biến thể phức tạp hơn như thêm
các liên kết bổ sung, cho phép chèn hay loại bỏ các nút hiệu quả hơn tại vị trí bất kì.
Một nhược điểm của danh sách liên kết là thời gian truy cập là tuyết tính ( và khó thực
thi ống dẫn). Truy cập nhanh hơn, ví dụ như truy cập ngẫu nhiên, là không khả thi.
Mảng có vùng đệm ( cache locality) tốt hơn so sánh với liên kết.
Danh sách liên kết là một trong những cấu trúc dữ liệu đơn giản và phổ biến nhất. Nó
có thể được hiện thực một số kiểu dữ liệu trừu tượng phổ biến khác, bao gồm danh
sách ( LIST), ngăn xếp ( STACK), hàng đợi, mảng liên kết và S-expression, mặc dù
không có gì lạ khi thực hiện các cấu trúc đó mà không dựa trên nền tảng của danh sách
liên kết.
Ví dụ: Ta có thể xem hình ảnh trực quan của ngăn xếp bằng một chồng đĩa đặt trên
bàn . Muốn thêm vào chồng đó 1 đĩa ta để đĩa mới trên đỉnh chồng , muốn lấy các đĩa
ra khỏi chồng ta cũng phải lấy đĩa trên trước. Như vậy ngăn xếp là cấu trúc có tính
chất “ vào sau – ra trước” hay “ vào trước ra sau”(LAST IN – FIRST OUT (LIFO))
hay (FIRST IN – LAST OUT (FILO)).
TOP(L): xem như một hàm trả về phần tử tại đỉnh của ngăn xếp. Nếu ngăn xếp rỗng
thì hàm không xác định.
POP(L) : Chương trình con xóa một phần tử tại đỉnh ngăn xếp.
PUSH (L) chương trình thêm một phần tử vào đỉnh ngăn xếp.
ISEMPTY(L) Kiểm tra ngăn xếp rỗng. Hàm cho kết quả 1 (true) nếu ngăn xếp rỗng thì
trả về kết quả 0 (false) trong trường hợp ngược lại.
Khi chúng ta đã dùng danh sách để biểu diễn cho ngăn xếp thì ta nên sử dụng các phép
toán trên danh sách để cài đặt các phép toán trên ngăn xếp. Sau đây là phần cài đặt
ngăn xếp bằng danh sách mà tôi sử dụng trong đồ án:
else return 0;
p->data = x;
p->next = NULL;
return p;
if (isEmpty(s))
s->head = s->tail = p; // neu stack rong thi ta gan p la phan tu dau va cuoi
else
if (!isEmpty(s))
s->head = p->next;
free(p);
else
Hãy tìm các nghiệm của phương trình bằng phương pháp dây cung
(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.
Yêu cầu: Sử dụng danh sách liên kết kiểu ngắn xếp để thực hiện các công việc trên.
Dữ liệu đầu vào: file DAYSO.IN
Dữ liệu đầu ra: Kết quả thực hiện được lưu ở 2 file RESULT1.OUT,
RESULT2.OUT.
Hình 4: Giao diện của chương trình khi khởi động chương trình.
Hình 5: Giao diện của chương trình sau khi nhập một phím bất kì.
c) Tìm các nghiệm của phương trình bằng phương pháp dây cung
(với sai số ), hiển thị kết quả và lưu kết quả ra file RESULT2.OUT.
a. Kết luận
- Về kiến thức:
+ Nâng cao tinh thần tự học, tự nghiên cứu.
+ Hiểu hơn về danh sách liên kết kiểu Stack, đọc ghi File.
+ Có thể giải phương trình bậc cao bằng phương pháp dây cung.
- Về chương trình:
+ Sử dụng danh sách liên kết kiểu ngăn xếp để thực hiện các công việc: đọc,
ghi dữ liệu từ file, tìm kiếm, xóa một phần tử trong danh sách.
+ Giao diện chương trình chưa đẹp và bắt mắt.
[1] Phan Chí Tùng, Bài giảng Cấu trúc dữ liệu, Khoa CNTT, ĐHBK-ĐHĐN, lưu
hành nội bộ.
[2] Đỗ Thị Tuyết Hoa, Bài giảng Phương pháp tính, Khoa CNTT, ĐHBK-
ĐHĐN, lưu hành nội bộ
[3] Nguyenvanhieu, URL: https://nguyenvanhieu.vn/ngan-xep-stack/, ngày truy
cập: 20/7/2020.
[4] Nguyenvanhieu, URL: https://nguyenvanhieu.vn/mang-2-chieu-trong-c/, ngày
truy cập: 20/7/2020
PHỤ LỤC
Code đồ án:
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
struct Node
{
float data;
struct Node *next;
};
struct List
{
struct Node *head;
struct Node *tail;
};
// tao Node
struct Node *creat_Node(float x)
{
struct Node *p = (struct Node*) malloc( sizeof(struct Node) );
p->data = x;
p->next = NULL;
return p;
}
while (p != NULL)
{
printf("\t%.2f",p->data);
p = p->next;
}
}
int i,j;
for(i=1;i<=n;i++)
{
printf("\t-------------------------------------- Danh sach thu %2d
--------------------------------------\n\n\t",i);
Init(&s[i]);// khoi tao stack
int i,j;
int n;
for (i=1;i<=1;++i)
{
struct Node *p = s[i].head;
while (p!=NULL){
a[i][j]=p->data;
p=p->next;
j++;
}
for (i=0;i<1;++i)
{
for (k=0;k<j;k++)
{
pt += a[i][k]*pow(x,k);
}
}
return pt;
while (p!=NULL){
a[i][j]=p->data;
p=p->next;
j++;
}
int k,l=0;
printf("\n\t------------------------------------------- Giai pt
------------------------------------------\n\n\t\t");
for (i=0;i<1;++i)
{
printf("%0.1f ", a[0][0]);
printf("+ %.0fx ", a[0][1]);
for (k=2;k<j;k++)
{
int k=1,h;
int nghiem;
do
{
printf("\n\n\t\tPhuong trinh co bao nghiem : ");
scanf("%d", &nghiem);
if (nghiem == 0)
{
if (h == 0)
printf("\n\n\t----------------------------------- Ket thuc chuong trinh
------------------------------------\n\n");
else
if(h<= nghiem)
{
f=fopen("RESULT2.OUT","w");
do
{
do
{
printf("\n\t\tCho gia tri cua a = ");
scanf("%f",&a);
printf("\t\tCho gia tri cua b = ");
scanf("%f",&b);
}
while (pt(s,f,a)*pt(s,f,b) > 0 );
ga=pt(s,f,a);
fclose(f);
printf("\n\n\t----------------------------------- Ket thuc chuong trinh
------------------------------------\n\n");
}
FILE*f;
Doc_file(s,f,n,m);
xoaphantu(s);
xuat_file(s,f);
giai_pt(s,f);
}