Tải bản đầy đủ (.pdf) (34 trang)

Tiểu luận Lập trình cấu trúc C++ "Xây dựng lớp đa thức"

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (563.04 KB, 34 trang )



TRƯỜNG ĐH HỒNG ĐỨC
KHOA CNTT&TT









BÀI TIỂU LUẬN

HỌC PHẦN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
C++

Đề tài:
“Xây dựng lớp đa thức”




SVTH : Bùi Hữu Giáp
Lớp : Đại học tin – K15
MSV : 1261030003



Thanh Hóa, 11/2014




TRƯỜNG ĐH HỒNG ĐỨC
KHOA CNTT&TT







BÀI TIỂU LUẬN

HỌC PHẦN LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG
C++

Đề tài:
“Xây dựng lớp đa thức”




SVTH : Bùi Hữu Giáp
Lớp : Đại học tin – K15
MSV : 1261030003
GVHD : ThS. Nguyễn Thị Xuân Đài





Thanh Hóa, 11/2014


LỜI CẢM ƠN
Trong quá trình học tập tại trường, chúng em đã được học hỏi và tiếp thu
rất nhiều kiến thức đại cương cũng như chuyên ngành nhằm nâng cao vốn hiểu
biết và là hành trang quý báu giúp chúng em vững bước vào đời. Em xin gửi lời
cảm ơn chân thành đến quý thầy cô đã giảng dạy chúng em trong suốt thời gian
qua, khoa Công Nghệ Thông Tin và truyền thông cũng như tất cả quý thầy cô
trong trường Đại học Hồng Đức. Đặc biệt em xin chân thành cảm ơn cô Nguyễn
Thị Xuân Đài – người đã trực tiếp giảng dạy chúng em học phần Lập trình
hướng đối tượng C++ và cũng là người tận tình hướng dẫn em trong suốt thời
gian thực hiện đề tài này.
Tuy nhiên, dù rất cố gắng nhưng do thời gian có hạn nên bài tiểu luận của
em khó tránh khỏi những thiếu sót. Em rất mong nhận được sự thông cảm và đóng
góp ý kiến của quý thầy cô và các bạn để bài tiểu luận của em được hoàn chỉnh
hơn.
Em xin chân thành cảm ơn!


Thanh Hóa, 11/2014
Sinh viên thực hiện

i

MỤC LỤC
CHƯƠNG I: MỞ ĐẦU 1

1.1.


Lí do chọn đề tài 1

1.2.

Mục tiêu và nhiệm vụ của đề tài 1

1.2.1.

Mục tiêu đề tài 1

1.2.2.

Nhiệm vụ đề tài 1

1.3.

Khách thể, đối tượng và phạm vi nghiên cứu 2

1.3.1.

Khách thể nghiên cứu 2

1.3.2.

Đối tượng và phạm vi nghiên cứu 2

1.4.

Các phương pháp nghiên cứu 2


CHƯƠNG II: CƠ SỞ LÍ LUẬN 3

2.1.

Khái niệm đa thức một biến. 3

2.2.

Phép cộng trừ hai đa thức. 3

2.3.

Phép nhân hai đa thức. 3

2.4.

Phép chia có dư của hai đa thức. 4

2.5.

Đạo hàm của đa thức. 4

2.6.

Nguyên hàm của một đa thức. 4

CHƯƠNG III: NỘI DUNG 6

3.1.


Xây dựng lớp phân số 6

3.2.

Xây dựng lớp đơn thức 8

3.3.

Lưu trữ và chuẩn hóa đa thức 10

3.3.1.

Lưu trữ 10

3.3.2.

Chuẩn hóa 10

3.4.

Xây dựng các hàm tạo cho đa thức 11

3.5.

Xây dựng các toán tử cho đa thức 12

3.5.1.

Nhóm các toán tử số học 12


3.5.2.

Toán tử gán 16

3.5.3.

Nhóm các toán tử gán phức hợp 17

ii

3.5.4.

Xây dựng toán tử vào và ra 18

3.5.5.

Nhóm các toán tử quan hệ 19

3.5.6.

Nhóm các toán tử khác 19

3.6.

Hàm tính đạo hàm đa thức 19

3.7.

Hàm tính nguyên hàm của đa thức 20


3.8.

Hàm tính giá trị của đa thức 21

3.9.

Nhóm các hàm khác của đa thức 22

3.10.

Xây dựng giao diện chương trình 22

CHƯƠNG IV: KẾT LUẬN 27

4.1.

Tóm tắt kết quả nghiên cứu 27

