<pre name="code" class="cpp">// workOrderDemo.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; #include <stdio.h> #include <stdlib.h> #include <iomanip> #include <assert.h> #include <vector> #include <fstream> #include <assert.h> #include <string> #define EQUAL '=' #define SPACE ' ' #define STARBAR '*' typedef unsigned int UINT32; #define MAX_NAME_LEN 100 //最大名字长度 #define MAX_SPAN_LEN 9 //间隔字符长度 #define MAX_WEEKS_CNT 52 //365/7 或者366/7 周数 #define MAX_CYC_WEEK_CNT 6 //最大循环次数 #define MAX_MONTH_CNTS_IN_YEAR 12 //1年的月份数 #define THIS_YEAR 2015 //当前的年份 const char* pszOutFile = "E:\\WorkTable.txt"; ofstream g_fOutFile(pszOutFile); //打开文件用于写,若文件不存在就创建它 //星期序列 typedef enum WEEK_DAY { MONDAY = 0, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATUDAY, SUNDAY, MAX_WORK_DAYS //计数用 }WEEKDAY; //值班检验师名称 typedef enum INSPECTOR_YANTAI { WANG_XIN_PING = 0, FU_TIAN = 1, ZHAO_JI_JUAN = 2, //0 ZHAO_YU_XIANG, ZHANG_XIA, WANG_XIAO_FEI, ZHU_HONG_JING, MAX_INSPECTOR_CNT //计数用 }INSPECTOR; //值班类型 typedef enum WORK_TYPES { NIGHT_WORK = 0, //夜班 AFTER_NIGHT_WORK, //起夜 SLEEP, //休息 URGENT_DIAGNOSE, //急诊 URGENT_WORK, //急值 URGENT_DIAGNOSE_AFTERNON, //急诊午 WORK_CNTS //7 计数用 }WORK_TYPE; char g_pszInspectorArr[MAX_INSPECTOR_CNT][MAX_NAME_LEN] = {"王*平", "付*明", "赵*娟", "赵*香", "张*玉", "王*飞", "朱*静"}; char g_workTypeName[WORK_CNTS][MAX_NAME_LEN] = {"夜班", "起夜", "休息", "急诊", "急值", "急诊午" }; char g_weekDayName[MAX_WORK_DAYS][MAX_NAME_LEN] = {"周一", "周二", "周三", "周四", "周五", "周六", "周日"}; //临时存储 WORK_TYPE g_TmpDayWork[MAX_WORK_DAYS] = {NIGHT_WORK}; WORK_TYPE g_WeekWorkTable[MAX_INSPECTOR_CNT][MAX_WORK_DAYS] = {NIGHT_WORK}; WORK_TYPE g_WeekWorkTableBak[MAX_INSPECTOR_CNT][MAX_WORK_DAYS] = {NIGHT_WORK}; //基准表,1月份的永恒不变 //存储格式化日期格式 vector<char* > g_DaysVector; /* **@brief:打印字符格式化用 **@param:ch字符, num个数 **@return:空. */ void print_n_char(char ch , int num) { int count = 0; for (count = 0 ; count < num ; count++) { cout << ch; g_fOutFile << SPACE; } } /* **@brief:根据年月日返回星期几 **@param:UINT32 iYear 年, UINT32 iMonth 月, UINT32 iDay 日 **@return: 星期几. */ int ReturnWeekDay(UINT32 iYear, UINT32 iMonth, UINT32 iDay) { int iWeek = 0; UINT32 y = 0, c = 0, m = 0, d = 0; if ( iMonth == 1 || iMonth == 2 ) { c = ( iYear - 1 ) / 100; y = ( iYear - 1 ) % 100; m = iMonth + 12; d = iDay; } else { c = iYear / 100; y = iYear % 100; m = iMonth; d = iDay; } iWeek = y + y / 4 + c / 4 - 2 * c + 26 * ( m + 1 ) / 10 + d - 1; //蔡勒公式 iWeek = iWeek >= 0 ? ( iWeek % 7 ) : ( iWeek % 7 + 7 ); //iWeek为负时取模 if ( iWeek == 0 ) //星期日不作为一周的第一天 { iWeek = 7; } return iWeek; } /* **@brief:返回月份 **@param:格式化的串 **@return: 月 */ int GetMonthFromStr(char* pszStr) { string strTmp(pszStr); size_t iEnd = strTmp.find_first_of("月"); size_t iBegin = 0; string strMonth = strTmp.substr(iBegin, iEnd); //cout << "strMonth = " << strMonth << endl; int iMonth = atoi(strMonth.c_str()); //cout << "iMonth = " << iMonth << endl; assert(iMonth >= 1 && iMonth <= 12); return iMonth; } /* **@brief:返回天 **@param:格式化的串 **@return: 天 */ int GetDayFromStr(char* pszStr) { string strTmp(pszStr); size_t iBegin = 2 + strTmp.find_first_of("月"); size_t iEnd = strTmp.find_first_of("日"); //cout << "iBegin = " << iBegin << "\t iEnd = " << iEnd << endl; assert(iEnd > iBegin); string strDay = strTmp.substr(iBegin, iEnd - iBegin); //cout << "strDay = " << strDay << endl; int iDay = atoi(strDay.c_str()); //cout << "iDay = " << iDay << endl; assert(iDay >= 1 && iDay <= 31); return iDay; } /* **@brief:返回格式化周几 **@param:int iWeekDay 星期几 **@return: 格式化周几. */ char* GetWeekName(int iWeekDay) { assert(iWeekDay > 0); return g_weekDayName[iWeekDay - 1]; } /* **@brief:初始化基准工作表,以5月11号一周为基准(设定为1月1日) **@param:空 **@return:无 */ void InitWorkTableBakFun() { //0 WANG_XIN_PING g_WeekWorkTableBak[WANG_XIN_PING][MONDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[WANG_XIN_PING][TUESDAY] = URGENT_WORK; g_WeekWorkTableBak[WANG_XIN_PING][WEDNESDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[WANG_XIN_PING][THURSDAY] = NIGHT_WORK; g_WeekWorkTableBak[WANG_XIN_PING][FRIDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[WANG_XIN_PING][SATUDAY] = SLEEP; g_WeekWorkTableBak[WANG_XIN_PING][SUNDAY] = SLEEP; //1 FU_TIAN g_WeekWorkTableBak[FU_TIAN][MONDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[FU_TIAN][TUESDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[FU_TIAN][WEDNESDAY] = SLEEP; g_WeekWorkTableBak[FU_TIAN][THURSDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[FU_TIAN][FRIDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[FU_TIAN][SATUDAY] = SLEEP; g_WeekWorkTableBak[FU_TIAN][SUNDAY] = URGENT_DIAGNOSE; //2 ZHAO_JI_JUAN g_WeekWorkTableBak[ZHAO_JI_JUAN][MONDAY] = NIGHT_WORK; g_WeekWorkTableBak[ZHAO_JI_JUAN][TUESDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[ZHAO_JI_JUAN][WEDNESDAY] = SLEEP; g_WeekWorkTableBak[ZHAO_JI_JUAN][THURSDAY] = SLEEP; g_WeekWorkTableBak[ZHAO_JI_JUAN][FRIDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[ZHAO_JI_JUAN][SATUDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[ZHAO_JI_JUAN][SUNDAY] = NIGHT_WORK; //3 ZHAO_YU_XIANG g_WeekWorkTableBak[ZHAO_YU_XIANG][MONDAY] = URGENT_WORK; g_WeekWorkTableBak[ZHAO_YU_XIANG][TUESDAY] = NIGHT_WORK; g_WeekWorkTableBak[ZHAO_YU_XIANG][WEDNESDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[ZHAO_YU_XIANG][THURSDAY] = SLEEP; g_WeekWorkTableBak[ZHAO_YU_XIANG][FRIDAY] = URGENT_WORK; g_WeekWorkTableBak[ZHAO_YU_XIANG][SATUDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[ZHAO_YU_XIANG][SUNDAY] = SLEEP; //4 ZHANG_XIA g_WeekWorkTableBak[ZHANG_XIA][MONDAY] = SLEEP; g_WeekWorkTableBak[ZHANG_XIA][TUESDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[ZHANG_XIA][WEDNESDAY] = NIGHT_WORK; g_WeekWorkTableBak[ZHANG_XIA][THURSDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[ZHANG_XIA][FRIDAY] = SLEEP; g_WeekWorkTableBak[ZHANG_XIA][SATUDAY] = URGENT_WORK; g_WeekWorkTableBak[ZHANG_XIA][SUNDAY] = URGENT_WORK; //5 WANG_XIAO_FEI g_WeekWorkTableBak[WANG_XIAO_FEI][MONDAY] = SLEEP; g_WeekWorkTableBak[WANG_XIAO_FEI][TUESDAY] = SLEEP; g_WeekWorkTableBak[WANG_XIAO_FEI][WEDNESDAY] = URGENT_WORK; g_WeekWorkTableBak[WANG_XIAO_FEI][THURSDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[WANG_XIAO_FEI][FRIDAY] = NIGHT_WORK; g_WeekWorkTableBak[WANG_XIAO_FEI][SATUDAY] = AFTER_NIGHT_WORK; g_WeekWorkTableBak[WANG_XIAO_FEI][SUNDAY] = URGENT_DIAGNOSE_AFTERNON; //6 ZHU_HONG_JING g_WeekWorkTableBak[ZHU_HONG_JING][MONDAY] = SLEEP; g_WeekWorkTableBak[ZHU_HONG_JING][TUESDAY] = SLEEP; g_WeekWorkTableBak[ZHU_HONG_JING][WEDNESDAY] = URGENT_DIAGNOSE; g_WeekWorkTableBak[ZHU_HONG_JING][THURSDAY] = URGENT_WORK; g_WeekWorkTableBak[ZHU_HONG_JING][FRIDAY] = URGENT_DIAGNOSE_AFTERNON; g_WeekWorkTableBak[ZHU_HONG_JING][SATUDAY] = NIGHT_WORK; g_WeekWorkTableBak[ZHU_HONG_JING][SUNDAY] = AFTER_NIGHT_WORK; } /* **@brief:判定年份是否为闰年. **@param: iYear当前年份. **@return:true,闰年; false,平年. */ bool IsLeapYear(UINT32 iYear) { if ( (iYear%4 == 0 && iYear%100 != 0) || (iYear%400 == 0) ) { return true; } else { return false; } } /* **@brief:获取一年的总天数 **@param:iYear当前年份 **@return:无 */ int GetTotalDaysCnt(int iYear) { int iTotalDaysCnt = 0; if (IsLeapYear(iYear)) { iTotalDaysCnt = 366; } else { iTotalDaysCnt = 365; } return iTotalDaysCnt; } /* **@brief:初始化工作表(与基准表一致) **@param:空 **@return:无 */ void InitWorkTableFun() { //与基准对齐 for (int inspector = 0; inspector < MAX_INSPECTOR_CNT; ++inspector) { for (int curDay = 0; curDay < MAX_WORK_DAYS; ++curDay) { g_WeekWorkTable[inspector][curDay] = g_WeekWorkTableBak[inspector][curDay]; } } } /* **@brief: 返回vector数组中的起始位置,打印用 **@param: nCurWeek 当前第几周 **@return:返回pos */ int GetBeginOfDaysVector(UINT32 nCurWeek) { //获取第几周的日期格式 //如第一周返回:1月1, 1月2, ... 1月7 assert(nCurWeek >= 0 && nCurWeek <= 1 + MAX_WEEKS_CNT); int iBegin = (nCurWeek - 1) * 7; return iBegin; } /* **@brief: 打印对应周的排班表 **@param: iWeek 当前第几周 **@return:无 */ void PrintCurWorkTable(int iWeek) { char szTmpFormat[MAX_NAME_LEN] = {0}; vector<int> weekVector; #if 0 for (int curDay = 0; curDay < 1 + MAX_WORK_DAYS; ++curDay) { if (0 == curDay) { cout << std::right << std::setw(MAX_SPAN_LEN) << ""; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << ""; } else { cout << std::right << std::setw(MAX_SPAN_LEN) << g_weekDayName[curDay - 1]; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << g_weekDayName[curDay - 1]; } } cout << endl; g_fOutFile << endl; #endif int nDaysOfYear = 0; //打印日期第几周 格式:1-1 int iBegin = 0; int iWeekLen = 7; if (iWeek <= MAX_WEEKS_CNT) { iBegin = 4 + GetBeginOfDaysVector(iWeek); cout << std::right << std::setw(MAX_SPAN_LEN) << ""; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << ""; for (int i = iBegin; i < iBegin + iWeekLen; ++i) { if (i >= GetTotalDaysCnt(THIS_YEAR) - 1) { break; } cout << std::right << std::setw(MAX_SPAN_LEN) << g_DaysVector[i]; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << g_DaysVector[i]; //new add by ycy 2015-6-6 pm 20:09 int iMonth = GetMonthFromStr(g_DaysVector[i]); int iDay = GetDayFromStr(g_DaysVector[i]); int iWeekDay = ReturnWeekDay(THIS_YEAR, iMonth, iDay); //cout << iWeekDay; weekVector.push_back(iWeekDay); } cout << endl; g_fOutFile << endl; } else { if (IsLeapYear(THIS_YEAR)) { nDaysOfYear = 366; } else { nDaysOfYear = 365; } //最后一周单独处理 iWeekLen = nDaysOfYear - (MAX_WEEKS_CNT)*7; iBegin = GetBeginOfDaysVector(1 + MAX_WEEKS_CNT); for (int i = iBegin; i < iBegin + iWeekLen; ++i) { cout << std::right << std::setw(MAX_SPAN_LEN) << g_DaysVector[i]; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << g_DaysVector[i]; } cout << endl; g_fOutFile << endl; } int iWeekSize = weekVector.size(); // assert(iWeekSize == 7); for (int curDay = 0; curDay < 1 + iWeekSize; ++curDay) { if (0 == curDay) { cout << std::right << std::setw(MAX_SPAN_LEN) << ""; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << ""; } else { int iCurWeek = weekVector[curDay - 1]; cout << std::right << std::setw(MAX_SPAN_LEN) << g_weekDayName[iCurWeek - 1]; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << g_weekDayName[iCurWeek - 1]; } } cout << endl; g_fOutFile << endl; for (int curDay = 0; curDay < 1 + MAX_WORK_DAYS; ++curDay) { if (0 == curDay) { cout << std::right << std::setw(MAX_SPAN_LEN) << ""; //g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << ""; } for (int j = 0; j < MAX_SPAN_LEN - 1; ++j) { cout << '-'; //g_fOutFile << ' '; } } cout << endl; //g_fOutFile << endl; int curWorkType = 0; for (int inspector = 0; inspector < MAX_INSPECTOR_CNT; ++inspector) { sprintf_s(szTmpFormat , "%d%s", inspector, g_pszInspectorArr[inspector]); cout << std::left << std::setw(MAX_SPAN_LEN) << szTmpFormat; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN) << szTmpFormat; for (int curDay = 0; curDay < MAX_WORK_DAYS; ++curDay) { curWorkType = (int)(g_WeekWorkTable[inspector][curDay]); cout << std::right << std::setw(MAX_SPAN_LEN)<< g_workTypeName[curWorkType]; g_fOutFile << std::right << std::setw(MAX_SPAN_LEN)<< g_workTypeName[curWorkType]; } cout << endl; g_fOutFile << endl; } } /* **@brief: 测试打印日期格式 **@param: 空 **@return:无 */ void testWeekDayOfData() { int iYear = 2015; int iMonth = 6; int iDay = 1; for (iDay = 1; iDay <= 30; ++iDay) { int iWeekDay = ReturnWeekDay(iYear, iMonth, iDay); cout << iWeekDay << GetWeekName(iWeekDay) << "\t"; if (iDay % 7 == 0) { cout << endl; } } } /* **@brief: 以基准周为依据按照规律排班 **@param: nWeek当前第几周 **@return:无 */ void ExchangeWork(UINT32 nWeek) { assert(nWeek >= 0 && nWeek <= MAX_INSPECTOR_CNT - 2); //0-5之间 //0 第1周不变: 排班顺序 0 1 2 3 4 5 6; //1 第2周: 排班顺序 0 1 3 4 5 6 2; //2 第3周: 排班顺序 0 1 4 5 6 2 3; //3 第4周: 排班顺序 0 1 5 6 2 3 4; //4 第5周: 排班顺序 0 1 6 2 3 4 5; 循环终止 //5 第6周: 排班顺序 0 1 2 3 4 5 6; 同第一周 //每次都从基准周变更 if (0 == nWeek) { (void)InitWorkTableFun(); } else { (void)InitWorkTableFun(); //1-6 6个人,第0行始终不变无需再排班 for (int iInspector = 2; iInspector < MAX_INSPECTOR_CNT ; ++iInspector) { int iNewOrder = iInspector + nWeek; if (iNewOrder > (MAX_INSPECTOR_CNT - 1)) { iNewOrder = (iInspector + nWeek) % (MAX_INSPECTOR_CNT - 2); } if (0 == iNewOrder) { iNewOrder = 5; } //cout << "iNewOrder = " << iNewOrder << endl; assert(iNewOrder == 3 || iNewOrder == 4 || iNewOrder == 5 || iNewOrder == 6 || iNewOrder == 2); //周一到周日 for (int curDay = 0; curDay < MAX_WORK_DAYS; ++curDay) //0-6 7天 { if (2 == iInspector) { g_TmpDayWork[curDay] = g_WeekWorkTable[nWeek][curDay]; // } g_WeekWorkTable[iInspector][curDay] = g_WeekWorkTableBak[iNewOrder][curDay]; }//end for curDay }//end for iInspector }//end else } /* **@brief: 全年中第几周的排班表 **@param: nWeek当前全年的第几周 **@return:无 */ void CurWeekWorkOrder(UINT32 nWeek) { assert(nWeek <= MAX_WEEKS_CNT); //全年周转化为规律周 UINT32 nOrderWeek = nWeek % (MAX_INSPECTOR_CNT - 2); assert(nOrderWeek >= 0 && nOrderWeek < (MAX_INSPECTOR_CNT - 2)); //cout << "nWeek = " << nWeek << "nOrderWeek = " << nOrderWeek << endl; (void)ExchangeWork(nOrderWeek); } /* **@brief:判定某年某月的天数. **@param: iYear当前年份,iMonth当前月份; **@return:当前年、月的天数. */ unsigned int daysInMonth(UINT32 nYear, UINT32 nMonth) { assert(nMonth >=1 && nMonth <= MAX_MONTH_CNTS_IN_YEAR); int nDaysInMonth = 0; switch(nMonth) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: nDaysInMonth = 31; break; case 4: case 6: case 9: case 11: nDaysInMonth = 30; break; case 2: if (IsLeapYear(nYear)) { nDaysInMonth = 29; } else { nDaysInMonth = 28; } break; default: cout << "Error Month!!" << endl; break; } return nDaysInMonth; } /* **@brief:构建格式化日期 **@param: nYear 当年年份 **@return:无 */ void BuildDayOfMonth(UINT32 nYear) { UINT32 nDaysOfYear = 0; if (IsLeapYear(nYear)) { nDaysOfYear = 366; } else { nDaysOfYear = 365; } for (int iMonth = 1; iMonth <= MAX_MONTH_CNTS_IN_YEAR; ++iMonth) { for (int iDay = 1; iDay <= (int)(daysInMonth(nYear, iMonth)); ++iDay) { char *pszDataFormat = (char*)malloc(20); memset(pszDataFormat, 0, 20); sprintf_s(pszDataFormat, 20, "%d月%d日", iMonth, iDay); //cout << pszDataFormat << "\t"; g_DaysVector.push_back(pszDataFormat); }//end for iDay //cout << endl; }//end for iMonth } /* **@brief:释放内存 **@param: 空 **@return:无 */ void ReleaseDaysVector() { int iVectorSize = g_DaysVector.size(); //cout << "iVectorSize = " << iVectorSize << endl; for (int i = 0; i < iVectorSize; ++i) { if (NULL != g_DaysVector[i]) { free(g_DaysVector[i]); g_DaysVector[i] = NULL; } } } /* **@brief:测试打印全年日期格式 **@param: 当前年份 **@return:无 */ void testPrintDaysByWeek(UINT32 nYear) { int iWeekLen = 7; //每周七天 int nDaysOfYear = 0; if (IsLeapYear(nYear)) { nDaysOfYear = 366; } else { nDaysOfYear = 365; } cout << endl; int iBegin = 0; for (int iWeek = 1; iWeek <= MAX_WEEKS_CNT; ++iWeek) { iBegin = GetBeginOfDaysVector(iWeek); for (int i = iBegin; i < iBegin + iWeekLen; ++i) { cout << g_DaysVector[i] << "\t"; } cout << endl; } //最后一周单独处理 iWeekLen = nDaysOfYear - (MAX_WEEKS_CNT)*7; iBegin = GetBeginOfDaysVector(1 + MAX_WEEKS_CNT); for (int i = iBegin; i < iBegin + iWeekLen; ++i) { cout << g_DaysVector[i] << "\t"; } cout << endl; } void testPrintVectorDays() { int iVectorSize = g_DaysVector.size(); //cout << "iVectorSize = " << iVectorSize << endl; for (int i = 0; i < iVectorSize; ++i) { cout << g_DaysVector[i] << "\t"; } } int _tmain(int argc, _TCHAR* argv[]) { (void)InitWorkTableBakFun(); //基准初始化 (void)BuildDayOfMonth(THIS_YEAR); //(void)testPrintDaysByWeek(THIS_YEAR); //初始化写文件 if (!g_fOutFile) { cout << "Open file" << pszOutFile << "Failed!" << endl; } char szDateFormat[128] = {0}; //打印全年排班表 for(int iWeek = 1; iWeek <= MAX_WEEKS_CNT; ++iWeek) { print_n_char(STARBAR, 28); sprintf_s(szDateFormat, " %d 年 第 %d 周", THIS_YEAR, iWeek); cout << szDateFormat; g_fOutFile << szDateFormat; print_n_char(STARBAR, 28); cout << endl; g_fOutFile << endl; //逐月份排班 (void)CurWeekWorkOrder(iWeek - 1); (void)PrintCurWorkTable(iWeek); cout << endl << endl; g_fOutFile << endl << endl; } (void)ReleaseDaysVector(); g_fOutFile.close(); getchar(); return 0; }
2015-6-6 pm18:09 思于家中床前,耗时9h
作者:铭毅天下
转载请标明出处,原文地址:http://blog.csdn.net/laoyang360/article/details/46390293
如果感觉本文对您有帮助,请点击‘顶’支持一下,您的支持是我坚持写作最大的动力,谢谢!