Thứ Ba, 12 tháng 6, 2012

Bài toán quản lý nhân viên - Cấu trúc dữ liệu và giải thuật

Phát biểu bài toán

Xem chi tiết tại đây http://kenhdaihoc.com/forum/showthread.php?t=4516 

Giả sử có một quy tắc tổ chức quản lý nhân viên của một công ty như sau :

Thông ti n về một nhân viên bao gồm lý lịch và bảng chấm công

+ Lý lịch nhân viên :
- Mã nhân viên : chuỗi 8 kí tự
- Họ, tên nhân viên : chuỗi 30 kí tự
- Tình trạng gia đình : 1 kí tự ( m=married , s= single)
- Số con : Số nguyên ≤ 20
- Trình độ văn hóa : chuỗi 2 kí tự (C1,C2,C3,DH,CH )
- Lương căn bản : số thực ≤ 1 triệu

+ Chấm công nhân viên
- Số ngày nghỉ có phép trong tháng : số ≤ 28
- Số ngày nghỉ không phép trong tháng : số ≤ 28
- Số ngày làm thêm trong tháng : số ≤ 28
- Kết quả công việc : chuỗi 2 kí tự (TO=tốt,BT=đạt,KE=kém)
- Lương thực lĩnh trong tháng : số ≤ 2 triệu

Quy tắc lĩnh lương
Trong đó nếu : lương thực lĩnh = lương căn bản + phụ trội

- Số con > 2 : phụ trội = +5 % lương căn bản
- Trình độ văn hóa = CH : phụ trội = +10% lương căn bản
- Làm thêm : phụ trội = +4% lương căn bản/ngày
- Nghỉ không phép : phụ trội = -5% lương căn bản/ngày

Y
êu cầu
Xây dự ng chương trình quản lý nhân viên c ủa công ty bằng ngôn ngữ C (sử dụng danh sách liên kết đơ n để tổ chức dữ liệu cho danh sách cán bộ) . C hương trình bao gồm
các chức năng sau :
- Nhập dữ liệu
- Tính lương thực lĩnh của các nhân viên
- Sắp xếp danh sách theo mã nhân viên
- Thêm một nhân viên mới
- Xóa một nhân viên ( Thông qua mã nhân viên)
- Sửa đổi thông tin về một nhân viên
- Xem thông ti n về một nhân viên
- Xem bảng lương c ủa toàn thể nhân viên ( chỉ xem họ tên và lương )
- Thoát

I. Xác định bài toán

a. Input của bài toán :
- Thông tin của các nhân viên
- Thông tin của nhân viên cần được xử lý ( tìm kiếm, sửa đổi, xóa bỏ,hiển thị )

b. Output cuả bài toán
- Lương thực lĩnh của từng nhân viên nhập vào
- Danh sách mới sau khi được xử lý ( tìm kiếm, sửa đổi, xóa bỏ các nhân viên )
- Bảng lương của toàn thế nhân viên


II. Tìm cấu trúc dữ liệu bài toán

Sử dụng danh sách liên kết đơ n với cấu trúc như sau :

[CODE]struct data{
         char mnv[9]; // mã nhân viên
         char hoten[31]; // họ và tên
         char tt;            //tình trạng gia đình
         char socon; //số con
         char vanhoa[3]; //trình trạng văn hóa
         char nphep; //số ngày nghỉ phép
         char nkophep;            //số ngày không nghỉ phép
         char nlamthem; //số ngày làm thêm
         char ketqua[3]; //kết quả công việc
         float luongcb; //lương cơ bản
         float luongtl; //lương thực lĩnh
};
struct node     // nút liên kết
{
    data info;
    node *next;
};
struct list     //cấu trúc dữ liệu của danh sách
{
    node *head;
    node *tail;
};

[/CODE]

III. Tìm thuật toán
A. Khởi tạo và nhập danh sách
1Ý tưởng : lặp đi lặp lại quá trình thêm nhân viên vào danh sách
2Thuật toán :
Bước 1 : Gọi hàm thêm nhân viên
Bước 2 : Hỏi có nhập tiếp ko : có thì về bước 1 , không thì thoát khỏi việc nhập