4.2.

Đề xuất và hướng phát triển 27

TÀI LIỆU THAM KHẢO 29


Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp

1
GVHD: ThS. Nguyễn Thị Xuân Đài

CHƯƠNG I: MỞ ĐẦU
1.1. Lí do chọn đề tài
Đa thức là một trong những phạm trù toán học cơ bản, không chỉ học sinh ở
nước ta mà còn ở tất cả các nước trên thế giới được tiếp cận khá sớm. Ở Việt Nam,
ngay từ chương trình môn toán trung học cơ sở, học sinh đã được tiếp cận với
khái niệm đa thức. Một trong những khái niệm mở đầu được đề cập tới đó là đa
thức một biến.
Có rất nhiều phép toán có thể thực hiện trên đa thức một biến như: cộng hai
đa thức, trừ hai đa thức, nhân hai đa thức… Việc thực hiện các phép toán này đối
với những đa thức nhỏ, có ít phần tử thì ta có thể thực hiện và kiểm tra tính đúng
đắn một cách dễ dàng và nhanh chóng. Tuy nhiên, với những đa thức thực tế trong
các lĩnh vực khoa học thường có số lượng phần tử rất lớn, có độ phức tạp rất cao,
việc thực hiện tính toán thủ công làm chúng ta tốn khá nhiều thời gian và công
sức mà độ tin cậy lại không cao. Khi đó, chiếc máy tính điện tử sẽ trở thành một
trợ thủ đắc lực của bạn và một chương trình được viết ra có thể giúp bạn giải quyết
những công việc trên một cách dễ dàng và nhanh chóng với độ chính xác cao.
Để định nghĩa một kiểu dữ liệu mới đồng thời mang lại cho tất cả mọi người
một công cụ hữu ích giúp thực hiện tất cả các phép toán thường gặp trên đa thức
một biến, tôi đã quyết định lựa chọn đề tài “Cài đặt lớp đa thức”. Để có thể nắm
rõ được những thuật toán được sử dụng cũng như cách thức tổ chức hoạt động của
chương trình, mời các bạn tìm hiểu phần nội dung đề tài.
1.2. Mục tiêu và nhiệm vụ của đề tài
1.2.1. Mục tiêu đề tài
Đề tài này được thực hiện nhằm định nghĩa một kiểu dữ liệu mới đồng thời
tạo ra một chương trình thực hiện tất cả các phép toán thường gặp đối với đa thức
một biến bao gồm: cộng hai đa thức, trừ hai đa thức, nhân hai đa thức…
1.2.2. Nhiệm vụ đề tài

- Xây dựng lớp phân số.
- Xây dựng lớp đơn thức.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
2
GVHD: ThS. Nguyễn Thị Xuân Đài

- Tổ chức lưu trữ một đa thức một biến cụ thể.
- Chuẩn hóa đa thức theo đúng những quy tắc trong toán học.
- Xây dựng hàm tạo cho lớp.
- Xây dựng các toán tử cho lớp.
- Xây dựng hàm tính đạo hàm của một đa thức.
- Xây dựng hàm tính nguyên hàm của một đa thức.
- Xây dựng giao diện cho chương trình.
1.3. Khách thể, đối tượng và phạm vi nghiên cứu
1.3.1. Khách thể nghiên cứu
Cài đặt lớp đa thức và một chương trình demo thực hiện tất cả những phép
toán thường gặp trên đa thức một biến.
1.3.2. Đối tượng và phạm vi nghiên cứu
Lớp đa thức và các phép toán thường gặp trên đa thức một biến.
1.4. Các phương pháp nghiên cứu
- Phương pháp thu thập tài liệu: thu thập tài liệu từ những bài báo khoa
học, các trang web tin học và một số ebook về đề tài nghiên cứu, giáo
trình và các tài liệu học tập khác.
- Phương pháp phân tích và tổng hợp tài liệu: từ những tài liệu đã thu
thập, tiến hành tìm hiểu, phân tích và tồng hợp nội dung liên quan đến
đề tài.

- Phương pháp chuyên gia: trong quá trình nghiên cứu có sự góp ý, điều
chinh từ giáo viên hướng dẫn.
- Phương pháp phân tích và tổng hợp kinh nghiệm: sau quá trình tìm
hiểu và đúc kết kinh nghiệm, tiến hành tổng hợp và hoàn thiện đề tài.
- Phương pháp thực nghiệm: sau khi cài đặt xong chương trình cần xây
dựng một số bộ test tiêu biểu và thực hiện kiểm tra tính đúng đắn dựa
trên kết quả thu được từ chương trình.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
3
GVHD: ThS. Nguyễn Thị Xuân Đài

