Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
55 kB
71
Indexable
Never
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <math.h>
#include <random>
#include <ctime>
#include <iomanip>
#include <list>    // Danh sach lien ket don va kep
#include <bitset>  // Bit set (cu coi la mot bool array)
#include <fstream> // File
#include <sstream>
#include <set>

using namespace std;

// constants
const int MAX_DMS = 10;          // max danh muc sach cua moi dau sach
const int MAX_SACH_MUON = 3;     // moi lan muon toi da 3 sach
const int MAX_SACH = 100;        // max sach cua moi dau sach
const int MAX_THE_DOCGIA = 1000; // max the doc gia
long long danh_so_the_muon = 0;  // dung de luu the muon sach
const int MAX_DAU_SACH = 100000; // max dau sach
const int MAX_NGAY_MUON = 7;     // max ngay muon

bitset<MAX_THE_DOCGIA * 10> kiem_tra_ma_the; // check xem ma the da ton tai hay chua
bitset<MAX_DAU_SACH * 10> kiem_tra_ISBN;
// cac ham random
string random_ISBN()
{
    default_random_engine engine(static_cast<long long int>(time(0)));
    uniform_int_distribution<long long int> randomInt(1000000000000, 9999999999999);
    long long ISBN = randomInt(engine);
    string ISBN_str = to_string(ISBN);
    return ISBN_str;
}
int random_ma_the()
{
    int ma_the;
    do
    {
        ma_the = rand() % (MAX_THE_DOCGIA * 10 - 1) + 1;
    } while (kiem_tra_ma_the[ma_the]);
    kiem_tra_ma_the[ma_the] = 1;
    return ma_the;
}
/* Phan khai bao cau truc du lieu */
struct Dau_sach;
struct Sach;
struct The_doc_gia;
struct Phieu_muon_tra_sach;
struct Ngay_thang;
/* hien thuc struct */
struct Dau_sach
{
    string ISBN; // ma ISBN gom 13 chu so
    string ten_sach;
    int so_trang;
    string tac_gia;
    int nam_xuat_ban;
    string the_loai;
    int so_lan_muon;
    list<Sach*> danh_muc_sach;

    ~Dau_sach()
    {
        for (auto& i : danh_muc_sach)
        {
            delete i;
        }
    }
};
struct Sach
{
    string ma_sach;
    int trang_thai; // 0 muon duoc, 1 da muon, 2 da hu
    string vi_tri;
    ~Sach()
    {
    }
};

struct The_doc_gia
{
    int ma_the;
    string ho_ten;
    string gioi_tinh;
    Phieu_muon_tra_sach* sach_dang_muon[MAX_SACH_MUON];
    int so_sach_dang_muon;

    int trang_thai; // 0: khoa the. 1: mo the.
    ~The_doc_gia()
    {
        for (int i = 0; i < so_sach_dang_muon; i++)
        {
            delete sach_dang_muon[i];
        }
    }
};
struct Phieu_muon_tra_sach
{
    string ma_phieu;
    Sach* sach;
    Ngay_thang* ngay_muon;
    Ngay_thang* ngay_tra;
    The_doc_gia* the_doc_gia;
    int trang_thai; // 0: chua tra. 1: da tra. 2: lam mat
    ~Phieu_muon_tra_sach()
    {
        delete ngay_muon;
        delete ngay_tra;
    }
};
struct Ngay_thang
{
    int ngay;
    int thang;
    int nam;
    ~Ngay_thang()
    {
    }
};
// ham tinh do lech giua 2 ngay https://www.geeksforgeeks.org/find-number-of-days-between-two-given-dates/
const int monthDays[12] = { 31, 28, 31, 30, 31, 30,
                           31, 31, 30, 31, 30, 31 };

// This function counts number of
// leap years before the given date
int countLeapYears(Ngay_thang* d)
{
    int years = d->nam;

    // Check if the current year needs to be
    //  considered for the count of leap years
    // or not
    if (d->thang <= 2)
        years--;

    // An year is a leap year if it
    // is a multiple of 4,
    // multiple of 400 and not a
    // multiple of 100.
    return years / 4 - years / 100 + years / 400;
}

// This function returns number of
// days between two given dates
int getDifferenceDay(Ngay_thang* dt1, Ngay_thang* dt2)
{
    // COUNT TOTAL NUMBER OF DAYS
    // BEFORE FIRST DATE 'dt1'

    // initialize count using years and day
    long int n1 = dt1->nam * 365 + dt1->ngay;

    // Add days for months in given date
    for (int i = 0; i < dt1->thang - 1; i++)
        n1 += monthDays[i];

    // Since every leap year is of 366 days,
    // Add a day for every leap year
    n1 += countLeapYears(dt1);

    // SIMILARLY, COUNT TOTAL NUMBER OF
    // DAYS BEFORE 'dt2'

    long int n2 = dt2->nam * 365 + dt2->ngay;
    for (int i = 0; i < dt2->thang - 1; i++)
        n2 += monthDays[i];
    n2 += countLeapYears(dt2);

    // return difference between two counts
    return (n2 - n1);
}
// chuan hoa chuoi
string chuan_hoa_chuoi(string s)
{
    // xoa ky tu trong dau
    s.erase(0, s.find_first_not_of(" "));
    s.erase(s.find_last_not_of(" ") + 1);
    // xoa 2 ky tu trong o giua
    while (s.find("  ") != string::npos)
    {
        s.erase(s.find("  "), 1);
    }
    return s;
    // chuan hoa chuoi
}

string viet_in_hoa(string s)
{
    string s1 = "";
    for (int i = 0; i < s.length(); i++)
    {
        if (s[i] == ' ')
        {
            s1 += ' ';
        }
        else
        {
            s1 += toupper(s[i]);
        }
    }
    return s1;
}

string toString(Ngay_thang* d)
{
    stringstream ss;
    ss << d->ngay << "/" << d->thang << "/" << d->nam;
    return ss.str();
}
// * binaray search tree (cay nhi phan tim kiem) */

struct Node_tree
{
    The_doc_gia* data;
    Node_tree* left;
    Node_tree* right;
    ~Node_tree()
    {
        delete data;
        if (left != NULL)
        {
            delete left;
        }
        if (right != NULL)
        {
            delete right;
        }
    }
};
struct BST
{
    Node_tree* root;
    int size;
};
void init_BST(BST* bst)
{
    bst->root = NULL;
    bst->size = 0;
}
void add_BST(BST* bst, The_doc_gia* data)
{
    Node_tree* p = bst->root;
    Node_tree* parent = NULL;
    while (p != NULL)
    {
        parent = p;
        if (data->ma_the < p->data->ma_the)
            p = p->left;
        else
            p = p->right;
    }
    Node_tree* new_node = new Node_tree;
    new_node->data = data;
    new_node->left = NULL;
    new_node->right = NULL;
    if (parent == NULL)
        bst->root = new_node;
    else if (data->ma_the < parent->data->ma_the)
        parent->left = new_node;
    else
        parent->right = new_node;
    bst->size++;
}
void remove_BST(BST* bst, int ma_the)
{
    Node_tree* p = bst->root;
    Node_tree* parent = NULL;
    while (p != NULL)
    {
        if (p->data->ma_the == ma_the)
            break;
        else
        {
            parent = p;
            if (ma_the < p->data->ma_the)
                p = p->left;
            else
                p = p->right;
        }
    }
    if (p == NULL)
        return;
    if (p->left == NULL)
    {
        if (parent == NULL)
            bst->root = p->right;
        else if (p->data->ma_the < parent->data->ma_the)
            parent->left = p->right;
        else
            parent->right = p->right;
    }
    else if (p->right == NULL)
    {
        if (parent == NULL)
            bst->root = p->left;
        else if (p->data->ma_the < parent->data->ma_the)
            parent->left = p->left;
        else
            parent->right = p->left;
    }
    else
    {
        Node_tree* q = p->right;
        Node_tree* parent_q = p;
        while (q->left != NULL)
        {
            parent_q = q;
            q = q->left;
        }
        p->data = q->data;
        if (parent_q == p)
            parent_q->right = q->right;
        else
            parent_q->left = q->right;
    }
    delete p;
    bst->size--;
}
void in_order_BST_recursive(Node_tree* root, vector<The_doc_gia*>& v)
{
    if (root == NULL)
        return;
    in_order_BST_recursive(root->left, v);
    v.push_back(root->data);
    in_order_BST_recursive(root->right, v);
}