3. Cài đặt
[CODE]void nhap(list &ds){
    do
    {
        themnv(ds);
        printf("Ban co nhap tiep khong (Y/N) ? \n");
    }
    while (toupper(getch())=='Y');
}


[/CODE]

4. Đánh giá độ p hức tạp của giải thuật


==> Vậy độ phức tạp của giải thuật là O(n)

B. Nhập nút
1. Ý tưởng, thuật toán : Nhập lần lượt các thông tin của một nhân viên
2. Cài đặt:

[CODE]void nhapnut(node *p,int cachthuc)
{
if (cachthuc==1)
    {
        printf("Ma nhan vien      (max08char): ");
        fflush(stdin);gets(p->info.mnv);
        printf("Ho va ten           max30char: ");
        fflush(stdin);gets(p->info.hoten);
    }
        printf("Tinh trang hon nhan       M/S: ");  scanf("%c",&p->info.tt);
        printf("So con                    <21: ");       scanf("%d",&p->info.socon);
        printf("Van hoa              Cx/DH/CH: ");    scanf("%s",&p->info.vanhoa);
        printf("So ngay nghi phep         <28: ");   scanf("%d",&p->info.nphep);
        printf("So ngay nghi ko phep      <28: "); scanf("%d",&p->info.nphep);
        printf("So ngay lam them           <5: ");    scanf("%d",&p->info.nphep);
        printf("Ket qua cong viec    TO/BT/KE: ");
        fflush(stdin);gets(p->info.ketqua);
        printf("Luong can ban             <1M: ");
        float temp; scanf("%f",&temp); p->info.luongcb=temp;
        tinhluongtl(p);                p->next=NULL
}[/CODE]

3. Đánh giá độ p hức tạp giải thuật: giải thuật trên có độ p hức tạp hằng số : O(1)

C. Chèn sau

1. Ý tưởng : Nếu danh sách rỗng thì cho Head và Tail trỏ vào phần tử mới.
Không thì thực hiện như sau :
Ban đầu :

2. Thuật toán :
Bước 1 : Nếu danh sách rỗng sang bước 2 không thì sang bước 3
Bước 2 : Gán Head và Tail trỏ đến phần tử mới, kết thúc
Bước 3 :
- cho Tail next trỏ đến phần tử mới
- cho Tail trỏ đến phần tử mới


3. Cài đặt
[CODE]
void chensau(list &ds,node *p)
{
    if  (ds.head==NULL)
    {
        ds.head=p;          ds.tail=p;
    }
    else
    {
        ds.tail->next=p;   ds.tail=p;
    }
}


[/CODE]


4. Đánh giá độ p hức tạp của giải thuật

=> Vậy độ phức tạp của giải thuật là O(1)

D. Thêm một nhân viên mới
1. Ý tưởng : Tạo 1 node mới và chèn vào sau danh sách
2. Thuật toán
Bước 1 : khai báo 1 con trỏ p kiểu node
Bước 2 : Cấp phát cho p 1 vùng nhớ mới, kiểm tra nếu
Bước 3 : Kiểm tra nếu (p==NULL) thì kết thúc , ko thì sang bước 4
Bước 4 : Nhập các thông tin vào p ( gọi hàm nhập nút )
Bước 5 : Chèn p vào danh sách ( gọi hàm chèn sau )


3. Cài đặt





[CODE]void themnv(list &ds)
{
    node *p;
    p=(node *)malloc(sizeof(node));
    if (p==NULL) return;
    nhapnut(p,1);
    chensau(ds,p);
}[/CODE]

4. Đánh giá độ phức tạp : Giải thuật trên có độ p hức tạp hằng số O(1)

E. Hiển thị danh sách
1. Ý tưởng: duyệt từ đầu danh sách đến cuối danh sách, hiển thị thông tin của nhân viên đó ra
2. Thuật toán:
Bước 1 : Khai báo 1 con trỏ p;
Bước 2 : p=head;
Bước 3 : Nếu( p==NULL) sang bước 6 ko thì sáng bước 4
Bước 4 : Hiển thị các thông tin nằm trong con trỏ p
Bước 5 : p=p next; về bước 3
Bước 6 : Kết thúc