CHƯƠNG II: CƠ SỞ LÍ LUẬN
2.1. Khái niệm đa thức một biến.
Các đa thức của một biến (cũng được gọi là đa thức một ẩn) có dạng
P(x) = a
0
+ a
1
x + + a
n-1
x
n-1
+ a
n
x
n

với các hệ số a
i
∊ℝ là một đa thức một biến trên ℝ. Nếu a
n
≠ 0 thì P(x) là đa
thức một biến bậc n.
Đa thức trên có thể viết ngắn gọn nhờ ký hiệu xich-ma là
(x) =








2.2. Phép cộng trừ hai đa thức.
Cho hai đa thức:
(x) =








(x) =









Khi đó phép cộng và trừ hai đa thức P(x) và Q(x) được thực hiện theo từng
hệ số của x
k
, tức là

(

)
+() =

(


±

)




{,}


2.3. Phép nhân hai đa thức.

Cho hai đa thức:
(x) =








Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
4
GVHD: ThS. Nguyễn Thị Xuân Đài

(x) =








Khi đó P(x) . Q(x) là một đa thức có bậc m + n và có các hệ số xác định bởi



=








2.4. Phép chia có dư của hai đa thức.
Với hai đa thức P(x) và Q(x) bất kỳ, trong đó bậc của đa thức Q deg(Q) ≥
1, tồn tại duy nhất các đa thức S(x) và R(x) thoả mãn đồng thời các điều kiện:
i. P(x) = Q(x) . S(x) + R(x)
ii. deg(R) < deg(Q)
S(x) được gọi là thương số và R(x) được gọi là số dư trong phép
chia P(x) cho Q(x).
2.5. Đạo hàm của đa thức.
Cho hàm số biến số thực y = ʄ(x) xác định trên khoảng (a; b) (khoảng (a;
b)={x ∊ℝ | a < x < b}). Xét giá trị x
0
∊(a; b) và giá trị x ∊(a; b).
Đặt Δx = x − x
0
thì x = x
0
+ Δx . Δx được gọi là số gia đối số.
Đặt Δy = f(x) – f(x
0
). Δy được gọi là số gia hàm số.
Xét tỷ số 



. Nếu khi Δx→0, tỷ số đó dần tới một giới hạn thì giới hạn đó
được gọi là đạo hàm của hàm số y = f(x) tại điểm x
0
kí hiệu là ʄ'(x) hay
̇
().
ʄ

(
x
)
= lim
→
ʄ
(


+Δx
)
−ʄ(

)


Công thức tính đạo hàm đa thức một biến:
(u + v)' = u' + v'
(x
α

)' = α . x
α-1

2.6. Nguyên hàm của một đa thức.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
5
GVHD: ThS. Nguyễn Thị Xuân Đài

Cho hàm f xác định trên D ⊂ ℝ. Hàm F là một nguyên hàm của f nếu F’(x)
= f(x) với mọi x ∊D.
Công thức tính nguyên hàm đa thức một biến:
(u + v)' = u' + v'
(x
α
)' = α . x
α-1

Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
6
GVHD: ThS. Nguyễn Thị Xuân Đài

CHƯƠNG III: NỘI DUNG

3.1. Xây dựng lớp phân số
Trong chương trình, chúng tôi đã xây dựng lớp phân số trong thư viện
fraction.h với nội dung như sau:
class fraction
{
long nume, deno;
long ucln(long a, long b);
void standize();
public:
fraction(long nu=0, long de=1);
~fraction();
long set_fraction(long nu=0, long de=1);
long get_nume();
long get_deno();
//
fraction operator -();
operator float();
operator long();
friend fraction operator +(fraction const &a, fraction const &b);
friend fraction operator -(fraction const &a, fraction const &b);
friend fraction operator *(fraction const &a, fraction const &b);
friend fraction operator /(fraction const &a, fraction const &b);
fraction operator ++();
fraction operator ();
fraction operator ++(int);
fraction operator (int);
fraction operator +=(const fraction &f);
fraction operator -=(const fraction &f);
fraction operator *=(const fraction &f);
fraction operator /=(const fraction &f);

fraction operator ^=(long exp);
friend fraction operator ^(const fraction &f, long exp);
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
7
GVHD: ThS. Nguyễn Thị Xuân Đài

void operator =(const fraction &f);
friend long operator ==(const fraction &f1, const fraction &f2);
friend long operator !=(const fraction &f1, const fraction &f2);
friend long operator >(const fraction &f1, const fraction &f2);
friend long operator <(const fraction &f1, const fraction &f2);
friend long operator >=(const fraction &f1, const fraction &f2);
friend long operator <=(const fraction &f1, const fraction &f2);
friend istream &operator >>(istream &in, fraction &f);
friend ostream &operator <<(ostream &out, const fraction &f);
//
};
Trong đó:
- long nume, deno lần lượt là hai thuộc tính dùng để lưu trữ tử số và
mẫu số của phân số.
- long set_fraction(long nu=0, long de=1) là hàm thành viên dùng để
thiết lập giá trị cho phân số. Nếu de = 0 thì phân số sẽ được nhận giá
trị 0, ngược lại phân số đó sẽ nhận giá trị là