vector<The_doc_gia*> in_order_BST(BST* bst)
{
    vector<The_doc_gia*> v(0);
    if (bst->root == NULL)
        return v;
    in_order_BST_recursive(bst->root, v);
    return v;
}
The_doc_gia* search_BST(BST* bst, int ma_the)
{
    Node_tree* p = bst->root;
    while (p != NULL)
    {
        if (p->data->ma_the == ma_the)
            return p->data;
        else if (ma_the < p->data->ma_the)
            p = p->left;
        else
            p = p->right;
    }
    return NULL;
}

void xoa_cay_BST(Node_tree* root)
{
    if (root == NULL)
        return;
    xoa_cay_BST(root->left);
    xoa_cay_BST(root->right);
    delete root;
}

// * Phan bien toan cuc (global variable)

Dau_sach* danh_sach_dau_sach[MAX_SACH];
int so_luong_dau_sach;

list<Phieu_muon_tra_sach*> danh_sach_phieu_muon_tra_sach;

BST* danh_sach_the_doc_gia;

set<string> danh_sach_the_loai_sach;

Ngay_thang* ngay_thang_hien_tai;
/* Phan ham */
// * lien quan de tao struct (constructor)
Dau_sach* tao_dau_sach(string ISBN, string ten_sach, int so_trang, string tac_gia, int nam_xuat_ban, string the_loai);
Sach* tao_sach(string ma_sach, int trang_thai, string vi_tri);
The_doc_gia* tao_the_doc_gia(int ma_the, string ho_ten, string gioi_tinh);
Phieu_muon_tra_sach* tao_phieu_muon_tra_sach(Sach* sach, Ngay_thang* ngay_muon, Ngay_thang* ngay_tra, The_doc_gia* the_doc_gia, string, int);
Ngay_thang* tao_ngay_thang(int ngay, int thang, int nam);

// ham nguoi dung nhap
void nhap_dau_sach(/*Dau_sach *dau_sach*/);
void nhap_sach(/*Sach *sach*/);
// void nhap_the_doc_gia(The_doc_gia *the_doc_gia);
void nhap_phieu_muon_tra_sach(Phieu_muon_tra_sach* phieu_muon_tra_sach);
void nhap_ngay_thang(Ngay_thang* ngay_thang);

// ham in thong tin
void in_dau_sach();
void in_the_loai();
void in_sach();

// ham tim
void tim_sach();

void hien_main_menu();
void hien_menu_doc_gia();
void hien_menu_sach();
void hien_dau_sach();
void hien_menu_muon_tra();
void hien_menu_thong_ke();
// * cac ham trong doc gia

void nhap_the_doc_gia();
void in_the_doc_gia();
void in_the_doc_gia_theo_ma_the();
void in_the_doc_gia_theo_ho_ten();
void xoa_the_doc_gia();
void xin_chao_doc_giai(The_doc_gia* the_doc_gia);
// * cac ham trong muon tra

void muon_sach();
bool kiem_tra_dieu_kien_muon_sach(The_doc_gia*);
void tra_sach();
void in_sach_dang_muon();
void in_phieu_muon_tra_sach();
void in_danh_sach_the_thu_tu_tre_han();
void thong_ke_10_sach_cao_nhat();
// cac ham trong thong ke

// cac ham phu (search, sort, trim, Ngay_thang ...)
// luu file, doc file
void luu_file_dau_sach(); // luu luôn sách
void luu_file_the_doc_gia();
void luu_file_phieu_muon_tra_sach();
void luu_ngay_thang();

void doc_file_ngay_thang();
void doc_file_dau_sach();
void doc_file_the_doc_gia();
void doc_file_phieu_muon_tra_sach();

// cac ham find
vector<Dau_sach*> tim_sach_theo_ten(string ten_sach);
Sach* tim_sach_theo_ma_sach(string);
Phieu_muon_tra_sach* tim_phieu_muon_tra_theo_ma_phieu(string);
The_doc_gia* tim_the_doc_gia_theo_ma_the(int ma_the);
Dau_sach* tim_dau_sach_theo_ISBN(string);

void khoi_tao()
{
    so_luong_dau_sach = 0;
    ngay_thang_hien_tai = tao_ngay_thang(1,1, 2022);
    danh_sach_the_doc_gia = new BST;
    danh_sach_the_doc_gia->root = NULL;
    danh_sach_the_doc_gia->size = 0;

    doc_file_ngay_thang();
    doc_file_dau_sach();
    doc_file_phieu_muon_tra_sach();
    doc_file_the_doc_gia();
}
void don_rac() // gabbage collector
{
    luu_file_dau_sach();
    luu_file_the_doc_gia();
    luu_file_phieu_muon_tra_sach();
    luu_ngay_thang();

    // delete danh_sach_dau_sach;
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        delete danh_sach_dau_sach[i];
    }
    xoa_cay_BST(danh_sach_the_doc_gia->root);
    delete danh_sach_the_doc_gia;
    // delete phieu muon tra sach
    for (list<Phieu_muon_tra_sach*>::iterator it = danh_sach_phieu_muon_tra_sach.begin(); it != danh_sach_phieu_muon_tra_sach.end(); it++)
    {
        if (*it != NULL)
        {
            delete* it;
        }
    }
}
void cap_nhap_ngay_thang();

// Ham in
// void in_dau_sach(Dau_sach *dau_sach)
// {
//     cout << left << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
// }

int main()
{
    srand(time(NULL));
    khoi_tao();

    hien_main_menu();

    don_rac();
    return 0;
}