3. Cài đặt

[CODE]void hienthids(list &ds)
{
    node *p;
    p=ds.head;
    printf("\nMa nhan vien       Ho va ten               Luong thuc linh");
    while(p!=NULL)
    {
        printf("\n%   -12s       %-25s %-10.0f ",p->info.mnv,p->info.hoten,p->info.luongtl);
        p=p->next;
    }
}[/CODE]

4. Đánh giá độ phức tạp giải thuật


==> Vậy độ phức tạp của giải thuật là O(n)

F. Sắp xếp danh sách

1. Ý tưởng : Ta sử dụng tư tưởng của thuật toán đổi chỗ trực tiếp (interchange
sort) để xắp xếp danh sách
2. Thuật toán
Bước 1 : khai báo con trỏ p,q có kiểu node *
Bước 2 : cho p trỏ vào đầu danh sách : p=head
Bước 3 : Nếu (p!=NULL và p→next !=NULL) sang bước 4 ko thì kết thúc
Bước 4 : Cho q=p → next
Bước 5 : Nếu q!= NULL thì sang bước 5 không thì sang bước 8
Bước 6 : Nếu thông tin cần so sánh của p<q thì hoán vị (p và q)
Bước 7 : Cho q=q→next rồi về bước 5
Bước 8 : Cho p=p→next rồi về bước 3







3. Cài đặt
[CODE]void sapxep(list &ds) //interchange sort
{
    node *p,*q;
    p=ds.head;
    while (p!=NULL&&p->next!=NULL)
    {
        q=p->next;
        while (q!=NULL)
        {
            if (strcmp(q->info.mnv,p->info.mnv)== 1) hoanvi(p,q);
            q=q->next;
        }
            p=p->next;
    }
}[/CODE]


4. Đánh giá độ p hức tạp
+ Số lượng các phép so sánh (câu lệnh if ) ko phụ thuộc vào tình trạng dãy
số ban đầu (đã xắp xếp hoặc chưa ) luôn luôn là 

+ Số lương hoán vị p hụ thuộc vào kết quả của phép so sánh
+ Việc hoán vị trên 2 con trỏ ta chỉ thay đổi giá trị nằm trong con trỏ ( tức là
thay đổi địa chỉ vùng nhớ mà nó trỏ vào ) nên mất O(1)=i thời gian
+ Nếu phép so sánh cho kết quả đúng thì câu lệnh if mất 2*i thời gian, không
thì sẽ mất i thời gian

==> Vậy độ phức tạp của giải thuật là O(n2)

G. Xóa một nhân viên
1. Ý tưởng : Để xóa bỏ 1 thành phần trong danh sách liên kết đơn ta cần biết thành phần trước nó. Vậy ta sẽ duyệt từ đầu danh sách đến cuối danh sách, trong quá trình duyệt ta sẽ lưu lại địa chỉ của
nút trước nút đang duyệt để sau khi tìm thấy tiến hành thay đổi các móc nối
Ứng với mỗi mã nhân viên chỉ có 1 nhân viên tương ứng nên sau khi tìm thấy và xóa đi ta sẽ dừng việc duyệt lại.
Nếu có tìm thấy ( để xóa ) thì có các trường hợp xảy ra :
Nhân viên cần xóa ở đầu danh sách o nếu danh sách có 1 nút thì ta cho Head và Tail trỏ đến NULL,
sau đó giải phóng bộ nhớ

Nhân viên cần xóa nằm ở giữa danh sách có nhiều nút thì ta cho next
của thằng trước đó trỏ vào nút đằng sau của nút cần xóa sau đó giải
phóng bộ nhớ