sau khi đã thực hiện tối

giản phân số.
- long get_nume() và long get_deno() lần lượt là các hàm thành viên
dùng để lấy ra giá trị của tử số và mẫu số với kết quả được trả về thông
qua lời gọi hàm.
- fraction(long nu=0, long de=1) là hàm tạo một phân số từ hai đối nu
và de, fraction(fraction const &f) là hàm tạo có chức năng sao chép
giá trị của phân số f vào giá trị của phân số đang được con trỏ this trỏ
tới.
- fraction operator -() là toán tử dùng để đổi dấu của phân số (nhân giá
trị của phân số với -1).
- operator float() và operator long() là hai toán tử dùng để chuyển đổi
giá trị của phân số sang các kiểu tương ứng là float và long.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
8
GVHD: ThS. Nguyễn Thị Xuân Đài

- fraction operator ++(), fraction operator (), fraction operator ++(int),
fraction operator (int) là các toán tử dùng để tăng giảm giá trị của
phân số đi 1.
- void operator =(const fraction &f) là toán tử dùng để gán cho đa thức
đang được con trỏ this trỏ tới giá trị của phân số f.
- Các toán tử +, -, *, / lần lượt dùng để cộng, trừ, nhân, chia hai phân số
cho nhau.
- Các toán tử +=, -=, *=, /= lần lượt dùng để cộng, trừ, nhân, chia phân
số đang được con trỏ this trỏ tới một phân số khác.
- Hai toán tử ^ và ^= lần lượt dùng để lũy thừa phân số được trỏ tới bởi

con trỏ this với đối số exp.
- friend istream &operator >>(istream &in, fraction &f) và friend
ostream &operator <<(ostream &out, const fraction &f) là hai toán tử
dùng để nhập và xuất một phân số.
3.2. Xây dựng lớp đơn thức
Lớp đơn thức được chúng tôi xây dựng trong thư viện monomial.h với nội
dung như sau:
class monomial
{
fraction coe;
long exp;
public:
monomial(long co_nume=0, long co_deno=1, long ex=0);
monomial(const fraction &co, int ex=0);
~monomial();
long set_monomial(long co_nume=0, long co_deno=1, long ex=0);
fraction get_coe() const;
long get_exp() const ;
int set_coe(const fraction &co);
int set_exp(const long &ex);
//
monomial operator -();
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
9
GVHD: ThS. Nguyễn Thị Xuân Đài


friend monomial operator +(const monomial &m, const fraction &cofm);
friend monomial operator -(const monomial &m, const fraction &cofm);
friend monomial operator *(const monomial &m1, monomial const &m2);
monomial operator ++();
monomial operator ();
monomial operator *=(const monomial &m);
monomial operator +=(const fraction &cofm);
monomial operator -=(const fraction &cofm);
monomial operator ^=(long exp);
friend monomial operator ^(const monomial &f, long exp);
void operator =(const monomial &m);
friend long operator ==(const monomial &m1, const monomial &m2);
friend long operator !=(const monomial &m1, const monomial &m2);
friend long operator >(const monomial &m1, const monomial &m2);
friend long operator <(const monomial &m1, const monomial &m2);
friend long operator >=(const monomial &m1, const monomial &m2);
friend long operator <=(const monomial &m1, const monomial &m2);
friend istream &operator >>(istream &in, monomial &e);
friend ostream &operator <<(ostream &out, const monomial &e);
//
};
Trong đó:
- fraction coe, long exp là hai thuộc tính dùng để lưu hệ số và số mũ
của đơn thức.
- monomial(long co_nume=0, long co_deno=1, long ex=0) là hàm tạo
đơn thức từ 3 đối ứng với hệ số
_
_
số mũ ex, monomial(const
fraction &co, int ex=0) là hàm tạo một đơn thức thừ một phân số có