// menu
void hien_main_menu()
{
    int choice;
    do
    {
        system("cls");
        cout << "\n==========================" << endl;
        cout << "Hom nay la ngay: " << toString(ngay_thang_hien_tai) << endl
            << endl;
        cout << "\t============== QUAN LY THU VIEN =============" << endl;
        cout << "\t\t\t1. Doc gia\n";
        cout << "\t\t\t2. Sach\n";
        cout << "\t\t\t3. Muon tra\n";
        cout << "\t\t\t4. Thong ke\n";
        cout << "\t\t\t5. Cap nhap ngay thang\n";
        cout << "\t\t\t0. Thoat\n";
        cout << "\t\t============== END =============" << endl;
        cout << "Nhap lua chon: ";
        cin >> choice;
        switch (choice)
        {
        case 1:
            hien_menu_doc_gia();
            break;
        case 2:
            hien_menu_sach();
            break;
        case 3:
            hien_menu_muon_tra();
            break;
        case 4:
            hien_menu_thong_ke();
            break;
        case 5:
            cap_nhap_ngay_thang();
            break;
        case 0:
            return;
            break;
        default:
            cin.clear();
            cout << "Lua chon khong hop le!\n";
            break;
        }
    } while (choice != 0);
}
void hien_menu_doc_gia()
{
    /*int luachon;
    while (true)
    {
        system("cls");
        cout << "\n==========================" << endl;
        cout << "Hom nay la ngay: " << toString(ngay_thang_hien_tai) << endl
            << endl;
        cout << "1. Nhap the doc gia\n";
        cout << "2. In the doc gia\n";
        cout << "3. Xoa the doc gia\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        //luachon = 0;
        cin >> luachon;
        if (luachon == 1)
        {
            nhap_the_doc_gia();
        }
        else if (luachon == 2)
        {
            in_the_doc_gia();
            system("pause");
        }
        else if (luachon == 3)
        {
            xoa_the_doc_gia();
        }
        else if (luachon == 0)
        {
            return;
        }
        else
        {
            cout << "Lua chon khong hop le " << endl;
            system("pause");
        }
    }*/
    int choice;
    do
    {
      
        cout << "\n==========================" << endl;
        cout << "Hom nay la ngay: " << toString(ngay_thang_hien_tai) << endl
            << endl;
        cout << "1. Nhap the doc gia\n";
        cout << "2. In the doc gia\n";
        cout << "3. Xoa the doc gia\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        choice = 0;
        cin >> choice;
        switch (choice)
        {
        case 1:
            nhap_the_doc_gia();
            break;
        case 2:
            in_the_doc_gia();
            system("pause");
            break;
        case 3:
            xoa_the_doc_gia();
            break;
        case 0:
            return;
            break;
        default:
            cout << "Lua chon khong hop le!\n";
            
            cin.clear();
            
            cin.ignore();
            
            break;
        }
    } while (choice != 0);
}
void hien_menu_sach()
{
    int choice;
    do
    {
       
        cout << "\n==========================" << endl;
        cout << "Hom nay la ngay: " << toString(ngay_thang_hien_tai) << endl
            << endl;
        cout << "1. Cap nhat dau sach\n";
        cout << "2. Hien thi cac dau sach\n";
        cout << "3. Cap nhat danh muc sach\n";
        cout << "4. Hien thi danh muc sach\n";
        cout << "5. Tim thong tin sach\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        cin >> choice;
        switch (choice)
        {
        case 0:
            return;
            break;
        case 1:
            nhap_dau_sach();
            break;
        case 2:
            hien_dau_sach();
            break;
        case 3:
            nhap_sach();
            break;
        case 4:
            in_sach();
            break;
        case 5:
            tim_sach();
            break;
        default:
            cout << "Lua chon khong hop le!\n";
            break;
        }
    } while (choice != 0);
}
void hien_dau_sach()
{
    int choice;
    do
    {
       
        cout << "\n==========================" << endl;
        cout << "Hom nay la ngay: " << toString(ngay_thang_hien_tai) << endl
            << endl;
        cout << "1. Hien thi tat ca dau sach\n";
        cout << "2. Hien thi cac dau sach theo the loai\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        cin >> choice;
        switch (choice)
        {
        case 0:
            return;
            break;
        case 1:
            in_dau_sach();
            break;
        case 2:
            in_the_loai();
            break;
        default:
            cout << "Lua chon khong hop le!\n";
            break;
        }
    } while (choice != 0);
}
void hien_menu_muon_tra()
{
    int choice;
    do
    {
        
        cout << "\n==========================" << endl;
        cout << "1. Muon sach\n";
        cout << "2. Tra sach\n";
        cout << "3. In phieu muon tra\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        cin >> choice;
        switch (choice)
        {
        case 1:
            muon_sach();
            break;
        case 2:
            tra_sach();
            break;
        case 3:
            in_sach_dang_muon();
            break;
        case 0:
            return;
            break;
        default:
            cout << "Lua chon khong hop le!\n";
            break;
        }
    } while (choice != 0);
}
void hien_menu_thong_ke()
{
    int choice;
    do
    {
       
        cout << "\n==========================" << endl;
        cout << "1. Thong ke doc gia muon qua han.\n";
        cout << "2. Top 10 sach duoc muon nhieu nhat.\n";
        cout << "0. Thoat\n";
        cout << "\n==========================" << endl;
        cout << "Nhap lua chon: ";
        cin >> choice;
        switch (choice)
        {
        case 1:
            in_danh_sach_the_thu_tu_tre_han();
            break;
        case 2:
            thong_ke_10_sach_cao_nhat();
            break;
        case 0:
            return;
            break;
        default:
            cout << "Lua chon khong hop le!\n";
            break;
        }
    } while (choice != 0);
}
void cap_nhap_ngay_thang()
{
    //    the next day
    ngay_thang_hien_tai->ngay++;
    if (ngay_thang_hien_tai->ngay > monthDays[ngay_thang_hien_tai->thang - 1])
    {
        ngay_thang_hien_tai->ngay = 1;
        ngay_thang_hien_tai->thang++;
    }
    if (ngay_thang_hien_tai->thang > 12)
    {
        ngay_thang_hien_tai->thang = 1;
        ngay_thang_hien_tai->nam++;
    }
    // cout << "Ngay thang hien tai: " << toString(ngay_thang_hien_tai) << endl;
}

The_doc_gia* tao_the_doc_gia(int ma_the, string ho_ten, string gioi_tinh)
{
    The_doc_gia* the_doc_gia = new The_doc_gia;
    the_doc_gia->ma_the = ma_the;
    the_doc_gia->ho_ten = viet_in_hoa(chuan_hoa_chuoi(ho_ten));
    the_doc_gia->gioi_tinh = viet_in_hoa(chuan_hoa_chuoi(gioi_tinh));

    the_doc_gia->trang_thai = 1; 

    for (int i = 0; i < MAX_SACH_MUON; i++)
        the_doc_gia->sach_dang_muon[i] = NULL;
    the_doc_gia->so_sach_dang_muon = 0;
    return the_doc_gia;
}
Phieu_muon_tra_sach* tao_phieu_muon_tra_sach(Sach* sach,
    Ngay_thang* ngay_muon,
    Ngay_thang* ngay_tra,
    The_doc_gia* the_doc_gia,
    string ma_phieu = "", int trang_thai = 0)
{
    Phieu_muon_tra_sach* phieu = new Phieu_muon_tra_sach;

    if (ma_phieu == "")
    {
        phieu->ma_phieu = to_string(danh_so_the_muon);
        danh_so_the_muon++;
    }
    else
        phieu->ma_phieu = ma_phieu;
    // cung la de luu lai ma phieu muon tra,
    // neu dung so luong phieu muon tra thi se
    // bi trung vi khi tra sach se xoa phieu muon tra

    phieu->sach = sach;
    phieu->ngay_muon = ngay_muon;
    if (ngay_tra != NULL)
        phieu->ngay_tra = ngay_tra;
    else
        phieu->ngay_tra = new Ngay_thang;
    phieu->the_doc_gia = the_doc_gia;
    phieu->trang_thai = trang_thai;
    return phieu;
}
Ngay_thang* tao_ngay_thang(int ngay = 1, int thang = 1, int nam = 1970)
{
    Ngay_thang* ngay_thang = new Ngay_thang;
    ngay_thang->ngay = ngay;
    ngay_thang->thang = thang;
    ngay_thang->nam = nam;
    return ngay_thang;
}
Dau_sach* tao_dau_sach(string ISBN, string ten_sach, int so_trang, string tac_gia, int nam_xuat_ban, string the_loai)
{
    Dau_sach* dau_sach = new Dau_sach;
    dau_sach->ISBN = ISBN;
    dau_sach->ten_sach = ten_sach;
    dau_sach->so_trang = so_trang;
    dau_sach->tac_gia = tac_gia;
    dau_sach->nam_xuat_ban = nam_xuat_ban;
    dau_sach->the_loai = the_loai;
    dau_sach->so_lan_muon = 0;
    dau_sach->danh_muc_sach.clear();

    danh_sach_the_loai_sach.insert(the_loai);

    return dau_sach;
}
Sach* tao_sach(string ma_sach, int trang_thai, string vi_tri)
{
    Sach* sach = new Sach;
    sach->ma_sach = ma_sach;
    sach->trang_thai = trang_thai;
    sach->vi_tri = vi_tri;
    return sach;
}
/* Phan hien thuc ham */

