Đề HK1 2022-2023
Một tổ chức chuyên trưng bày, mua bán các sản phẩm liên quan đến nghệ thuật đang muốn xây dựng một ứng dụng để quản lý các hoá đơn khi bán các sản phẩm. Mỗi lần bán sản phẩm thành công, cửa hàng sẽ lưu trữ các hoá đơn chứa thông tin sản phẩm liên quan. Mỗi hoá đơn sẽ có thông tin: mã hoá đơn, thông tin khách hàng, ngày lập hoá đơn, danh sách sản phẩm, tổng giá (tổng giá trị các sản phẩm trong đơn hàng). Tổ chức này hiện tại chỉ kinh doanh 2 loại sản phẩm: tranh ảnh và CD âm nhạc (tương lai có thể thay đổi sản phẩm kinh doanh khác). Mỗi sản phẩm sẽ có thông tin chung cần quản trị: mã số, tiêu đề, giá bán. Ngoài thông tin chung, các sản phẩm tranh ảnh cần thêm thông tin kích thước của bức tranh (chiều rộng, chiều cao), tên hoạ sĩ. Sản phẩm CD âm nhạc sẽ có thêm tên ca sĩ, tên đơn vị sản xuất. Mỗi khách hàng sẽ được lưu trữ các thông tin: mã khách hàng, tên khách hàng, số điện thoại.
Áp dụng tư tưởng lập trình hướng đối tượng (có sử dụng kế thừa, đa hình), anh/chị hãy:
- (1.5 điểm) Thiết kế và vẽ sơ đồ lớp cho ứng dụng theo bài toán được mô tả
- Cài đặt chi tiết theo sơ đồ lớp đã thiết kế và cũng như thành phần cần thiết khác để xây dựng chương trình thực hiện các tính năng sau:
- (1.5 điểm) Nhập và xuất danh sách các hoá đơn bán hàng
- (1 điểm) Tính tổng thu nhập của cửa hàng
- (1 điểm) Tìm các khách hàng mua nhiều nhất ở cửa hàng (dựa vào tổng giá trị các hoá đơn khách hàng đã mua).
Lưu ý: Các thông tin trong đề thi chỉ mang tính chất giả sử, KHÔNG nhất thiết phải đúng hoặc khớp với các thông tin hiện tại trong thế giới thực. Sinh viên cần bám sát các mô tả trong đề thi và vận dụng kiến thức về lập trình hướng đối tượng để làm bài theo yêu cầu.
Phân tích đề
Bước 1: Xác định các lớp
Vừa đọc đề ta thấy yêu cầu là phải quản lí các hóa đơn nên tất nhiên là phải có lớp Hóa đơn và Danh sách hóa đơn. Bên trong lớp Hóa đơn sẽ có thêm lớp Người để biểu diễn thông tin khách hàng, lớp Ngày để mô tả ngày lập hóa đơn, và lớp Sản phẩm. Có 2 lớp con kế thừa từ lớp Sản phẩm là Tranh ảnh và CD âm nhạc.
Bước 2: Thiết kế thuộc tính
Lớp Danh sách hóa đơn sẽ là một mảng các Hóa đơn (vì chỉ có 1 loại hóa đơn nên không cần dùng con trỏ). Lớp Hóa đơn có 5 thông tin cần thể hiện, trong đó danh sách sản phẩm được biểu diễn bằng 1 mảng các con trỏ thuộc lớp Sản phẩm (vì có nhiều loại sản phẩm nên sử dụng con trỏ để áp dụng tính đa hình). Đề này đã chỉ rõ luôn cho ta biết các thuộc tính nào là chung, riêng của lớp Sản phẩm, Tranh ảnh và CD âm nhạc.
Bước 3: Thiết kế phương thức
- Các phương thức nhập, xuất cho các lớp. Phương thức nhập, xuất ở lớp Sản phẩm là phương thức ảo.
- Phương thức tính tổng giá các sản phẩm ở lớp Hóa đơn, tính tổng giá các hóa đơn ở lớp Danh sách.
- Phương thức tìm max ở lớp danh sách hóa đơn.
Ngoài ra cần định nghĩa thêm các phương thức truy vấn phù hợp.
Sơ đồ thiết kế lớp
Lời giải tham khảo
#include<iostream>
#include<string>
#include<map>
using namespace std;
class Nguoi {
private:
int maKhach;
string ten;
string SDT;
public:
void Nhap();
void Xuat();
int getMaKhach();
};
class Ngay {
private:
int ngay;
int thang;
int nam;
public:
void Nhap();
void Xuat();
};
class SanPham {
protected:
string maSo;
string tieuDe;
long gia;
public:
virtual void Nhap();
virtual void Xuat();
long getGia();
};
class Tranh :public SanPham {
protected:
int rong;
int cao;
string hoaSi;
public:
void Nhap();
void Xuat();
};
class CD :public SanPham {
protected:
string caSi;
string donVi;
public:
void Nhap();
void Xuat();
};
class HoaDon {
protected:
string maDon;
Nguoi khach;
Ngay ngayCap;
int n;
SanPham* hd[100];
long tongGia;
public:
void Nhap();
void Xuat();
long getTongGia();
Nguoi getKhach();
};
class DanhSach {
protected:
int size;
HoaDon ds[100];
public:
void Nhap();
void Xuat();
long ThuNhap();
void TimKiemMax();
};
void Ngay::Nhap() {
cout << "Nhap ngay: ";
cin >> ngay;
cout << "Nhap thang: ";
cin >> thang;
cout << "Nhap nam: ";
cin >> nam;
}
void Ngay::Xuat() {
cout << ngay << "/" << thang << "/" << nam << endl;
}
void Nguoi::Nhap() {
cout << "Nhap ma khach hang: ";
cin >> maKhach;
cout << "Nhap ho ten: ";
cin >> ten;
cout << "Nhap so dien thoai: ";
cin >> SDT;
}
void Nguoi::Xuat() {
cout << "Ma khach hang: " << maKhach << endl;
cout << "Ho ten: " << ten << endl;
cout << "So dien thoai: " << SDT << endl;
}
int Nguoi::getMaKhach() {
return maKhach;
}
void SanPham::Nhap() {
cout << "Nhap ma so: ";
cin >> maSo;
cout << "Nhap tieu de: ";
cin >> tieuDe;
cout << "Nhap gia ban: ";
cin >> gia;
}
void SanPham::Xuat() {
cout << "Ma so: " << maSo << endl;
cout << "Tieu de: " << tieuDe << endl;
cout << "Gia ban: " << gia << endl;
}
long SanPham::getGia() {
return gia;
}
void Tranh::Nhap() {
SanPham::Nhap();
cout << "Nhap kich thuoc: " << endl;
cout << "Nhap chieu rong: ";
cin >> rong;
cout << "Nhap chieu cao: ";
cin >> cao;
cout << "Nhap ten hoa si: ";
cin >> hoaSi;
}
void Tranh::Xuat() {
SanPham::Xuat();
cout << "Chieu rong: " << rong << endl;
cout << "Chieu cao: " << cao << endl;
cout << "Ten hoa si: " << hoaSi << endl;
}
void CD::Nhap() {
SanPham::Nhap();
cout << "Nhap ten ca si: ";
cin >> caSi;
cout << "Nhap don vi san xuat: ";
cin >> donVi;
}
void CD::Xuat() {
SanPham::Xuat();
cout << "Ten ca si: " << caSi << endl;
cout << "Don vi san xuat: " << donVi << endl;
}
void HoaDon::Nhap() {
cout << "Nhap ma hoa don: ";
cin >> maDon;
cout << "Nhap thong tin khach hang: " << endl;
khach.Nhap();
cout << "Nhap ngay cap: " << endl;
ngayCap.Nhap();
cout << "Nhap so luong san pham: ";
cin >> n;
for (int i = 0; i < n; i++) {
cout << "Nhap san pham thu " << i + 1 << endl;
int loai;
cout << "Nhap loai (0. Tranh anh, 1. CD): ";
cin >> loai;
if (loai == 0) {
hd[i] = new Tranh();
}
else {
hd[i] = new CD();
}
hd[i]->Nhap();
}
}
void HoaDon::Xuat() {
cout << "Ma hoa don: " << maDon << endl;
cout << "Ngay cap: ";
ngayCap.Xuat();
cout << "Thong tin khach hang: " << endl;
cout << "Tong gia tien: " << getTongGia() << endl;
khach.Xuat();
for (int i = 0; i < n; i++) {
cout << "San pham thu " << i + 1 << endl;
hd[i]->Xuat();
}
}
long HoaDon::getTongGia() {
tongGia = 0;
for (int i = 0; i < n; i++) {
tongGia += hd[i]->getGia();
}
return tongGia;
}
Nguoi HoaDon::getKhach() {
return khach;
}
void DanhSach::Nhap() {
cout << "Nhap so luong hoa don: ";
cin >> size;
for (int i = 0; i < size; i++) {
cout << "Nhap hoa don thu " << i + 1 << endl;
ds[i].Nhap();
}
}
void DanhSach::Xuat() {
for (int i = 0; i < size; i++) {
cout << "Hoa don thu " << i + 1 << endl;
ds[i].Xuat();
}
}
long DanhSach::ThuNhap() {
int s = 0;
for (int i = 0; i < size; i++) {
s += ds[i].getTongGia();
}
return s;
}
void DanhSach::TimKiemMax() {
map<int, long> mp;
for (int i = 0; i < size; ++i) {
int id = ds[i].getKhach().getMaKhach();
mp[id] += ds[i].getTongGia();
}
long max = 0;
for (const auto& pair : mp) {
if (pair.second > max) {
max = pair.second;
}
}
cout << "ID cac khach mua nhieu nhat: \n";
for (const auto& pair : mp) {
if (pair.second == max) {
cout << pair.first << endl;
}
}
}
int main() {
DanhSach l;
l.Nhap();
l.Xuat();
cout << "Tong thu nhap: " << l.ThuNhap() << endl;
l.TimKiemMax();
}