sẵn co và số mũ ex, monomial(const monomial &m) là hàm tạo một
đơn thức từ một đơn thức có sẵn m.
- long set_monomial(long co_nume=0, long co_deno=1, long ex=0) là
hàm thành viên dùng để thiết lập giá trị cho phân số. co_nume ứng
với tử số của hệ số, co_deno ứng với mẫu số của hệ số, ex ứng với số
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
10
GVHD: ThS. Nguyễn Thị Xuân Đài

mũ của đơn thức. Khi co_deno = 0, đơn thức sẽ nhận giá trị 0, ngược
lại thì chuẩn hóa phân số và gán giá trị cha đơn thức tương ứng.
- fraction get_coe() const và long get_exp() const lần lượt là hai hàm
thành viên dùng để lấy ra giá trị hệ số và số mũ của phân số.
- int set_coe(const fraction &co) và int set_exp(const long &ex) lần
lượt là hai hàm thành viên dùng thiết lập giá trị hệ số và số mũ cho
phân số.
- void operator =(const monomial &m) là toán tử dùng để sao chép giá
trị của đơn thức m vào đơn thức đang được con trỏ this trỏ tới.
- monomial operator -() là toán tử dùng để đổi dấu đơn thức (nhân đơn
thức đang được con trỏ this trỏ tới với -1).
- Các toán tử +, -, *, / lần lượt được dùng để cộng, trừ, nhân, chia hai
đơn thức cho nhau, kết quả trả về là một đơn thức.
- Các toán tử +=, -=, *=, /= lần lượt dùng để nhân đơn thức đang được
con trỏ this trỏ tới với một đơn thức khác.
- Hai toán tử ^ và ^= được dùng để lũy thừa một đơn thức với số mũ là
exp.

- friend istream &operator >>(istream &in, monomial &e) và friend
ostream &operator <<(ostream &out, const monomial &e) lần lượt là
hai toán tử dùng để nhập vào và xuất ra đơn thức.
- Các toán tử còn lại được dùng để so sánh giá trị của hai đơn thức với
nhau một cách tương ứng.
3.3. Lưu trữ và chuẩn hóa đa thức
3.3.1. Lưu trữ
Đa thức là một tập hợp của các đơn thức, chính vì vậy chúng tôi đã sử dụng
một vector để lưu trữ cho đa thức:
vector <monomial> pol;
Trong vector, mỗi phần tử ứng với mỗi đơn thức thành viên trong đa thức.
3.3.2. Chuẩn hóa
Việc chuẩn hóa đa thức được hàm thành viên void standize() đảm nhận.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
11
GVHD: ThS. Nguyễn Thị Xuân Đài

void polynomial::standize()
{
sort(pol.begin(), pol.end(), greater<monomial>());
int i=0;
while (i<pol.size())
{
if (pol[i].get_coe()==0)
pol.erase(pol.begin()+i);
else if (i<pol.size()-1 && pol[i].get_exp()==pol[i+1].get_exp())

{
pol[i].set_coe(pol[i].get_coe()+pol[i+1].get_coe());
pol.erase(pol.begin()+i+1);
}
else
i++;
}
if (pol.size()==0)
pol.push_back(0);
}
Hàm này làm những công việc sau:
- Sắp xếp các đơn thức trong vector theo thứ tự giảm dần độ lớn của các
đơn thức.
- Nếu đơn thức nào đó có hệ số bằng 0 thì loại bỏ đơn thức này ra khỏi
vector.
- Nếu đơn thức hiện hành và đơn thức nằm ngay phía sau trong vector
có cùng số mũ thì thay thế hai đơn thức này bằng một đơn thức khác
có hệ số là tích của hai đơn thức đó, số mũ là tổng số mũ của hai đơn
thức đó.
- Sau quá trình ở trên, nếu vector rỗng (không còn một đơn thức thành
viên nào trong vector) thì chèn một đơn thức có giá trị 0 vào vector.

3.4. Xây dựng các hàm tạo cho đa thức
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
12
GVHD: ThS. Nguyễn Thị Xuân Đài