void nhap_dau_sach()
{
    string ten_sach, tac_gia, the_loai, ISBN = random_ISBN(), ma_sach, vi_tri;
    int nam_xuat_ban, so_trang, trang_thai;
    cin.clear();
    cin.ignore();
    cout << "\n==========================" << endl;
    cout << "Ma ISBN: " << ISBN << endl;
    cout << "NHAP VAO CAC THONG TIN SAU" << endl;
    cout << "Ten sach: ";
    getline(cin, ten_sach);
    ten_sach = viet_in_hoa(chuan_hoa_chuoi(ten_sach));

    cout << "So trang: ";
    cin >> so_trang;

    cout << "Tac gia: ";
    cin.ignore();
    getline(cin, tac_gia);
    tac_gia = viet_in_hoa(chuan_hoa_chuoi(tac_gia));

    cout << "Nam xuat ban: ";
    cin >> nam_xuat_ban;

    cout << "The loai: ";
    cin.ignore();
    getline(cin, the_loai);
    the_loai = viet_in_hoa(chuan_hoa_chuoi(the_loai));

    Dau_sach* dau_sach = tao_dau_sach(ISBN, ten_sach, so_trang, tac_gia, nam_xuat_ban, the_loai);
    // [1,2,3,x,x,x,], num = 3
    danh_sach_dau_sach[so_luong_dau_sach++] = dau_sach;
    cout << "\n==========================" << endl;
    cout << left << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;
    cout << left << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
    cout << "\n==========================" << endl;
    int so_luong_sach{ 0 };
    cout << "So luong sach: ";
    cin >> so_luong_sach;
    cout << "\n==========================" << endl;
    for (int j = 0; j < so_luong_sach; j++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[so_luong_dau_sach - 1];
        ma_sach = dau_sach->ISBN + to_string(j + 1);
        cout << "Ma sach " << j + 1 << ": " << ma_sach << endl;

        cout << "Trang thai sach (0: cho muon duoc - 1: da co doc gia muon - 2: sach da thanh ly): ";
        cin >> trang_thai;
        while (trang_thai != 0 && trang_thai != 1 && trang_thai != 2)
        {
            cout << "Nhap sai trang thai!\n";
            cout << "Nhap lai trang thai (0: cho muon duoc - 1: da co doc gia muon - 2: sach da thanh ly): ";
            cin >> trang_thai;
        }

        cout << "Vi tri sach: ";
        cin >> vi_tri;

        Sach* sach = tao_sach(ma_sach, trang_thai, vi_tri);
        dau_sach->danh_muc_sach.push_back(sach);

        cout << "\n==========================" << endl;
        cout << left << setw(10) << "STT" << setw(29) << "Ma sach" << setw(29) << "Trang thai" << setw(20) << "Vi tri" << endl;
        int n{ 0 };
        for (list<Sach*>::iterator it = danh_sach_dau_sach[so_luong_dau_sach - 1]->danh_muc_sach.begin(); it != danh_sach_dau_sach[so_luong_dau_sach - 1]->danh_muc_sach.end(); it++)
        {
            cout << left << setw(10) << n + 1 << setw(29) << (*it)->ma_sach << setw(29) << (*it)->trang_thai << setw(20) << (*it)->vi_tri << endl;
            n++;
        }
        cout << "\n==========================" << endl;
    }
    cin.ignore();
}

void in_dau_sach()
{
    cout << "\n==========================" << endl;
    cout << "BANG THONG TIN CAC DAU SACH THEO THU TU TEN SACH TANG DAN\n";
    cout << left << setw(10) << "STT" << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;

    vector<string> ten_sach_sap_xep;
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach* dau_sach = danh_sach_dau_sach[i];
        ten_sach_sap_xep.push_back(dau_sach->ten_sach);
    }
    sort(ten_sach_sap_xep.begin(), ten_sach_sap_xep.end());
    for (int j = 0; j < ten_sach_sap_xep.size(); j++)
    {
        for (int k = 0; k < so_luong_dau_sach; k++)
        {
            Dau_sach* dau_sach = danh_sach_dau_sach[k];
            if (ten_sach_sap_xep[j] == dau_sach->ten_sach)
            {
                Dau_sach* dau_sach = danh_sach_dau_sach[k];
                cout << left << setw(10) << j + 1 << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
            }
        }
    }
}

void nhap_sach()
{
    int so_thu_tu{ 1 }, trang_thai, k{ 0 };
    string ma_sach, vi_tri;

    cout << setw(25) << "CHON DAU SACH DE CAP NHAT DANH MUC SACH" << endl;
    cout << left << setw(10) << "STT" << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[i];
        cout << left << setw(10) << i + 1 << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
    }

    cout << "NHAP VAO CAC THONG TIN SAU" << endl;
    cout << "So thu tu: ";
    cin >> so_thu_tu;

    cout << left << setw(10) << "STT" << setw(29) << "Ma sach" << setw(29) << "Trang thai" << setw(20) << "Vi tri" << endl;
    for (list<Sach*>::iterator it = danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.begin(); it != danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.end(); it++)
    {
        cout << left << setw(10) << k + 1 << setw(29) << (*it)->ma_sach << setw(29) << (*it)->trang_thai << setw(20) << (*it)->vi_tri << endl;
        k++;
    }

    int so_luong_sach{ 0 };
    cout << "So luong sach (lon hon 0): ";
    cin >> so_luong_sach;
    while (so_luong_sach < 0)
    {
        cout << "Nhap sai so luong sach!\n";
        cout << "Nhap lai so luong sach (lon hon 0): ";
        cin >> trang_thai;
    }
    for (int j = 0; j < so_luong_sach; j++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[so_thu_tu - 1];
        ma_sach = dau_sach->ISBN + to_string(k + j + 1);
        cout << "Ma sach " << k + j + 1 << ": " << dau_sach->ISBN + to_string(k + j + 1) << endl;

        cout << "Trang thai sach (0: cho muon duoc - 1: da co doc gia muon - 2: sach da thanh ly): ";
        cin >> trang_thai;
        while (trang_thai != 0 && trang_thai != 1 && trang_thai != 2)
        {
            cout << "Nhap sai trang thai!\n";
            cout << "Nhap lai trang thai (0: cho muon duoc - 1: da co doc gia muon - 2: sach da thanh ly): ";
            cin >> trang_thai;
        }

        cout << "Vi tri sach: ";
        cin >> vi_tri;

        Sach* sach = tao_sach(ma_sach, trang_thai, vi_tri);
        dau_sach->danh_muc_sach.push_back(sach);

        cout << left << setw(10) << "STT" << setw(29) << "Ma sach" << setw(29) << "Trang thai" << setw(20) << "Vi tri" << endl;

        int n{ 0 };
        for (list<Sach*>::iterator it = danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.begin(); it != danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.end(); it++)
        {
            cout << left << setw(10) << n + 1 << setw(29) << (*it)->ma_sach << setw(29) << (*it)->trang_thai << setw(20) << (*it)->vi_tri << endl;
            n++;
        }
    }
    cin.ignore();
}

void in_sach()
{
    int so_thu_tu{ 1 }, m{ 1 };

    cout << setw(25) << "CHON DAU SACH DE XEM DANH MUC SACH" << endl;
    cout << left << setw(10) << "STT" << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[i];
        cout << left << setw(10) << i + 1 << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
    }

    cout << "NHAP VAO THONG TIN SAU" << endl;
    cout << "So thu tu: ";
    cin >> so_thu_tu;

    cout << left << setw(10) << "STT" << setw(29) << "Ma sach" << setw(29) << "Trang thai" << setw(20) << "Vi tri" << endl;
    for (list<Sach*>::iterator it = danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.begin(); it != danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.end(); it++)
    {
        cout << left << setw(10) << m++ << setw(29) << (*it)->ma_sach << setw(29) << (*it)->trang_thai << setw(20) << (*it)->vi_tri << endl;
    }
}

