• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 183,  comments - 10,  trackbacks - 0
            /Files/unixfy/考勤處理程序-MarkYang.pdf 

             

            考勤處理程序

             

            Mark Yang

            QQ: 591 247 876

            Email: goonyangxiaofang@163.com

             

             

            一個考勤數據最主要的三項就是:

            人名         日期         打卡時間

             

            所以我們這里針對這三項數據進行處理。

             

            一、對原始打卡記錄集進行預處理

            首先,需要對這些考勤記錄進行處理,去每個人,每一天的最早和最晚打卡時間,分別作為上班時間和下班時間。

             

            考勤記錄中一個人一天可能有0、1、2、3、……個等多種情況的打卡記錄,如果有0條記錄,那么自然我們找不到;如果有1條記錄,那么我們即將其作為上班時間也將其作為下班時間,因為上班時間和下班時間肯定不是一個時間,所以這種情況下肯定存在遲到或早退現象,甚至即遲到又早退;如果有大于等于2個記錄,那么我們去其中的最早和最晚時間分別作為上班時間和下班時間,并且比較這里的上班時間和下班時間是否分別早于和晚于規定的上班時間和下班時間,以此來判斷是否遲到或早退。

            我們的程序首先要解決的問題就是要從一堆考勤記錄中,找到每個人每天最早和最晚的那兩個時間。

            考勤記錄示例:

            AAA 20120701         112933

            AAA 20120703         143838

            AAA 20120703         173006

            AAA 20120703         173011

            BBB 20120704         082317

            BBB 20120704         084932

            BBB 20120704         090709

            BBB 20120704         100721

            BBB 20120704         101016

            CCC 20120704         174635

             

            這里,我們考慮一種更為靈活的方式,就是這些記錄有可能被打散了,也就是說,記錄并不是按照人名、日期排列的,而是一個個之間沒有次序關聯的“人名 日期 打卡時間”獨立單元。

            這里采用人名+日期來劃分打卡記錄,讀取數據的時候,按照人民+日期來劃分。

            另外,這里為了后續的處理方便,我們順便得到人名集合和日期集合。

            程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <map>

            #include <set>

            #include <vector>

            #include <string>

            using namespace std;

             

            int main()

            {

                     ifstream fin("kaoqin.txt");

                     ofstream fout("1.txt");

                     ofstream fout_names("names.txt");

                     ofstream fout_dates("dates.txt");

                     if (!fin || !fout || !fout_names || !fout_dates)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     map<string, vector<string> > checkins;

                     set<string> names, dates;

                     string line;

                     string name, date, time;

                     while (getline(fin, line))

                     {

                               istringstream sin(line);

                               sin >> name >> date >> time;

                               names.insert(name);

                               dates.insert(date);

                               checkins[name + '\t' + date].push_back(time);

                     }

                     string earliest, lastest;

                     for (map<string, vector<string> >::const_iterator cit = checkins.begin(); cit != checkins.end(); ++cit)

                     {

                               earliest = lastest = cit->second[0];

                               for (vector<string>::size_type i = 0; i != cit->second.size(); ++i)

                               {

                                        if (earliest > cit->second[i])

                                        {

                                                 earliest = cit->second[i];

                                        }

                                        else if (lastest < cit->second[i])

                                        {

                                                 lastest = cit->second[i];

                                        }

                               }

                               fout << cit->first << '\t' << earliest << endl;

                               fout << cit->first << '\t' << lastest << endl;

                     }

                     for (set<string>::const_iterator cit = names.begin(); cit != names.end(); ++cit)

                     {

                               fout_names << *cit << endl;

                     }

                     for (set<string>::const_iterator cit = dates.begin(); cit != dates.end(); ++cit)

                     {

                               fout_dates << *cit << endl;

                     }

                     fin.close();

                     fout.close();

                     fout_names.close();

                     fout_dates.close();

                     return 0;

            }

             

            程序得到的結果是每人每天都有兩條記錄分別對應該人在當天最早的上班時間和最晚的下班時間。如果原始記錄集中只有一條記錄,那么這條記錄既作為最早上班時間也作為最晚下班時間。

            另外,得到的結果還有人名集和打卡記錄中的日期集。

             

            二、判斷每人每天是否遲到或早退

                     根據第一步得到的結果,每人每天有兩條打卡記錄,判斷第一條記錄是否早于上班時間,且第二條記錄是否晚于下班時間,如果都符合則說明沒有遲到和早退現象,否則存在遲到或早退現象。將出勤正常的記錄與出勤不正常的記錄分隔開,得到出勤正常結果和出勤不正常結果。

            程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <string>

            using namespace std;

             

            struct checkin

            {

                     string name;

                     string date;

                     string time;

            };

             

            void foo(ofstream& fout_nor, ofstream& fout_abn, const checkin& ci1, const checkin& ci2, const string& start, const string& end)

            {

                     if (ci1.time <= start)

                     {

                               fout_nor << ci1.name << '\t' << ci1.date << '\t' << ci1.time << endl;

                     }

                     else

                     {

                               fout_abn << ci1.name << '\t' << ci1.date << '\t' << ci1.time << endl;

                     }

                     if (ci2.time >= end)

                     {

                               fout_nor << ci2.name << '\t' << ci2.date << '\t' << ci2.time << endl;

                     }

                     else

                     {

                               fout_abn << ci2.name << '\t' << ci2.date << '\t' << ci2.time << endl;

                     }

            }

             

            int main()

            {

                     ifstream fin("1.txt");

                     ofstream fout_nor("2-normal.txt"), fout_abn("2-abnormal.txt");

                     if (!fin || !fout_nor || !fout_abn)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     string line1, line2;

                     checkin ci1, ci2;

                     string start = "083000", end = "173000";

                     while (getline(fin, line1) && getline(fin, line2))

                     {

                               istringstream sin1(line1), sin2(line2);

                               sin1 >> ci1.name >> ci1.date >> ci1.time;

                               sin2 >> ci2.name >> ci2.date >> ci2.time;

                               foo(fout_nor, fout_abn, ci1, ci2, start, end);

                     }

                     fin.close();

                     fout_nor.close();

                     fout_abn.close();

                     return 0;

            }

                     程序得到的兩個結果文件,一個是正常考勤記錄的,一個是遲到或早退的。我們下一步主要針對遲到或早退的記錄文件進行處理。

             

             

            三、對遲到或早退記錄進行統計

            1)按人名進行組織這些信息,并輸出有效的格式

                     按人名進行組織,在單個人名內部,又按日期進行組織。輸出的結果有兩種形式,分別是按行的輸出以及按列的輸出。

                     程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <string>

            #include <map>

            #include <set>

            #include <vector>

            using namespace std;

             

            struct date_time

            {

                     string date;

                     string time;

            };

             

            int main()

            {

                     ifstream fin_ci("2-abnormal.txt");

                     ofstream fout_row("3-name-row.txt");

                     ofstream fout_col("3-name-column.txt");

                     if (!fin_ci || !fout_row || !fout_col)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     map<string, vector<date_time> > bypers;

                     vector<string> names;

                     string line, name;

                     date_time dt;

                     int MAXNUM = 0;

                     while (getline(fin_ci, line))

                     {

                               istringstream sin(line);

                               sin >> name >> dt.date >> dt.time;

                               bypers[name].push_back(dt);

                     }

                     // 同名字下相同日期的合并

                     for (map<string, vector<date_time> >::iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               // 提取名字

                               names.push_back(cit->first);

                              

                               vector<date_time> tmp, hold = cit->second;

                               vector<date_time>::size_type i = 0;

                               while (i < hold.size() - 1)

                               {

                                        if (hold[i].date == hold[i+1].date)

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time + hold[i + 1].time;

                                                 tmp.push_back(dt);

                                                 i += 2;

                                        }

                                        else

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time;

                                                 tmp.push_back(dt);

                                                 ++i;

                                        }

                               }

                               // 最后兩個如果相等,那么 i 一下子回跳到 hold.size()

                               // 如果不相等,那么 i 變成 hold.size() - 1, 推出循環。

                               // 也就是說推出循環有兩種情況,分別是 i 為 hold.size() 和 hold.size() - 1

                               // i 為 hold.size() 的情況沒有遺漏記錄,i 為 hold.size() - 1 遺漏了數據,所以在此補充。

                               if (i == hold.size() - 1)

                               {

                                        dt.date = hold[i].date;

                                        dt.time = hold[i].time;

                                        tmp.push_back(dt);

                                        ++i;

                               }

                               // 記錄最大記錄個數

                               if (MAXNUM < tmp.size())

                               {

                                        MAXNUM = tmp.size();

                               }

                               cit->second = tmp;

                     }

                     // 按行輸出

                     for (map<string, vector<date_time> >::const_iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               fout_row << cit->first << '\t';

                               for (vector<date_time>::size_type i = 0; i != cit->second.size(); ++i)

                               {

                                        fout_row << cit->second[i].date << '\t' << cit->second[i].time << '\t';

                               }

                               fout_row << endl;

                     }

                    

                     // 先輸出人名

                     for (vector<string>::size_type i = 0; i != names.size(); ++i)

                     {

                               fout_col << names[i] << '\t';

                     }

                     fout_col << endl;

                     // 按列輸出

                     for (int i = 0; i != MAXNUM; ++i)

                     {

                               for (vector<string>::size_type j = 0; j != names.size(); ++j)

                               {

                                        if (bypers[names[j]].size() > i)

                                        {

                                                 fout_col << bypers[names[j]][i].date << ',' << bypers[names[j]][i].time << '\t';

                                        }

                                        else

                                        {

                                                 fout_col /* << "XXXXXX" */ << '\t';

                                                 // 這里的輸出 "XXXXXX" 可以省略,即可以直接 fout_col << '\t';

                                        }

                               }

                               fout_col << endl;

                     }

                     fin_ci.close();

                     fout_row.close();

                     fout_col.close();

                     return 0;

            }

             

            2)按日期進行組織

                     方法和按人名類似,只要把人名和日期轉換一下即可。這里在讀取數據的時候,故意把人名和日期進行逆置,其他部分不用修改。

                     輸出還是按行、按列兩種方式。

                     另外,輸入文件名和輸出文件名相應的修改一下。

             

            程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <string>

            #include <map>

            #include <set>

            #include <vector>

            using namespace std;

             

            struct date_time

            {

                     string date;

                     string time;

            };

             

            int main()

            {

                     ifstream fin_ci("2-abnormal.txt");

                     ofstream fout_row("3-date-row.txt");

                     ofstream fout_col("3-date-column.txt");

                     if (!fin_ci || !fout_row || !fout_col)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     map<string, vector<date_time> > bypers;

                     vector<string> names;

                     string line, name;

                     date_time dt;

                     int MAXNUM = 0;

                     while (getline(fin_ci, line))

                     {

                               /*

                               // 這是原來 3-1 的程序,即按照人名組織的。

                               istringstream sin(line);

                               sin >> name >> dt.date >> dt.time;

                               bypers[name].push_back(dt);

                               */

                               // 按照日期來組織

                               // 將原來的人名看做日期,原來的日期看做人名

                               istringstream sin(line);

                               sin >> dt.date >> name >> dt.time; // 要做的只是把 name 與 dt.date 的位置變換一下

                               bypers[name].push_back(dt);

                              

                     }

                     // 同名字下相同日期的合并

                     for (map<string, vector<date_time> >::iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               // 提取名字

                               names.push_back(cit->first);

                              

                               vector<date_time> tmp, hold = cit->second;

                               vector<date_time>::size_type i = 0;

                               while (i < hold.size() - 1)

                               {

                                        if (hold[i].date == hold[i+1].date)

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time + hold[i + 1].time;

                                                 tmp.push_back(dt);

                                                 i += 2;

                                        }

                                        else

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time;

                                                 tmp.push_back(dt);

                                                 ++i;

                                        }

                               }

                               // 最后兩個如果相等,那么 i 一下子回跳到 hold.size()

                               // 如果不相等,那么 i 變成 hold.size() - 1, 推出循環。

                               // 也就是說推出循環有兩種情況,分別是 i 為 hold.size() 和 hold.size() - 1

                               // i 為 hold.size() 的情況沒有遺漏記錄,i 為 hold.size() - 1 遺漏了數據,所以在此補充。

                               if (i == hold.size() - 1)

                               {

                                        dt.date = hold[i].date;

                                        dt.time = hold[i].time;

                                        tmp.push_back(dt);

                                        ++i;

                               }

                               // 記錄最大記錄個數

                               if (MAXNUM < tmp.size())

                               {

                                        MAXNUM = tmp.size();

                               }

                               cit->second = tmp;

                     }

                     // 按行輸出

                     for (map<string, vector<date_time> >::const_iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               fout_row << cit->first << '\t';

                               for (vector<date_time>::size_type i = 0; i != cit->second.size(); ++i)

                               {

                                        fout_row << cit->second[i].date << '\t' << cit->second[i].time << '\t';

                               }

                               fout_row << endl;

                     }

                    

                     // 先輸出人名

                     for (vector<string>::size_type i = 0; i != names.size(); ++i)

                     {

                               fout_col << names[i] << '\t';

                     }

                     fout_col << endl;

                     // 按列輸出

                     for (int i = 0; i != MAXNUM; ++i)

                     {

                               for (vector<string>::size_type j = 0; j != names.size(); ++j)

                               {

                                        if (bypers[names[j]].size() > i)

                                        {

                                                 fout_col << bypers[names[j]][i].date << ',' << bypers[names[j]][i].time << '\t';

                                        }

                                        else

                                        {

                                                 fout_col /* << "XXXXXX" */ << '\t';

                                                 // 這里的輸出 "XXXXXX" 可以省略,即可以直接 fout_col << '\t';

                                        }

                               }

                               fout_col << endl;

                     }

                     fin_ci.close();

                     fout_row.close();

                     fout_col.close();

                     return 0;

            }

             

            3)按照人名,日期進行二維輸出

                     這里有兩種方式,分別是“人名-日期”和“日期-人名”。

                     程序實現是根據人名+日期進行索引找到對應的出勤情況。

                     程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <string>

            #include <map>

            #include <set>

            #include <vector>

            using namespace std;

             

            struct date_time

            {

                     string date;

                     string time;

            };

             

            int main()

            {

                     ifstream fin_ci("2-abnormal.txt");

                     ofstream fout_name_date("3-name-date.txt");

                     ofstream fout_date_name("3-date-name.txt");

                     if (!fin_ci || !fout_name_date || !fout_date_name)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     map<string, vector<date_time> > bypers;

                     vector<string> names;

                     string line, name;

                     date_time dt;

                     int MAXNUM = 0;

                     // 記錄日期集合

                     set<string> dates_tmp;

                     while (getline(fin_ci, line))

                     {

                               istringstream sin(line);

                               sin >> name >> dt.date >> dt.time;

                               dates_tmp.insert(dt.date); // 記錄日期集合

                               bypers[name].push_back(dt);

                     }

                     // 日期集合

                     vector<string> dates(dates_tmp.begin(), dates_tmp.end());

                    

                     // 同名字下相同日期的合并

                     for (map<string, vector<date_time> >::iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               // 提取名字

                               names.push_back(cit->first);

                              

                               vector<date_time> tmp, hold = cit->second;

                               vector<date_time>::size_type i = 0;

                               while (i < hold.size() - 1)

                               {

                                        if (hold[i].date == hold[i+1].date)

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time + hold[i + 1].time;

                                                 tmp.push_back(dt);

                                                 i += 2;

                                        }

                                        else

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time;

                                                 tmp.push_back(dt);

                                                 ++i;

                                        }

                               }

                               // 最后兩個如果相等,那么 i 一下子回跳到 hold.size()

                               // 如果不相等,那么 i 變成 hold.size() - 1, 推出循環。

                               // 也就是說推出循環有兩種情況,分別是 i 為 hold.size() 和 hold.size() - 1

                               // i 為 hold.size() 的情況沒有遺漏記錄,i 為 hold.size() - 1 遺漏了數據,所以在此補充。

                               if (i == hold.size() - 1)

                               {

                                        dt.date = hold[i].date;

                                        dt.time = hold[i].time;

                                        tmp.push_back(dt);

                                        ++i;

                               }

                               // 記錄最大記錄個數

                               if (MAXNUM < tmp.size())

                               {

                                        MAXNUM = tmp.size();

                               }

                               cit->second = tmp;

                     }

                    

                     // 為了下一步輸出方便,對數據做一處理

                     map<string, string> namedate_time;

                     for (map<string, vector<date_time> >::const_iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               for (vector<date_time>::size_type i = 0; i != cit->second.size(); ++i)

                               {

                                        namedate_time[cit->first + cit->second[i].date] = cit->second[i].time;

                               }

                     }

                    

                     // 按照“人名-日期”進行輸出

                     fout_name_date /* << "XXXXXX" */ << '\t';

                     for (vector<string>::size_type i = 0; i != dates.size(); ++i)

                     {

                               fout_name_date << dates[i] << '\t';

                     }

                     fout_name_date << endl;

                    

                     for (vector<string>::size_type i = 0; i != names.size(); ++i)

                     {

                               fout_name_date << names[i] << '\t';

                               for (vector<string>::size_type j = 0; j != dates.size(); ++j)

                               {

                                        if (namedate_time.find(names[i] + dates[j]) != namedate_time.end())

                                        {

                                                 fout_name_date << namedate_time[names[i] + dates[j]] << '\t';

                                        }

                                        else

                                        {

                                                 fout_name_date /* << "XXXXXX" */ << '\t';

                                        }

                               }

                               fout_name_date << endl;

                     }

                    

                     // 按照“日期-人名”進行輸出

                     // 另一種角度可以將其看成是矩陣的轉置

                     fout_date_name /* << "XXXXXX" */ << '\t';

                     for (vector<string>::size_type i = 0; i != names.size(); ++i)

                     {

                               fout_date_name << names[i] << '\t';

                     }

                     fout_date_name << endl;

                    

                     for (vector<string>::size_type i = 0; i != dates.size(); ++i)

                     {

                               fout_date_name << dates[i] << '\t';

                               for (vector<string>::size_type j = 0; j != names.size(); ++j)

                               {

                                        if (namedate_time.find(names[j] + dates[i]) != namedate_time.end())

                                        {

                                                 fout_date_name << namedate_time[names[j] + dates[i]] << '\t';

                                        }

                                        else

                                        {

                                                 fout_date_name /* << "XXXXXX" */ << '\t';

                                        }

                               }

                               fout_date_name << endl;

                     }

             

                     fin_ci.close();

                     fout_name_date.close();

                     fout_date_name.close();

                     return 0;

            }

             

            四、對一些特殊人名、日期進行剔除的操作

                     打卡的記錄里可能存在節假日的記錄,這時需要將這些記錄剔除掉。另外,也可能因為某些原因,不考慮某些人的考勤的情況。所以,需要剔除某些指定的人名或日期的考勤打卡記錄。

                     在哪里剔除都可以,較為簡便的方法即是在輸入數據的時候,就就行篩選,剔除制定的人名或日期記錄。

                     這里只實現一個例子,其他方式也都是一樣的,只要在讀取數據的時候進行過濾即可。

                     這里剔除也可以是提取,不管怎樣就是去除不想要的記錄,得到想要的記錄。

                     程序實現如下:

            #include <iostream>

            #include <fstream>

            #include <sstream>

            #include <string>

            #include <map>

            #include <set>

            #include <vector>

            using namespace std;

             

            struct date_time

            {

                     string date;

                     string time;

            };

             

            int main()

            {

                     ifstream fin_ci("2-abnormal.txt");

                     ifstream fin_names("names-filter.txt");

                     ifstream fin_dates("dates-filter.txt");

                     ofstream fout_row("3-name-row-filter.txt");

                     ofstream fout_col("3-name-column-filter.txt");

                     if (!fin_ci || !fout_row || !fout_col)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     map<string, vector<date_time> > bypers;

                     vector<string> names;

                     string line, name;

                     date_time dt;

                     int MAXNUM = 0;

                     // 讀取想要的人名

                     set<string> names_filter;

                     while (fin_names >> name)

                     {

                               names_filter.insert(name);

                     }

                     // 讀取想要的日期

                     set<string> dates_filter;

                     while (fin_dates >> line)

                     {

                               dates_filter.insert(line);

                     }

                     while (getline(fin_ci, line))

                     {

                               istringstream sin(line);

                               sin >> name >> dt.date >> dt.time;

                               // 提取想要的人名和日期

                               if (names_filter.find(name) == names_filter.end() || dates_filter.find(dt.date) == dates_filter.end())

                               {

                                        continue;

                               }

                               bypers[name].push_back(dt);

                     }

                     // 同名字下相同日期的合并

                     for (map<string, vector<date_time> >::iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               // 提取名字

                               names.push_back(cit->first);

                              

                               vector<date_time> tmp, hold = cit->second;

                               vector<date_time>::size_type i = 0;

                               while (i < hold.size() - 1)

                               {

                                        if (hold[i].date == hold[i+1].date)

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time + hold[i + 1].time;

                                                 tmp.push_back(dt);

                                                 i += 2;

                                        }

                                        else

                                        {

                                                 dt.date = hold[i].date;

                                                 dt.time = hold[i].time;

                                                 tmp.push_back(dt);

                                                 ++i;

                                        }

                               }

                               // 最后兩個如果相等,那么 i 一下子回跳到 hold.size()

                               // 如果不相等,那么 i 變成 hold.size() - 1, 推出循環。

                               // 也就是說推出循環有兩種情況,分別是 i 為 hold.size() 和 hold.size() - 1

                               // i 為 hold.size() 的情況沒有遺漏記錄,i 為 hold.size() - 1 遺漏了數據,所以在此補充。

                               if (i == hold.size() - 1)

                               {

                                        dt.date = hold[i].date;

                                        dt.time = hold[i].time;

                                        tmp.push_back(dt);

                                        ++i;

                               }

                               // 記錄最大記錄個數

                               if (MAXNUM < tmp.size())

                               {

                                        MAXNUM = tmp.size();

                               }

                               cit->second = tmp;

                     }

                     // 按行輸出

                     for (map<string, vector<date_time> >::const_iterator cit = bypers.begin(); cit != bypers.end(); ++cit)

                     {

                               fout_row << cit->first << '\t';

                               for (vector<date_time>::size_type i = 0; i != cit->second.size(); ++i)

                               {

                                        fout_row << cit->second[i].date << '\t' << cit->second[i].time << '\t';

                               }

                               fout_row << endl;

                     }

                    

                     // 先輸出人名

                     for (vector<string>::size_type i = 0; i != names.size(); ++i)

                     {

                               fout_col << names[i] << '\t';

                     }

                     fout_col << endl;

                     // 按列輸出

                     for (int i = 0; i != MAXNUM; ++i)

                     {

                               for (vector<string>::size_type j = 0; j != names.size(); ++j)

                               {

                                        if (bypers[names[j]].size() > i)

                                        {

                                                 fout_col << bypers[names[j]][i].date << ',' << bypers[names[j]][i].time << '\t';

                                        }

                                        else

                                        {

                                                 fout_col /* << "XXXXXX" */ << '\t';

                                                 // 這里的輸出 "XXXXXX" 可以省略,即可以直接 fout_col << '\t';

                                        }

                               }

                               fout_col << endl;

                     }

                     fin_ci.close();

                     fout_row.close();

                     fout_col.close();

                     return 0;

            }

             

            五、總結

                     過去的做法:

            1.       從考勤記錄集合中找到遲到和早退的記錄;

            2.       針對這些遲到和早退的記錄,得到按日期分類的結果集合;

            3.       根據第2步的結果得到按照人名-日期的二維表,并且還得到按照人名分類的結果集合。

            過去處理這種程序的時候更為零落,一些細節處理的過于繁瑣,容易出錯。

                     這里處理的步驟如下:

            1.       篩選考勤記錄,得到最早和最晚下班時間;

            2.       按照規定的上班時間和下班時間得到遲到和早退的考勤記錄;

            3.       針對遲到和早退的考勤記錄,進行統計歸納,分為人名和日期兩個維度。另外輸出結果分別有按人名行輸出、按人名列輸出、按日期行輸出、按日期列輸出、人名-日期輸出、日期-人名輸出等。

            4.       針對特定的人名和日期得到剔除了節假日等情況下的考勤情況。

            另外,不區分進、出標識,因為這并沒有實際意義。打卡成功與失敗不在這里的處理范圍之內。

             

            六、附

            Excel 的格式問題:

                     Tab 健可以移位,針對NULL值不寫內容(“XXXXXX”)也可以。

            空格沒有移動功能。

             

            預處理:

                     這里處理過程中,最為關鍵的一部是按人名的時候,再按日期進行合并,或者按日期的時候再按人名進行合并。如何合并是一個算法上的問題,比如這樣的一個序列 1 2 2 3 3 3,我們想得到1個1、2個2、3個3,并且我們是嚴格要求同一天或同一個人的需要合并的。所以,需要進行一個排序。

                     一開始的時候對所有的打卡記錄進行排序,按照人名-日期-打卡時間的方式排序。

                     排序的預處理程序如下:

            #include <iostream>

            #include <fstream>

            #include <string>

            #include <vector>

            #include <algorithm>

            using namespace std;

             

            int main()

            {

                     ifstream fin("kaoqin.txt");

                     ofstream fout("0.txt");

                     if (!fin || !fout)

                     {

                               cerr << "File error!" << endl;

                               exit(1);

                     }

                     string line;

                     vector<string> kaoqin;

                     while (getline(fin, line))

                     {

                               kaoqin.push_back(line);

                     }

                     sort(kaoqin.begin(), kaoqin.end());

                     for (vector<string>::size_type i = 0; i != kaoqin.size(); ++i)

                     {

                               fout << kaoqin[i] << endl;

                     }

                     fin.close();

                     fout.close();

                     return 0;

            }

             

             

             


            posted on 2012-10-25 16:06 unixfy 閱讀(501) 評論(0)  編輯 收藏 引用
            久久久精品国产Sm最大网站| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲精品国产第一综合99久久| 久久人爽人人爽人人片AV| 久久精品女人天堂AV麻| 丁香狠狠色婷婷久久综合| 午夜精品久久久久久中宇| 久久亚洲国产成人影院| 精品欧美一区二区三区久久久| 国产美女久久久| 精品无码久久久久久午夜| 久久青青色综合| 色综合久久夜色精品国产| 久久这里只有精品视频99| 国产女人aaa级久久久级| 久久九九全国免费| 91精品国产91久久久久久蜜臀| 91精品婷婷国产综合久久| 老司机国内精品久久久久| 国产精品青草久久久久婷婷| 久久精品国产一区| 一本久久a久久精品综合夜夜| 久久综合欧美成人| segui久久国产精品| 久久强奷乱码老熟女| 欧美色综合久久久久久| 97香蕉久久夜色精品国产| 久久国产免费直播| 国内精品九九久久久精品| 色综合久久综精品| 久久久久一本毛久久久| 97视频久久久| 国产精品久久久久天天影视| 国产精品99久久久久久猫咪 | 亚洲一区中文字幕久久| 精品久久久久久国产| 久久精品中文字幕一区| 伊人久久大香线蕉亚洲| 久久99国产精一区二区三区| 久久久精品国产Sm最大网站| 亚洲午夜久久久影院伊人|