Trong lớp đa thức, chúng tôi đã xây dựng 3 hàm tạo:
polynomial(const monomial &m=0);
polynomial(const vector <monomial> &p);
polynomial(const polynomial &p);
Trong đó:
- polynomial(const monomial &m=0) là hàm tạo đa thức từ một đơn
thức m. Đa thức được tạo ra chỉ bao gồm một đơn thức m duy nhất.
- polynomial(const vector <monomial> &p) là hàm tạo đa thức từ
vector p với các phần tử là các đơn thức. Sau khi được gọi tới, hàm
này sẽ chuẩn hóa vector p rồi sau đó gán giá trị của nó cho vector pol
của đa thức.
- polynomial(const polynomial &p) là hàm dùng để sao chép giá trị của
đa thức p cho đa thức đang được trỏ tới bởi con trỏ this. Hàm này chỉ
đơn giản gán giá trị của vector pol của hai đa thức cho nhau.
3.5. Xây dựng các toán tử cho đa thức
3.5.1. Nhóm các toán tử số học
Nhóm các toán tử này bao gồm:
friend polynomial operator +(const polynomial &p1, const polynomial &p2);
friend polynomial operator -(const polynomial &p1, const polynomial &p2);
friend polynomial operator *(const polynomial &p1, const polynomial &p2);
friend polynomial operator /(const polynomial &p1, const polynomial &p2);
friend polynomial operator %(const polynomial &p1, const polynomial &p2);
Trong đó:
 Toán tử cộng
Toán tử này được định nghĩa như sau:
polynomial operator +(const polynomial &p1, const polynomial &p2)
{
vector <monomial> rt;
int i=0, j=0;

while (i<p1.size() || j<p2.size())
{
if (i==p1.size())
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
13
GVHD: ThS. Nguyễn Thị Xuân Đài

{
rt.push_back(p2[j]);
j++;
}
else if (j==p2.size())
{
rt.push_back(p1[i]);
i++;
}
else
{
if (p1[i]==p2[j])
{
rt.push_back(p1[i]+p2[j].get_coe());
i++;
j++;
}
else if (p1[i]>p2[j])
{

rt.push_back(p1[i]);
i++;
}
else
{
rt.push_back(p2[j]);
j++;
}
}
}
polynomial result(rt);
return result;
}
Đây là một toán tử hai ngôi, được khai báo là bạn của lớp đa thức, được dùng
để cộng hai đa thức p1 và p2 lại với nhau với kết quả được trả về qua lời gọi toán
tử.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
14
GVHD: ThS. Nguyễn Thị Xuân Đài

Toán tử này làm những công việc như sau:
- Khai báo một vector rt dùng để lưu trữ kết quả tạm thời, có kiểu dữ
liệu là monomial.
- Khai báo hai biến i, j có kiểu nguyên lần lượt dùng để duyệt hai đa
thức p1 và p2.
- Thực hiện công việc cộng hai đa thức với tư tưởng như sau: Nếu i có

giá trị lớn hơn chỉ số của đơn thức cuối cùng của p1 thì thêm đơn thức
có chỉ số j của p2 vào rt rồi sau đó tăng j lên 1; ngược lại, nếu j có giá
trị lớn hơn chỉ số của đơn thức cuối cùng của p2 thì thêm đơn thức có
chỉ số i của p1 vào rt rồi sau đó tăng i lên 1; ngược lại, nếu đơn thức
có chỉ số i của p1 và j của p2 có cùng số mũ thì thêm đơn thức có giá
trị là tổng của p1[i] và p2[j] vào rt rồi tăng cả i và j lên 1, ngược lại
thêm đơn thức có số mũ lớn hơn vào rt rồi sau đó tăng chỉ số lên 1
tương ứng.
- Khai báo một đa thức result dùng để lưu kết quả của phép cộng, đa
thức này được khởi tạo với đối đầu vào chính là vector rt.
- Trả về đa thức result.
 Toán tử trừ
Toán tử này được định nghĩa một cách tương tự như toán tử cộng, chỉ khác
ở phép toán đại số được thực hiện trong toán tử là trừ thay vì cộng.
 Toán tử nhân
Toán tử này được định nghĩa như sau:
polynomial operator *(const polynomial &p1, const polynomial &p2)
{
vector <monomial> rt;
for (int i=0; i<p1.size(); i++)
for (int j=0; j<p2.size(); j++)
rt.push_back(p1[i]*p2[j]);
polynomial result(rt);
return result;
}
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp

15
GVHD: ThS. Nguyễn Thị Xuân Đài

Toán tử này được khai báo là bạn của lớp, dùng để nhân hai đa thức p1 và
p2 với nhau, đa thức kết quả được trả về qua lời gọi hàm.
Toán tử này thực hiện những công việc sau:
- Khai báo vector rt có kiểu monomial dùng để lưu trữ tạm thời đa thức
kết quả.
- Dùng hai vòng for lồng nhau với hai biến i và j để duyệt hai đa thức
tương ứng p1 và p2, đẩy giá trị tích của p1[i] và p2[j] vào rt.
- Tạo một đa thức result từ vector rt, điều này nhằm mục đích chuẩn
hóa vector rt.
- Trả về đa thức result thông qua lời gọi hàm.
 Toán tử chia lấy phần nguyên