void tim_sach()
{
    string ten_sach_can_tim, ten_sach;
    bool tim_thay{ false };
    cout << "Nhap ten sach can tim: ";
    cin.ignore();
    getline(cin, ten_sach_can_tim);
    ten_sach_can_tim = viet_in_hoa(chuan_hoa_chuoi(ten_sach_can_tim));

    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[i];
        ten_sach = dau_sach->ten_sach;
        if (ten_sach.find(ten_sach_can_tim) != string::npos)
        {
            tim_thay = true;
        }
    }
    if (tim_thay == true)
    {
    }
    else
    {
        cout << "Khong tim thay sach!" << endl;
        return;
    }

    cout << left << setw(10) << "STT" << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;
    int so_thu_tu, k{ 0 };
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[i];
        ten_sach = dau_sach->ten_sach;
        if (ten_sach.find(ten_sach_can_tim) != string::npos)
        {
            cout << left << setw(10) << i + 1 << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
        }
    }
    cout << "Nhap STT de hien thi danh muc sach: ";
    cin >> so_thu_tu;

    cout << left << setw(10) << "STT" << setw(29) << "Ma sach" << setw(29) << "Trang thai" << setw(20) << "Vi tri" << endl;
    for (list<Sach*>::iterator it = danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.begin(); it != danh_sach_dau_sach[so_thu_tu - 1]->danh_muc_sach.end(); it++)
    {
        cout << left << setw(10) << k + 1 << setw(29) << (*it)->ma_sach << setw(29) << (*it)->trang_thai << setw(20) << (*it)->vi_tri << endl;
        k++;
    }
}

void in_the_loai()
{
    vector<string> danh_sach_the_loai;

    int so_thu_tu{ 1 }, i{ 1 }, luong_sach_the_loai, index{ 0 };

    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach* dau_sach = danh_sach_dau_sach[i];
        danh_sach_the_loai_sach.insert(dau_sach->the_loai);
    }

    cout << "\n==========================" << endl;
    cout << left << setw(10) << "STT" << setw(29) << "THE LOAI" << endl;
    for (auto it = danh_sach_the_loai_sach.begin(); it != danh_sach_the_loai_sach.end(); it++)
    {
        danh_sach_the_loai.push_back(*it);
    }

    for (int i = 0; i < danh_sach_the_loai.size(); i++)
    {
        cout << left << setw(10) << i + 1 << setw(29) << danh_sach_the_loai[i] << endl;
    }
    cout << "\n==========================" << endl;

    cout << "Nhap STT ung voi the loai: ";
    cin >> so_thu_tu;

    cout << "\n==========================" << endl;
    cout << left << setw(10) << "STT" << setw(29) << "ISBN" << setw(29) << "Ten sach" << setw(20) << "So trang" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;

    vector<string> ten_sach_sap_xep;
    Dau_sach* dau_sach_the_loai = danh_sach_dau_sach[so_thu_tu - 1];
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach* dau_sach = danh_sach_dau_sach[i];
        if (dau_sach->the_loai == danh_sach_the_loai[so_thu_tu - 1])
        {
            ten_sach_sap_xep.push_back(dau_sach->ten_sach);
        }
    }
    sort(ten_sach_sap_xep.begin(), ten_sach_sap_xep.end());
    for (int j = 0; j < ten_sach_sap_xep.size(); j++)
    {
        for (int k = 0; k < so_luong_dau_sach; k++)
        {
            Dau_sach* dau_sach = danh_sach_dau_sach[k];
            if (ten_sach_sap_xep[j] == dau_sach->ten_sach)
            {
                cout << left << setw(10) << j + 1 << setw(29) << dau_sach->ISBN << setw(29) << dau_sach->ten_sach << setw(20) << dau_sach->so_trang << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
            }
        }
    }
}

void luu_file_dau_sach()
{
    ofstream fout;
    fout.open("./Data/dau_sach.txt");
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        fout << danh_sach_dau_sach[i]->ISBN << endl;
        fout << danh_sach_dau_sach[i]->ten_sach << endl;
        fout << danh_sach_dau_sach[i]->so_trang << endl;
        fout << danh_sach_dau_sach[i]->tac_gia << endl;
        fout << danh_sach_dau_sach[i]->nam_xuat_ban << endl;
        fout << danh_sach_dau_sach[i]->the_loai << endl;
        fout << danh_sach_dau_sach[i]->so_lan_muon << endl;
        fout << danh_sach_dau_sach[i]->danh_muc_sach.size() << endl;
        //    luu danh muc sach
        for (list<Sach*>::iterator it = danh_sach_dau_sach[i]->danh_muc_sach.begin(); it != danh_sach_dau_sach[i]->danh_muc_sach.end(); it++)
        {
            fout << (*it)->ma_sach << endl;
            fout << (*it)->trang_thai << endl;
            fout << (*it)->vi_tri << endl;
        }
    }
    fout.close();
}

void doc_file_dau_sach()
{
    ifstream fin;
    fin.open("./Data/dau_sach.txt");
    if (!fin.is_open())
    {
        cout << "Khong mo duoc file dau sach!\n";
        return;
    }
    while (!fin.eof())
    {
        string ISBN, ten_sach, tac_gia, the_loai;
        int nam_xuat_ban;
        int so_lan_muon;
        int so_luong_sach, so_trang;
        string tempt;
        getline(fin, ISBN);
        if (ISBN == "")
            break;
        getline(fin, ten_sach);
        getline(fin, tempt);
        so_trang = stoi(tempt);
        getline(fin, tac_gia);
        getline(fin, tempt);
        nam_xuat_ban = stoi(tempt);
        getline(fin, the_loai);
        getline(fin, tempt);
        so_lan_muon = stoi(tempt);
        getline(fin, tempt);
        so_luong_sach = stoi(tempt);

        Dau_sach* dau_sach = tao_dau_sach(ISBN, ten_sach, so_trang, tac_gia, nam_xuat_ban, the_loai);
        for (int i = 0; i < so_luong_sach; i++)
        {
            string ma_sach, vi_tri, tempt;
            int trang_thai;
            getline(fin, ma_sach);
            getline(fin, tempt);
            trang_thai = stoi(tempt);
            getline(fin, vi_tri);

            Sach* sach = tao_sach(ma_sach, trang_thai, vi_tri);
            dau_sach->danh_muc_sach.push_back(sach);
        }
        dau_sach->so_lan_muon = so_lan_muon;
        danh_sach_dau_sach[so_luong_dau_sach] = dau_sach;
        so_luong_dau_sach++;
    }

    fin.close();
}

void luu_file_the_doc_gia()
{
    ofstream fout;
    fout.open("./Data/the_doc_gia.txt");
    vector<The_doc_gia*> ds_the_doc_gia_tempt = in_order_BST(danh_sach_the_doc_gia);
    for (int i = 0; i < ds_the_doc_gia_tempt.size(); i++)
    {
        The_doc_gia*& the_doc_gia = ds_the_doc_gia_tempt[i];
        fout << the_doc_gia->ma_the << endl;
        fout << the_doc_gia->ho_ten << endl;
        fout << the_doc_gia->gioi_tinh << endl;
        fout << the_doc_gia->trang_thai << endl;
        fout << the_doc_gia->so_sach_dang_muon << endl;
        for (int j = 0; j < the_doc_gia->so_sach_dang_muon; j++)
        {
            fout << the_doc_gia->sach_dang_muon[j]->ma_phieu << endl;
        }
    }
    fout.close();
}