2. Thuật toán
Bước 1 : Khai báo con trỏ p,q kiểu node * và cho cả 2 trỏ vào đầu danh sách
Bước 2 : Nếu p!=NULL thì sang bước 3 không thì kết thúc
Bước 3 : Nếu p là nút cần xóa thì sang bước 5 ko thì sang bước 4
Bước 4 : q=p sau đó p=p→next // như thế ta sẽ có q là nút đứng trước p
Bước 5 : Nếu p là đầu danh sách thì sang bước 6 ko thì sang bước 9
Bước 6 : Nếu danh sách có 1 nút thì sang bước 7 ko thì sang bước 8
Bước 7 : head=tail=NULL, sang bước 12
Bước 8 : head=head→next, sang bước 12
Bước 9 : Nếu p là tail thì sang bước 10 ko thì sang bước 11
Bước 10: tail=q, tail→next=NULL ,sang bước 12
Bước 11: q→next=p→next , sang bước 12
Bước 12: free(p) sau đó return //return sẽ dẫn đến kết thúc thuật toán


3. Cài đặt

[CODE]void xoanut(list &ds,char *mcx)
{
    node *p,*q;
    q=p=ds.head;
    while (p!=NULL)
    {
        if (stricmp(p->info.mnv,mcx)==0)
        {
            if (p==ds.head)
                if (p->next==NULL)
                    ds.head=ds.tail=NULL;
                else
                    ds.head=ds.head->next;
            else
                if (p->next==NULL)
                {
                    ds.tail=q;
                    ds.tail->next=NULL;
                }
                else
                    q->next=p->next;
            return;
        }
        q=p;
        p=p->next;
    }
}[/CODE]

4. Đánh giá độ p hức tạp
+ Câu lệnh if trong vòng lặp có độ p hức tạp O(logn)
+ Chi phí cho vòng lặp

==> Vậy độ p hức tạp của giải thuật là O(n.logn)


H. Tính lương thực lĩnh của các nhân viên
1. Cài đặt

[CODE]void tinhluongtl(node *p)
{
    int pt;
    pt=(p->info.socon>2)?0:5;
    pt+=(strcmp(p->info.vanhoa,"CH")==0)?0:10;
    pt+=p->info.nlamthem*4;
    pt-=p->info.nkophep*5;
    p->info.luongtl=p->info.luongcb*(1+pt/100.0);
}[/CODE]

2. Đánh giá độ p hức tạp : Hàm này có độ p hức tạp hằng số O(1)
I. Tìm nhân viên dựa vào mã nhân viên hoặc họ tên
1. Ý tưởng : (tìm kiếm tuyến tính)
Duyệt danh sách từ đầu đến cuối nếu chuỗi tìm kiếm trùng với họ tên
hoặc mã nhân viên thì trả về địa chỉ của nút đó
2. Thuật toán
Bước 1 : Khai báo 1 con trỏ p;
Bước 2 : p=head;
Bước 3 : Nếu( p!=NULL) sang bước 4 ko kết thúc
Bước 4 : Nếu p là nv cần tìm thì return p không thì sang bước 5
Bước 5 : p=p next; về bước 3


3. Cài đặt

[CODE]node* timkiem(list ds,char *xau)
{
    node *p;
    p=ds.head;
    while (p!=NULL)
    {
        if (strcmp(xau,p->info.mnv)==0 || strcmp(xau,p->info.hoten)==0) return p;
        p=p->next;
    }
    return NULL;
}
[/CODE]

4. Đánh giá độ phức tạp :

==> Vậy độ p hức tạp của giải thuật là O(n)


J. Sửa thông tin 1 nhân viên
1. Ý tưởng :
Đầu tiên ta khai báo 1 con trỏ p , sau đó tìm kiếm trên danh sách phần tử có
mã nhân viên hoặc họ tên như đối tượng ta muốn sửa đổi. Sau đó nếu tìm
thấy ta sẽ tiến hành sửa đổi
2. Thuật toán
Bước 1 : Khai báo 1 con trỏ p kiểu node
Bước 2 : p=timkiem(ds,xau)
Bước 3 : Nếu p!=NULL thì sang bước 4 không thì kết thúc thuật toán
Bước 4 : Nhập lại thông tin vào con trỏ p ( gọi hàm nhập nút )


3. Cài đặt
[CODE]void suanut(list ds,char *xau)
{
    node *p=timkiem(ds,xau);
    if (p!=NULL)
    {
        printf("\nNhap lai thong tin cho nhan vien do : ");
        nhapnut(p,2);
    }
}[/CODE]