polynomial operator /(const polynomial &p1, const polynomial &p2)
{
if (p2==0)
{
cout<<"Loi chia cho 0"<<endl;
cin.get();
exit(1);
}
vector <monomial> rt;
polynomial temp=p1;
while (temp[0].get_exp()>=p2[0].get_exp())
{
rt.push_back(monomial(temp[0].get_coe()/p2[0].get_coe(), temp[0].get_exp()-
p2[0].get_exp()));
temp-=rt[rt.size()-1]*p2;
}

polynomial result(rt);
return result;
}
Khi đa thức p2 được đưa vào có giá trị 0, lỗi chia cho 0 xuất hiện và chương
trình sẽ thoát ngay tức thì.
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
16
GVHD: ThS. Nguyễn Thị Xuân Đài

Một vector rt có kiểu monomial được khai báo để lưu trữ kết quả tạm thời
của phép chia, đa thức temp được khai báo và được gán cho giá trị bằng p1 để sử
dụng làm thương số cho phép chia do giá trị của thương số này sẽ bị thay đổi khi
thực hiện phép chia mà p1 lại được khai báo là const.
Quá trình lặp được thực hiện cho tơi khi phần tử đầu tiên của temp vẫn còn
lớn hơn phần tử đầu tiên của p2 thực hiện các công việc sau: đẩy đơn thức có giá
trị là thương số của phép chia temp[0] cho p2[0]; loại bỏ phần tử đầu tiên của
temp ra khỏi temp.
Một đa thức result được tạo ra từ vector rt và sau đó trả về qua lời gọi hàm.
 Toán tử chi lấy phần dư
polynomial operator %(const polynomial &p1, const polynomial &p2)
{
if (p2==0)
{
cout<<"Loi chia cho 0"<<endl;
cin.get();
exit(1);

}
polynomial quotient=p1/p2, remainder=p1-quotient*p2;
return remainder;
}
Cũng tương tự như toán tử chia lấy phần nguyên, toán tử này sẽ thoát chương
trình ngay tức thì nếu p2 có giá trị 0 và lỗi chia cho 0 sảy ra.
Một đa thức quotient được khai báo nhận giá trị phần nguyên trong phép chi
lấy phần nguyên p1 cho p2. Đa thức remainder được khai báo nhận giá trị p1-
quotient*p2, giá trị của đa thức này cũng chính là kết quả trả về bởi toán tử.
3.5.2. Toán tử gán
bool polynomial::operator =(const polynomial &p)
{
pol=p.pol;
}
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
17
GVHD: ThS. Nguyễn Thị Xuân Đài