void luu_ngay_thang()
{
    ofstream fout;
    fout.open("./Data/ngay_thang.txt");
    fout << ngay_thang_hien_tai->ngay << endl;
    fout << ngay_thang_hien_tai->thang << endl;
    fout << ngay_thang_hien_tai->nam << endl;
    fout.close();
}
void luu_file_phieu_muon_tra_sach()
{
    ofstream fout("./Data/phieu_muon_tra_sach.txt");
    fout << danh_so_the_muon << endl;
    for (auto it = danh_sach_phieu_muon_tra_sach.begin(); it != danh_sach_phieu_muon_tra_sach.end(); it++)
    {
        fout << (*it)->ma_phieu << endl;
        fout << (*it)->sach->ma_sach << endl;
        fout << (*it)->ngay_muon->ngay << endl;
        fout << (*it)->ngay_muon->thang << endl;
        fout << (*it)->ngay_muon->nam << endl;
        fout << (*it)->ngay_tra->ngay << endl;
        fout << (*it)->ngay_tra->thang << endl;
        fout << (*it)->ngay_tra->nam << endl;
        fout << (*it)->trang_thai << endl;
    }
    fout.close();
}
void doc_file_phieu_muon_tra_sach()
{
    //  doc file va tao lai danh sach
    ifstream fin("./Data/phieu_muon_tra_sach.txt");
    if (!fin.is_open())
    {
        cout << "Khong mo duoc file phieu muon tra sach!\n";
        return;
    }
    The_doc_gia* the_doc_gia_tempt = NULL;
    string tempt;
    getline(fin, tempt);
    danh_so_the_muon = stoi(tempt);
    while (!fin.eof())
    {
        string ma_phieu, ma_sach;
        int ngay, thang, nam;
        int ngay_tra, thang_tra, nam_tra;
        int trang_thai;
        getline(fin, ma_phieu);
        if (ma_phieu == "")
            break;
        getline(fin, ma_sach);
        getline(fin, tempt);
        ngay = stoi(tempt);
        getline(fin, tempt);
        thang = stoi(tempt);
        getline(fin, tempt);
        nam = stoi(tempt);
        getline(fin, tempt);
        ngay_tra = stoi(tempt);
        getline(fin, tempt);
        thang_tra = stoi(tempt);
        getline(fin, tempt);
        nam_tra = stoi(tempt);
        getline(fin, tempt);
        trang_thai = stoi(tempt);
        Ngay_thang* ngay_muon = tao_ngay_thang(ngay, thang, nam);
        Ngay_thang* ngay_thang_tra = tao_ngay_thang(ngay_tra, thang_tra, nam_tra);
        Phieu_muon_tra_sach* phieu_muon_tra_sach = tao_phieu_muon_tra_sach(tim_sach_theo_ma_sach(ma_sach), ngay_muon, ngay_thang_tra, the_doc_gia_tempt, ma_phieu);
        danh_sach_phieu_muon_tra_sach.push_back(phieu_muon_tra_sach);
    }
    fin.close();
}
void doc_file_the_doc_gia()
{
    //    doc va tao lai danh sach
    ifstream fin("./Data/the_doc_gia.txt");
    if (!fin.is_open())
    {
        cout << "Khong mo duoc file the doc gia!\n";
        return;
    }
    string tempt;
    while (!fin.eof())
    {
        string ho_ten, gioi_tinh;
        int so_sach_dang_muon, ma_the, trang_thai;
        getline(fin, tempt);
        if (tempt == "")
            break;
        ma_the = stoi(tempt);
        getline(fin, ho_ten);
        getline(fin, gioi_tinh);
        getline(fin, tempt);
        trang_thai = stoi(tempt);
        getline(fin, tempt);
        so_sach_dang_muon = stoi(tempt);
        The_doc_gia* the_doc_gia = tao_the_doc_gia(ma_the, ho_ten, gioi_tinh);
        for (int i = 0; i < so_sach_dang_muon; i++)
        {
            getline(fin, tempt);
            Phieu_muon_tra_sach* phieu_muon_tra_sach_tempt = tim_phieu_muon_tra_theo_ma_phieu(tempt);
            phieu_muon_tra_sach_tempt->the_doc_gia = the_doc_gia;
            the_doc_gia->sach_dang_muon[i] = phieu_muon_tra_sach_tempt;
            the_doc_gia->sach_dang_muon[i]->the_doc_gia = the_doc_gia;
            the_doc_gia->so_sach_dang_muon++;
        }
        add_BST(danh_sach_the_doc_gia, the_doc_gia);
    }
    fin.close();
}
void doc_file_ngay_thang()
{
    ifstream fin("./Data/ngay_thang.txt");
    if (!fin.is_open())
    {
        cout << "Khong mo duoc file ngay thang!\n";
        return;
    }
    string tempt;
    getline(fin, tempt);
    ngay_thang_hien_tai->ngay = stoi(tempt);
    getline(fin, tempt);
    ngay_thang_hien_tai->thang = stoi(tempt);
    getline(fin, tempt);
    ngay_thang_hien_tai->nam = stoi(tempt);
    fin.close();
}

Sach* tim_sach_theo_ma_sach(string ma_sach)
{
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        if (danh_sach_dau_sach[i]->ISBN == ma_sach.substr(0, 13))
            for (list<Sach*>::iterator it = danh_sach_dau_sach[i]->danh_muc_sach.begin(); it != danh_sach_dau_sach[i]->danh_muc_sach.end(); it++)
            {
                if ((*it)->ma_sach == ma_sach)
                {
                    return *it;
                }
            }
    }
    return NULL;
}
Phieu_muon_tra_sach* tim_phieu_muon_tra_theo_ma_phieu(string ma_phieu)
{
    for (auto it = danh_sach_phieu_muon_tra_sach.begin(); it != danh_sach_phieu_muon_tra_sach.end(); it++)
    {
        if ((*it)->ma_phieu == ma_phieu)
            return *it;
    }
    return NULL;
}
The_doc_gia* tim_the_doc_gia_theo_ma_the(int ma_the)
{
    return search_BST(danh_sach_the_doc_gia, ma_the);
}

void nhap_the_doc_gia()
{
    int ma_the = random_ma_the();
    string ho_ten, gioi_tinh;
    cout << "Ma the: DG" << ma_the << endl;
    cin.ignore();
    cout << "Nhap ho ten: ";
    getline(cin, ho_ten);
    cout << "Nhap gioi tinh (NAM - NU): ";
    getline(cin, gioi_tinh);
    gioi_tinh = viet_in_hoa(chuan_hoa_chuoi(gioi_tinh));
    while (gioi_tinh != "NAM" && gioi_tinh != "NU")
    {
        cout << "Nhap sai gioi tinh!\n";
        cout << "Nhap lai gioi tinh: (NAM - NU)";
        getline(cin, gioi_tinh);
        gioi_tinh = viet_in_hoa(chuan_hoa_chuoi(gioi_tinh));
    }

    The_doc_gia* the_doc_gia = tao_the_doc_gia(ma_the, ho_ten, gioi_tinh);
    add_BST(danh_sach_the_doc_gia, the_doc_gia);
}
void in_the_doc_gia_theo_ma_the()
{
    vector<The_doc_gia*> danh_sach_the_doc_gia_tempt = in_order_BST(danh_sach_the_doc_gia);
    //   in danh sach
    cout << left << setw(15) << "Ma the" << setw(15) << "Ho ten" << setw(15) << "Gioi tinh" << setw(5) << "TT" << setw(15) << "So sach dang muon" << endl;
    for (int i = 0; i < danh_sach_the_doc_gia_tempt.size(); i++)
    {
        The_doc_gia*& t = danh_sach_the_doc_gia_tempt[i];

        cout << left << setw(15) << t->ma_the << setw(15) << t->ho_ten << setw(15) << t->gioi_tinh << setw(5) << t->trang_thai << setw(15) << t->so_sach_dang_muon << endl;
    }
}