4. Đánh giá độ p hức tạp
+ Việc tìm kiếm sẽ chi phí O(n) thời gian
+ Việc nhập nút sẽ chi phí O(1) thời gian
Theo quy tắc tổng thì hàm sẽ có độ p hức tạp O(max(O(n),O(1))) = O(n)
==> Vậy độ p hức tạp của giải thuật là O(n)

K. Xem thông tin 1 nhân viên
1. Ý tưởng :
Đầu tiên ta khai báo 1 con trỏ p , sau đó tìm kiếm trên danh sách phần tử có
mã nhân viên hoặc họ tên như đối tượng ta muốn xem
Sau đó nếu có thì ta hiển thị thông tin của nút đó lên
2. Thuật toán
Bước 1 : Khai báo 1 con trỏ p kiểu node
Bước 2 : p=timkiem(ds,xau)
Bước 3 : Nếu p!=NULL thì sang bước 4 không thì kết thúc thuật toán
Bước 4 : Hiển thị thông tin con trỏ trong p




3. Cài đặt


[CODE]void hienthinv(list ds)
{
    char *xau;
    printf("\nNhap vao ho ten hoac ma nhan vien muon xem : ");
    fflush(stdin);
    gets(xau);
    node *p=timkiem(ds,xau);
    if (p!=NULL)
    {
        printf("\nMa nhan vien       Ho va ten               Luong thuc linh");
        printf("\n% -12s       %-25s %-10.0f ",p->info.mnv,p->info.hoten,p->info.luongtl);
        printf("\nTinh trang hon nhan     : %c",p->info.tt);
        printf("\nSo con                          : %d",p->info.socon);
        printf("\nVan hoa                        : %s",p->info.vanhoa);
        printf("\nSo ngay nghi phep       : %d",p->info.nphep);
        printf("\nSo ngay nghi ko phep : %d",p->info.nphep);
        printf("\nSo ngay lam them        : %d",p->info.nphep);
        printf("\nKet qua cong viec        : %s",p->info.ketqua);
        printf("\nLuong can ban             : %f",p->info.luongcb);
        printf("\nLuong thuc linh             : %f",p->info.luongtl);
    }
}[/CODE]

4. Đánh giá giải thuật
+ Việc tìm kiếm sẽ chi phí O(n) thời gian
+ Việc hiển thị nút sẽ chi phí O(1) thời gian
Theo quy tắc tổng thì hàm sẽ có độ p hức tạp O(max(O(n),O(1))) = O(n)
==> Vậy độ p hức tạp của giải thuật là O(n)

L. Xóa danh sách

1. Ý tưởng :
Sau khi chương trình kết thúc , việc bộ nhớ xin cấp phát có được tự giải
phóng hay ko thì tùy thuộc vào cài đặt của trình biên dịch và hệ điều hành.
Chúng ta có 2 khả năng

-Khả năng 1 : trong phần khởi động (trước khi vào function main() ), program xin một khối memory cuả system gọi là XXXX và mỗi lần malloc được gọi thì cấp pháp một phần memory cuả XXXX cho malloc.
Do đó, khi program exit thì trả XXXX về cho system là xong. Trong trường hợp này không bị mất memory
-Khả năng 2 : mỗi lần malloc được gọi thì xin memory từ system .
Trường hợp này có thể memory không trả về cho system. Lúc này chương trình sẽ bị gọi là có memory
leak.Như vậy sau vài lần chạy sẽ ko còn memory để cấp phát nữa
( Theo chuẩn C99 thì malloc luôn phải có free)
Vì vậy ta sẽ giải phóng toàn bộ bộ nhớ đã cấp phát cho danh sách
Ta sẽ dùng ý tưởng xóa nút đầu tiên trong danh sách để xóa danh sách :
Trong khi head khác rỗng thì xóa head

2. Thuật toán
Bước 1 : Khai báo con trỏ p kiểu node và cho p trỏ vào đầu danh sách
Bước 2 : Nếu p!=NULL thì sang bước 3, ko thì kết thúc thuật toán
Bước 3 : Cho head trỏ vào nút liền sau head hiện tại
Bước 4 : giải phóng bộ nhớ cho con trỏ p ( đang trỏ vào head cũ )
Bước 5 : gán p=head hiện tại rồi về bước 2.





