• <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 閱讀(505) 評論(0)  編輯 收藏 引用
            99久久精品国产毛片| avtt天堂网久久精品| 久久精品成人影院| 人妻丰满?V无码久久不卡| 欧美精品九九99久久在观看| 偷偷做久久久久网站| 日日躁夜夜躁狠狠久久AV| 久久99国产精品久久| 亚洲国产成人久久综合碰| 青草国产精品久久久久久| 国产国产成人久久精品| 久久精品国产亚洲av麻豆蜜芽 | 久久成人18免费网站| 久久丝袜精品中文字幕| jizzjizz国产精品久久| 97视频久久久| 久久亚洲国产成人影院网站| 乱亲女H秽乱长久久久| 久久久久亚洲AV综合波多野结衣| 亚洲国产另类久久久精品黑人| 狠狠久久综合伊人不卡| 国产亚洲欧美精品久久久| 四虎影视久久久免费观看| 93精91精品国产综合久久香蕉 | 久久久久久久久久久久中文字幕| 色偷偷888欧美精品久久久| 99久久国产综合精品女同图片| 久久91精品综合国产首页| 久久线看观看精品香蕉国产| 狠狠色婷婷久久一区二区 | 内射无码专区久久亚洲| 久久99国产亚洲高清观看首页| 少妇内射兰兰久久| 久久天天躁狠狠躁夜夜不卡| 怡红院日本一道日本久久| 久久99精品久久久久久久不卡| 亚洲va久久久噜噜噜久久狠狠| 久久精品免费一区二区| 亚洲午夜久久久久久噜噜噜| av色综合久久天堂av色综合在| 久久99这里只有精品国产|