string lay_ten(string ho_ten)
{
    string ten;
    size_t pos = ho_ten.rfind(' ');
    if (pos != string::npos)
    {
        return ho_ten.substr(pos + 1);
    }
    else
        return ho_ten;
    // ten = ho_ten.substr(pos + 1);
}
bool so_sanh_ten_ho(string a, string b)
{
    string a_tempt = chuan_hoa_chuoi(a);
    string b_tempt = chuan_hoa_chuoi(b);

    // get last word
    string ten_a = lay_ten(a_tempt);
    string ten_b = lay_ten(b_tempt);

    if (ten_a == ten_b)
        return a_tempt < b_tempt;
    else
        return ten_a < ten_b;
}

bool so_sanh_the_theo_ho_ten(The_doc_gia* a, The_doc_gia* b)
{
    return so_sanh_ten_ho(a->ho_ten, b->ho_ten);
}
void in_the_doc_gia_theo_ho_ten()
{
    vector<The_doc_gia*> danh_sach_the_doc_gia_tempt = in_order_BST(danh_sach_the_doc_gia);
    //   in danh sach
    // sort theo ten
    sort(danh_sach_the_doc_gia_tempt.begin(), danh_sach_the_doc_gia_tempt.end(), so_sanh_the_theo_ho_ten);
    cout << left << setw(15) << "Ma the" << setw(15) << "Ho ten" << setw(15) << "Gioi tinh" << setw(5) << "TT" << setw(15) << "So sach dang muon" << endl;
    for (int i = 0; i < danh_sach_the_doc_gia_tempt.size(); i++)
    {
        The_doc_gia*& t = danh_sach_the_doc_gia_tempt[i];

        cout << left << setw(15) << t->ma_the << setw(15) << t->ho_ten << setw(15) << t->gioi_tinh << setw(5) << t->trang_thai << setw(15) << t->so_sach_dang_muon << endl;
    }
}
void in_the_doc_gia()
{
    cout << "1. In the theo ma the\n";
    cout << "2. In the theo ho ten\n";
    int chon;
    cout << "Chon: (1 hoac 2) ";
    cin >> chon;
    while (chon != 1 && chon != 2)
    {
        cout << "Nhap sai!\n";
        cout << "Nhap lai: ";
        cin >> chon;
    }
    if (chon == 1)
        in_the_doc_gia_theo_ma_the();
    else
        in_the_doc_gia_theo_ho_ten();
}
void xoa_the_doc_gia()
{
    int ma_the;
    cout << "Nhap ma the can xoa: ";
    cin >> ma_the;
    The_doc_gia* the_doc_gia = tim_the_doc_gia_theo_ma_the(ma_the);
    if (the_doc_gia == NULL)
    {
        cout << "Khong tim thay the doc gia!\n";
        return;
    }
    // In thong tin the doc gia
    cout << left << setw(15) << "Ma the" << setw(15) << "Ho ten" << setw(15) << "Gioi tinh" << setw(5) << "TT" << setw(15) << "So sach dang muon" << endl;
    cout << left << setw(15) << the_doc_gia->ma_the << setw(15) << the_doc_gia->ho_ten << setw(15) << the_doc_gia->gioi_tinh << setw(5) << the_doc_gia->trang_thai << setw(15) << the_doc_gia->so_sach_dang_muon << endl;
    cout << "Ban co muon xoa the doc gia nay khong? (y/n): ";
    char c;
    cin >> c;
    if (c == 'n' || c == 'N')
        return;

    for (int i = 0; i < the_doc_gia->so_sach_dang_muon; i++)
    {
        delete the_doc_gia->sach_dang_muon[i];
        the_doc_gia->sach_dang_muon[i] = NULL;
    }
    remove_BST(danh_sach_the_doc_gia, the_doc_gia->ma_the);
    cout << "Xoa thanh cong!\n";
}
void muon_sach()
{
    int ma_the;
    string ten_sach;
    cout << "Nhap ma the: ";
    cin >> ma_the;
    The_doc_gia* the_doc_gia = tim_the_doc_gia_theo_ma_the(ma_the);
    if (the_doc_gia == NULL)
    {
        cout << "Khong tim thay the doc gia!\n";
        return;
    }
    xin_chao_doc_giai(the_doc_gia);

    if (!kiem_tra_dieu_kien_muon_sach(the_doc_gia))
    {
        cout << "Doc gia khong du dieu kiem muon sach.\n";
        return;
    }
    cout << "Tim sach\n";
    cout << "Nhap ten sach: ";
    cin.ignore();
    getline(cin, ten_sach);
    vector<Dau_sach*> danh_sach_sach_tempt = tim_sach_theo_ten(ten_sach);
    if (danh_sach_sach_tempt.size() == 0)
    {
        cout << "Khong tim thay sach!\n";
        return;
    }
    cout << "Danh sach sach tim duoc:\n";
    cout << left << setw(4) << "STT" << setw(20) << "Ten sach" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;

    for (int i = 0; i < danh_sach_sach_tempt.size(); i++)
    {
        Dau_sach*& dau_sach = danh_sach_sach_tempt[i];
        cout << left << setw(4) << i + 1 << setw(20) << dau_sach->ten_sach << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
        // cout << left << setw(15) << s->ma_sach << setw(15) << s->ten_sach << setw(15) << s->tac_gia << setw(15) << s->nha_xuat_ban << setw(15) << s->gia_sach << endl;
    }
    cout << "Chon sach muon: (1 ->" << danh_sach_sach_tempt.size() << ") ";
    int chon;
    cin >> chon;
    if (chon < 1 || chon > danh_sach_sach_tempt.size())
    {
        cout << "Chon khong hop le!\n";
        return;
    }
    Dau_sach*& dau_sach = danh_sach_sach_tempt[chon - 1];
    Sach* sach_muon = NULL;
    // tim sach trong dau sach
    for (list<Sach*>::iterator it = dau_sach->danh_muc_sach.begin(); it != dau_sach->danh_muc_sach.end(); it++)
    {
        if ((*it)->trang_thai == 0)
        {
            sach_muon = *it;
            break;
        }
    }
    if (sach_muon == NULL)
    {
        cout << "Sach da muon het!\n";
        return;
    }
    Phieu_muon_tra_sach* phieu_muon_tra_sach = tao_phieu_muon_tra_sach(sach_muon, ngay_thang_hien_tai, NULL, the_doc_gia);
    danh_sach_phieu_muon_tra_sach.push_back(phieu_muon_tra_sach);
    the_doc_gia->sach_dang_muon[the_doc_gia->so_sach_dang_muon] = phieu_muon_tra_sach;
    the_doc_gia->so_sach_dang_muon++;
    sach_muon->trang_thai = 1;
    dau_sach->so_lan_muon++;
    cout << "Muon sach thanh cong!\n";
}