3. Cài đặt

[CODE]
void xoads(list &ds)
{
   node *p=ds.head;
   while (p!=NULL)
   {
       ds.head=ds.head->next;
       free(p);
       p=ds.head;
   }
}


[/CODE]


4. Đánh giá độ p hức tạp của giải thuật
==> Vậy độ phức tạp của giải thuật là O(n)

IV. Lập trình
Check file CTDLdemo.cpp.
Sơ bộ hàm main:

[CODE]void main(void)     // đây chỉ là bản demo
{
do
{
        clrscr();
        printf("*------------Menu------------*\n");
        printf("1. Nhap du lieu\n");
        printf("2. Hien thi danh sach\n");
        printf("3. Sap xep danh sach\n");
        printf("4. Them mot nhan vien moi\n");
        printf("5. Xoa mot nhan vien\n");
        printf("6. Sua thong tin mot nhan vien\n");
        printf("7. Xem thong tin ve mot nhan vien\n");
        printf("8. Xem bang luong cua toan the nhan vien\n");
        printf("9. Thoat");
        printf("\nDanh sach hien tai ");hienthids(triduc);
        printf("\n\nNhap vao lua chon cua ban : \n");
        switch(getch())
        {
                  case '1' : nhap(triduc);break;
                  case '2' : hienthids(triduc);break;
                  case '3' : sapxep(triduc);break;
                  case '4' : themnv(triduc);break;
                  case '5' : xoanut(triduc);break;
                  case '6' : suanut(triduc);break;
                  case '7' : hienthinv(triduc);break;
                  case '8' : hienthids(triduc);break;
                  case '9' : xoads(triduc);exit(0);
        }
}
while(1);
}[/CODE]

Định hướng phát triển

I. Đánh giá chương trình
Sơ bộ :
Chương trình đã giải quyết tương đối với yêu cầu , mục đích đề ra của bài toán ( một bài tập cấu trúc dữ liệu lớn
về danh sách liên kết ).
Ưu điểm : 
- Tin cậy : Cấu trúc dữ liệu đã đạt đúng tiêu chuẩn (phản ánh đúng thực tế, phù hợp với thao tác xử lý, tiết kiệm tài nghuyên hệ thống ). Chương trình chạy đúng , mô tả đúng giải thuật, đúng với yêu cầu đề ra của bài toán ( tính tin cậy )
- Trong sáng : Các module trong chương trình đều đạt được đến độ phức tạp thấp nhất giúp cộng thêm code conversion hợp lý giúp cho code dễ đọc, dễ hiểu và nắm bắt ý tưởng
- Uyển chuyển : chương trình được tách ra làm nhiều module nhỏ(nhưng đều có tác dụng hữu ích cụ thể ), các module đều có độ phức tạp thấp, nên việc debug hoặc thay đổi là tương đối đơn giản
- Hữu hiệu : Xét về khía cạnh bài tập thì chương trình đạt đến độ hữu hiệu tương đối ( nhưng xét về góc độ ứng dụng thì....)
- Bộ nhớ : So với kĩ năng sử dụng mảng thì sử dụng dach sách liên kết có phần linh động hơn. Trong mảng thì yêu cầu tất cả các phần tử phải liên tiếp nhưng với danh sách liên kết thì các phần tử là rời rạc nhau dẫn đến ít khả năng ko cấp phát được hơn và ta sử dụng đến đâu cấp phát đến đấy sẽ ko lãng phí bộ nhớ
Nhược điểm :
Chương trình còn đơn giản với những nhược điểm sau đây :

Nhập : tất cả việc nhập đều dùng các hàm chuẩn của C vì thế có
thể sinh lỗi trong quá trình nhập nếu người nhập nhập sai kiểu dữ
liệu. Vẫn có thể nhập tên trùng, mã nhân viên trùng nhau
 Lưu trữ : Sau khi kết thúc chương trình thì toàn bộ danh sách đã