Do kiểu dữ liệu vector trong C++ đã hỗ trợ sẵn phép gán nên khi gán giá trị
của đa thức p cho đa thức đang được con trỏ this trỏ tới, chúng ta chỉ cần gán giá
trị của hai vector pol của hai đa thức này cho nhau.
3.5.3. Nhóm các toán tử gán phức hợp
Các toán tử gán phức hợp bao gồm:
polynomial polynomial::operator +=(const polynomial &p)
{
polynomial result((*this)+p);

(*this)=result;
return result;
}
polynomial polynomial::operator -=(const polynomial &p)
{
polynomial result((*this)-p);
(*this)=result;
return result;
}
polynomial polynomial::operator *=(const polynomial &p)
{
polynomial result((*this)*p);
(*this)=result;
return result;
}
polynomial polynomial::operator /=(const polynomial &p)
{
polynomial result((*this)/p);
(*this)=result;
return result;
}
polynomial polynomial::operator %=(const polynomial &p)
{
polynomial result((*this)%p);
(*this)=result;
return result;
Cài đặt lớp đa thức




SVTH: Bùi Hữu Giáp
18
GVHD: ThS. Nguyễn Thị Xuân Đài

}
Các toán tử này đều sử dụng các toán tử số học tương ứng để thực hiện phép
toán. Công việc mà các toán tử này thực hiện bao gồm: khai báo một đa thức
result dùng để lưu lại kết quả trung gian của việc thực hiện các phép toán số học
tương ứng của đối tượng đang được con trỏ this trỏ tới cho đa thức p; gán giá trị
của result cho đối tượng đang được con trỏ this trỏ tới; trả về giá trị của result.
3.5.4. Xây dựng toán tử vào và ra
istream &operator >>(istream &in, polynomial &p)
{
p.pol.clear();
monomial m;
while (1)
{
cout<<"Element "<<p.pol.size()+1<<" (<coe> <deno> <exp>): ";
cin>>m;
p.pol.push_back(m);
cout<<"Press Enter to continue, press another key to stop!"<<endl;
char ch=getch();
if (ch!=13)
break;
}
p.standize();
return in;
}
ostream &operator <<(ostream &out, const polynomial &p)
{

int p_size=p.size();
for (int i=0; i<p_size; i++)
{
if (i>0 && p[i].get_coe()>=0)
cout<<"+";
cout<<p[i];
}
return out;
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
19
GVHD: ThS. Nguyễn Thị Xuân Đài

}
Toán tử dòng vào >> dùng để đọc vào một đa thức từ bàn phím. Toán tử này
sẽ yêu cầu người dùng nhập vào từng đơn thức thành viên, các đơn thức này sẽ
được đẩy trực tiếp vào vector pol, sau khi quá trình nhập hoàn thành, hàm
standize() sẽ được gọi tới để chuẩn hóa vector này theo đúng định dạng của đa
thức.
Toán tử dòng ra << dùng để xuất đa thức ra màn hình theo đúng cấu trúc
toán học của một đa thức.
3.5.5. Nhóm các toán tử quan hệ
friend bool operator ==(const polynomial &p1, const polynomial &p2);
friend bool operator ==(const polynomial &p, const monomial &m);
friend bool operator !=(const polynomial &p1, const polynomial &p2);
friend bool operator >(const polynomial &p1, const polynomial &p2);
friend bool operator <(const polynomial &p1, const polynomial &p2);

friend bool operator >=(const polynomial &p1, const polynomial &p2);
friend bool operator <=(const polynomial &p1, const polynomial &p2);
Nhóm các toán tử này được sử dụng để thực hiện các phép toán quan hệ giữa
hai đa thức bằng cách so sánh lần lượt các đơn thức thành viên của hai đa thức đó
theo thứ tự từ trái qua phải.
3.5.6. Nhóm các toán tử khác
 Toán tử chỉ số
monomial &operator [] (int i);
monomial operator [] (int i) const;
Toán tử này được làm chồng để thực hiện cả hai công việc đơn thuần lấy ra
giá trị của phần tử và thay đổi giá trị của phần tử đó.
 Toán tử đảo dấu đa thức
polynomial operator -();
Toán tử này được sử dụng để đổi dấu đa thức. Công việc của đa thức này
thực hiện tương đương với việc nhân đa thức đó với -1. Để làm được công việc
này, toán tử sẽ đổi dấu tất cả các đơn thức thành viên của đa thức đó.
3.6. Hàm tính đạo hàm đa thức
Cài đặt lớp đa thức



SVTH: Bùi Hữu Giáp
20
GVHD: ThS. Nguyễn Thị Xuân Đài

polynomial polynomial::derivative() const
{
vector <monomial> rt;
for (int i=0; i<size(); i++)
rt.push_back(monomial((*this)[i].get_coe()*(*this)[i].get_exp(),

(*this)[i].get_exp()-1));
polynomial result(rt);
return result;
}
polynomial derivative(polynomial &p)
{
polynomial result(p.derivative());
p=result;
return result;
}
Trong đó:
- polynomial derivative() const là hàm thuộc lớp, chỉ trả về một đa thức
có giá trị là đạo hàm của đa thức đang được trỏ tới bởi con trỏ this mà
không làm thay đổi giá trị của nó. Vector rt có kiểu monomial được
sử dụng để lưu lại kết quả tạm thời của phép đạo hàm. Một vòng for
được sử dụng để duyệt đa thức, giá trị đạo hàm của các đơn thức thành
viên được đẩy vào trong rt. Một đa thức result được tạo ra từ vector
rt, đây chính là kết quả trả về của hàm.
- friend polynomial derivative(polynomial &p) được khai báo là bạn
của lớp. Khi được gọi tới, hàm này sẽ gán giá trị đạo hàm của đa thức
p cho p, đồng thời trả về giá trị này qua lời gọi hàm. Một đa thức result
được tạo ra từ đạo hàm của đa thức p. Giá trị của result được gán cho
p và sau đó trả về result qua lời gọi hàm.
3.7. Hàm tính nguyên hàm của đa thức
polynomial polynomial::antiderivative() const
{
vector <monomial> rt;

×