std::vector<Dau_sach*> tim_sach_theo_ten(std::string ten_sach)
{
    vector<Dau_sach*> danh_sach_sach_tempt;
    danh_sach_sach_tempt.clear();
    string key_word = chuan_hoa_chuoi(viet_in_hoa(ten_sach));
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        Dau_sach*& ds = danh_sach_dau_sach[i];
        if (ds->danh_muc_sach.empty())
            continue;
        string ten_dau_sach = chuan_hoa_chuoi(viet_in_hoa(ds->ten_sach));
        if (ten_dau_sach.find(key_word) != string::npos)
        {
            danh_sach_sach_tempt.push_back(ds);
        }
    }
    return danh_sach_sach_tempt;
}
void in_sach_dang_muon_theo_the_doc_gia(The_doc_gia* the_doc_gia)
{
    if (the_doc_gia == NULL)
    {
        return;
    }
    if (the_doc_gia->so_sach_dang_muon == 0)
    {
        cout << "Khong co sach dang muon!\n";
        return;
    }
    cout << "Danh sach sach dang muon:\n";
    cout << left << setw(4) << "STT" << setw(20) << "Ten sach" << setw(20) << "Tac gia" << setw(20) << "Nam xuat ban" << setw(20) << "The loai" << endl;
    for (int i = 0; i < the_doc_gia->so_sach_dang_muon; i++)
    {
        Phieu_muon_tra_sach*& phieu_muon_tra_sach = the_doc_gia->sach_dang_muon[i];
        Dau_sach* dau_sach = tim_dau_sach_theo_ISBN(phieu_muon_tra_sach->sach->ma_sach.substr(0, 13));
        cout << left << setw(4) << i + 1 << setw(20) << dau_sach->ten_sach << setw(20) << dau_sach->tac_gia << setw(20) << dau_sach->nam_xuat_ban << setw(20) << dau_sach->the_loai << endl;
    }
}
Dau_sach* tim_dau_sach_theo_ISBN(string ISBN)
{
    for (int i = 0; i < so_luong_dau_sach; i++)
    {
        if (danh_sach_dau_sach[i]->ISBN == ISBN)
        {
            return danh_sach_dau_sach[i];
        }
    }
    return NULL;
}
void tra_sach()
{
    int ma_the;
    cout << "Nhap ma the: ";
    cin >> ma_the;
    The_doc_gia* the_doc_gia = tim_the_doc_gia_theo_ma_the(ma_the);
    in_sach_dang_muon_theo_the_doc_gia(the_doc_gia);
    if (the_doc_gia == NULL)
    {
        cout << "Khong tim thay the doc gia!\n";
        return;
    }
    xin_chao_doc_giai(the_doc_gia);
    cout << "Chon sach muon tra: (1 ->" << the_doc_gia->so_sach_dang_muon << ") ";
    int chon;
    cin >> chon;
    if (chon < 1 || chon > the_doc_gia->so_sach_dang_muon)
    {
        cout << "Chon khong hop le!\n";
        return;
    }
    Phieu_muon_tra_sach* phieu = the_doc_gia->sach_dang_muon[chon - 1];
    phieu->ngay_tra = ngay_thang_hien_tai;
    phieu->trang_thai = 1;
    phieu->sach->trang_thai = 0;

    the_doc_gia->sach_dang_muon[chon - 1] = the_doc_gia->sach_dang_muon[the_doc_gia->so_sach_dang_muon - 1];
    the_doc_gia->sach_dang_muon[the_doc_gia->so_sach_dang_muon - 1] = NULL;
    the_doc_gia->so_sach_dang_muon--;

    cout << "Tra sach thanh cong!\n";
}

void in_sach_dang_muon()
{
    int ma_the;
    cout << "Nhap ma the: ";
    cin >> ma_the;
    The_doc_gia* the_doc_gia = tim_the_doc_gia_theo_ma_the(ma_the);
    if (the_doc_gia == NULL)
    {
        cout << "Khong tim thay the doc gia!\n";
        return;
    }
    xin_chao_doc_giai(the_doc_gia);
    in_sach_dang_muon_theo_the_doc_gia(the_doc_gia);
}

void xin_chao_doc_giai(The_doc_gia* the_doc_gia)
{
    if (the_doc_gia == NULL)
    {
        return;
    }
    cout << "Xin chao " << the_doc_gia->ho_ten << "!\n";
}

bool kiem_tra_bi_tre_han(The_doc_gia* the_doc_gia)
{
    if (the_doc_gia == NULL)
    {
        return false;
    }
    if (the_doc_gia->so_sach_dang_muon == 0)
    {
        return false;
    }
    for (int i = 0; i < the_doc_gia->so_sach_dang_muon; i++)
    {
        Phieu_muon_tra_sach*& phieu_muon_tra_sach = the_doc_gia->sach_dang_muon[i];
        if (getDifferenceDay(phieu_muon_tra_sach->ngay_muon, ngay_thang_hien_tai) > MAX_NGAY_MUON)
        {
            return true;
        }
    }
    return false;
}
bool kiem_tra_dieu_kien_muon_sach(The_doc_gia* the_doc_gia)
{
    // TODO can lam
    if (the_doc_gia->trang_thai == 0)
    {
        cout << "The doc gia bi khoa!\n";
        return false;
    }
    if (the_doc_gia->so_sach_dang_muon >= MAX_SACH_MUON)
    {
        cout << "The doc gia da muon qua so luong sach!\n";
        return false;
    }
    // ton tai sach qua han
    if (kiem_tra_bi_tre_han(the_doc_gia))
    {
        cout << "The doc gia da muon qua thoi gian muon!\n";
        return false;
    }

    return true;
}
bool so_sanh_ngay_thang(Ngay_thang* a, Ngay_thang* b)
{
    return a->nam > b->nam;
    return a->thang > b->thang;
    return a->ngay > b->ngay;
}
int so_ngay_tre_han(The_doc_gia* t)
{
    int res = 0;
    for (int i = 0; i < t->so_sach_dang_muon; i++)
    {
        Phieu_muon_tra_sach*& phieu_muon_tra_sach = t->sach_dang_muon[i];
        int tempt = getDifferenceDay(phieu_muon_tra_sach->ngay_muon, ngay_thang_hien_tai);
        if (tempt > res)
            res = tempt;
    }
    return res;
}
bool so_sanh_tre_han(The_doc_gia* a, The_doc_gia* b)
{
    return so_ngay_tre_han(a) > so_ngay_tre_han(b);
}
void in_danh_sach_the_thu_tu_tre_han()
{
    vector<The_doc_gia*> ds_the_doc_gia_dan_no = in_order_BST(danh_sach_the_doc_gia);
    int i = 0;
    while (i < ds_the_doc_gia_dan_no.size())
    {
        The_doc_gia*& the_doc_gia = ds_the_doc_gia_dan_no[i];
        if (kiem_tra_bi_tre_han(the_doc_gia))
        {
            i++;
        }
        else
        {
            ds_the_doc_gia_dan_no.erase(ds_the_doc_gia_dan_no.begin() + i);
        }
    }
    // sort theo ngay muon
    sort(ds_the_doc_gia_dan_no.begin(), ds_the_doc_gia_dan_no.end(), so_sanh_tre_han);
    cout << left << setw(15) << "Ma the" << setw(15) << "Ho ten" << setw(15) << "Gioi tinh" << setw(5) << "TT" << setw(15) << "So sach dang muon" << endl;
    for (int i = 0; i < ds_the_doc_gia_dan_no.size(); i++)
    {
        The_doc_gia*& t = ds_the_doc_gia_dan_no[i];

        cout << left << setw(15) << t->ma_the << setw(15) << t->ho_ten << setw(15) << t->gioi_tinh << setw(5) << t->trang_thai << setw(15) << t->so_sach_dang_muon << endl;
    }
}
bool so_sanh_so_lan_muon(Dau_sach* a, Dau_sach* b)
{
    return a->so_lan_muon > b->so_lan_muon;
}
void thong_ke_10_sach_cao_nhat()
{
    // return 0;3
    // sort dau sach theo so lan muon
    sort(danh_sach_dau_sach, danh_sach_dau_sach + so_luong_dau_sach, so_sanh_so_lan_muon);
    cout << left << setw(15) << "Ma sach" << setw(15) << "Ten sach" << setw(15) << "So luong" << endl;
    for (int i = 0; i < 10; i++)
    {
        Dau_sach*& dau_sach = danh_sach_dau_sach[i];
        if (dau_sach == NULL)
        {
            break;
        }
        cout << left << setw(15) << dau_sach->ISBN << setw(15) << dau_sach->ten_sach << setw(15) << dau_sach->so_lan_muon << endl;
    }
}