nhập sẽ mất. Nhược điểm này sẽ làm giảm bớt tính hữu dụng của
chương trình
 Ngôn ngữ : Vấn đề về ngôn ngữ là 1 vấn đề khá lớn với việc phát
triển phần mềm tại việt nam. Bộ font Unicode ra đời đã thay đổi
tình hình của vấn đề. Tuy nhiên tất cả các IDE C lại ko hỗ trợ vấn
đề về ngôn ngữ
 Tính mềm dẻo( hay còn được coi là độ dễ tính ) : tức là mức độ
của cách thức xử lý của trương trình trước những tình huống ngoài
dự tính (AI-Artificial Intelligence). Chương trình xử lý được những
tình huống ngoài dự tính 1 cách thông minh và hiệu quả thì được
coi là dễ tính, chương trình càng dễ tính thì càng thân thiện với
người sử dụng. Chương trình trên lại hoàn toàn ko có điều này

 Tổ chức bộ nhớ: Bộ nhớ vừa là ưu điểm vừa là nhược điểm của
chương trình. Chương trình C nằm gọn trong 1 segment có độ lớn
max là 64KB (code + data + heap + stack nằm gọn trong 1
segment). Như thế cái lợi là khi call function thì c hỉ cần dùng call
near, c hỉ cần offset thôi, không cần đổi giá trị của segment nên
chạy nhanh. Cái hại là chuơng trình không thể lớn.
 Chương trình được viết bằng ngôn ngữ C (đơn nhiệm , tuần tự ),
được biên dịch bằng compiler của hãng borland :Turbo C hoặc
Borland C nên chương trình chạy trên nền NTVDM.exe ( NT
Virtual DOS Machine ). Bản thân NTVDM là chương trình tạo máy
ảo 16 bit trên Windows 32 bit, nó được xem như là 1 tiến trình hệ
thống nên tuy nó tốn ít tài nguyên ram nhưng lại chiếm dụng tài
nguyên hệ thống lớn 1 cách vô ích : 95% với CPU đơn nhiệm, 50%
với CPU dual core và core 2 duo, 25% với CPU core quad. Vì vậy
tuy là 1 chương trình nhỏ nhưng nó ko hề nhẹ tí gì. Điều này sẽ
hạn chế k hả năng chương có thể đi từ góc độ bài tập sang thực tế
ứng dụng
 Giao diện của chương trình DOS ko thân thiện ( một trong những
yếu tố quan trọng quyết định sự thành bại của chương trình )

II. Final version
Trước những vấn đề đặt ra, ưu điểm thì ít nhưng nhược điểm thì quá nhiều, vì vậy final
ver đã ra đời với các update sau :
Sửa lỗi việc nhập, giúp cho việc nhập hoàn thiện hơn đúng đắn hơn :
- Chuẩn hóa việc nhập số nguyên: không bị bất kì bug nào khi nhập
số nguyên như gõ nhầm chữ cái, nhầm số thực........., không vượt
quá các mốc cho phép nhập,....
- Chuẩn hóa việc nhập xâu kí tự : Không nhập vượt quá được xâu kí
tự, tình trạng gia đình chỉ có thể nhập S hoặc M, tên ko có số và kí
tự đặc biệt,kết quả công việc ko nhập sai được.......
- Nhập xong sẽ được chuẩn hóa tên
- Và nhiều nâng cấp có hữu ích khác trong việc nhập
Có tạo được cơ sở dữ liệu riêng nhằm lưu lại danh sách sau khi thoát, tuy
nhiên còn rất sơ giản và chưa thực sự hiệu quả
Có sự nâng cấp về ngôn ngữ : nhập, xuất tiếng việt
Có sự nâng cấp về giao diện giúp tăng tính thân thiện giữa người và máy
Có thêm 1 số hotkey
Kiểm tra file CTDLfinal.cpp để biết thêm chi tiết

III. Định hướng phát triển
Việc tin học hoá tổ c hức quản lý nhân sự mang lại nhiều lợi ích hơn so với quản
lý thủ công. Quản lý thông tin về cán bộ, công nhân viên là một bài toán quan
trọng và có nhiều ứng dụng trong việc quản lý nguồn nhân lực, chính sách cán
bộ... nhằm đưa ra các quyết định trong lĩnh vực xây dựng đội ngũ lao động đủ
khả năng và trình độ đáp ứng các nhu cầu trong giai đoạn mới.
Trên thị trường phần mềm việt nam hiện nay có rất nhiều phần mềm q uản lý
nhân sự, nhưng lại chưa có sảm phẩm nào chiếm được sự thông dụng và nổi
trội. Một số sảm phẩm được giải thưởng và được đề cao nhưng đang chỉ dừng
lại ở mức giải thưởng . Thêm vào đó mỗi công ty lại có những đặc tính công việc
khác nhau nên việc quản lý nhân sự cũng có nhiều thay đổi so với mỗi công ty.
Vì vậy cơ hội đang là chia đều cho mọi người.
Quản lý nhân sự - phần mềm việt dành cho người việt. Một phần mềm của
người việt và được phục vụ rỗng rãi tại việt nam.

Để đến được cái đích đó cần có nhiều thay đổi, nâng cấp cực kì lớn về góc độ
lập trình và góc độ người sử dụng như
1. Chương trình sẽ được viết lại bằng ngôn ngữ cấp cao hơn, có hộ trỡ lập
trình GUI, có hỗ trợ unicode và sảm phẩm cuối cùng là 1 chương trình 32
bit hoặc 64 bit
2. Tìm kiểu cấu trúc dữ liệu thật sự hợp lý, có thể lưu trữ hàng nghìn đến
chục nghìn nhân viên có nhiều thông tin chi tiết hơn nhưng các thao tác
với nó có chi phí thấp nhất. Tuy danh sách liên kết rất hay nhưng nó lại
xin bộ nhớ trực tiếp từ RAM, như thế sẽ làm giảm hiệu quả của ct vì chi
phí hệ thống quá cao.
3. Chương trình cần hệ thống cơ sở dữ liệu tốt hơn, an toàn hơn hộ trợ
nhiều truy vấn (ví dụ các nhân viên có thể xem tình hình, trạng thái, kết
quả làm việc hàng tháng )
4. Và rất nhiều thay đổi khác nhằm mang chương đến với thực tế và đến với
người sử dụng
Và nó cũng rất cần những yếu tố tiềm ẩn mang đến thành công sau :

1. Đột phá ý tưởng : năm 1994 yahoo được sáng lập, và tuy là sinh sau đẻ
muộn so với window messenger ( ngày nay là window live messenger)
vốn dĩ có rất nhiều ưu thế của Microsoft ( lợi thế đặc biệt nhất chính là 1
sảm phẩm gắn chặt với dòng sảm phẩm nổi tiếng microsoft window) .
Ngày nay , Theo Alexa Internet và Netcraft (hai công ty chuyên về thống
kê lưu lượng Web) Yahoo! là website được nhiều người coi thứ hai hiện
giờ ( sau Google). Sự thành công của yahoo mang lại từ ý tưởng.
2. Tính hiệu quả của chương trình : thể hiện ở độ “thông minh” của
chương trình và quan trọng nhất là kết quả của chương trình mang lại.
Năm 1996, google ra đời trong bối cảnh chỉ là “đàn em” so với dịch vụ tìm
kiếm của Yahoo và MSN... Sự thành công của Google mang lại nhờ 2 yếu
tố đó là đơn giản và hiệu quả.
3. Sự đơn giản trong cách sử dụng : đó là sự đơn giản trong cách sử
dụng. Điều này đã mang đến sự thành công cho google và cả microsoft (1
trong những điều khiến người sử dụng yêu thích window hơn linux chính
là vì sự đơn giản trong cách sử dụng) .
4. Giao diện thân thiện, đẹp mắt : điều này đã mang lại thành công bất
ngờ cho window xp ra đời năm 2001
........................................
Hãy đón xem ý tưởng này sẽ trở thành như thế nào trong tương lai ko xa!
Nguồn: wWw.kenhdaihoc.com - Trích: Bài toán quản lý nhân viên – Bùi Tấn Quang – Cn1k7d1
Share:

0 nhận xét:

Đăng nhận xét