最近没啥活,其他人都很忙,在赶版本,虽然现在还在加班,不过四个校招生,就我没有单子。也不知道为什么。闲来无事,看到代码中有个计数管理类,原理很简单,但是如果不进行封装,每次使用将变得很麻烦。学着写一写。
原理:通过不同的ID来标识不同的计数对象,每个计数对象使用map保存,键就是ID,值就是对应的技术对象。技术对象应当包含的基本机构,有时间戳,计算数目,类型。针对于判断时间的部分,比如每天累加、每月累加那些地方,暂时使用简单的比较,即以每天24点清零重新计数。以简化整体代码。
头文件:CounterManager.h
#include <map>
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
/*********************************************
**brief:看到公司代码有个计数管理类,其实原理很简单
** 但是就是进行了封装,使用较为方便。大家都有
** 活,我闲来无事,自己写写。
**********************************************/
enum ConType
{
CHANGE_NONE = 0,
CHANGE_DAY = 1,
CHANGE_WEEK = 2,
CHANGE_MON = 3,
CHANGE_YEAR = 4,
CHANGE_HOUR = 5,
};
class Con
{
public:
int getCounterNum(){ return iCounterNum; }
int getCounterType(){ return iCounterType; }
void addCounter(int iNum, int iType);
time_t *getTimestr() { return ×tr; }
private:
int iCounterNum;
int iCounterType;
time_t timestr;
};
class Counter
{
private:
std::map<int, Con*> mapCounter;
public:
void save();
void load();
int getCounterNum(const int iTypeId);
int getMapCounterSize();
void insertCon(const int id, const int iNum, const int iType);
void addCounterNumByNone(const int iTypeId, const int iNum = 1);
void addCounterNumByDay(const int iTypeId, const int iNum = 1);
void addCounterNumByWeek(const int iTypeId, const int iNum = 1);
void addCounterNumByMon(const int iTypeId, const int iNum = 1);
void addCounterNumByYear(const int iTypeId, const int iNum = 1);
void addCounterNumByHour(const int iTypeId, const int iNum = 1);
};
实现文件:CounterManage.cpp
#include "CounterManager.h"
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
#include <time.h>
const string strFileName("C:\\Desktop\\a.txt");
/******************************************************
** brief:现在对于时间的处理都是使用的最简单的方
** 式,比如隔天累加,只是简单的判断是否后一天。
** 但是实际的情况是,从这一刻开始的24小时之后才算。
******************************************************/
std::string intTostring(int id)
{
std::stringstream oss;
oss << id;
return oss.str();
}
std::string ConToString(Con *id)
{
std::stringstream oss;
oss << id->getCounterNum();
oss << "|";
oss << id->getCounterType();
oss << "|";
oss << id->getTimestr();
return oss.str();
}
long int subTwoTime(time_t &t1, time_t &t2)
{
long int time1 = 0, time2 = 0;
std::string strtime1, strtime2;
char tchar1[64] = { 0 };
char tchar2[64] = { 0 };
ctime_s(tchar1, 63, &t1);
ctime_s(tchar2, 63, &t2);
strtime1 = tchar1;
strtime2 = tchar2;
for (int i = strtime1.size() - 1; i >= 0; --i)
{
int c = strtime1[i] - '0';
if (c < 0 || c > 9)
{
cout << "error : strTime change intTime error" << endl;
return -1;
}
for (int j = i; j > 0; --j)
c *= 10;
time1 += c;
}
for (int i = strtime2.size() - 1; i >= 0; --i)
{
int c = strtime2[i] - '0';
if (c < 0 || c > 9)
{
cout << "error : strTime change intTime error" << endl;
return -1;
}
for (int j = i; j > 0; --j)
c *= 10;
time2 += c;
}
return time1 - time2;
}
void Con::addCounter(int iNum, int iType)
{
iCounterNum += iNum;
time_t se;
se = time(NULL);
timestr = se;
iCounterType = iType;
//cout << "iType:" << iType << endl;
}
int Counter::getCounterNum(const int id)
{
for (std::map<int, Con*>::iterator it = mapCounter.begin(); it != mapCounter.end(); ++it)
{
if (it->first == id)
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if (CHANGE_NONE == it->second->getCounterType())
{
return it->second->getCounterNum();
}
else if (CHANGE_DAY == it->second->getCounterType())
{
if ((tm_cur->tm_year == tm_ago->tm_year && (tm_cur->tm_mday != tm_ago->tm_mday )) && ((subTwoTime(se, *(it->second->getTimestr())) > 0) && (subTwoTime(se, *(it->second->getTimestr())) < 24 * 60 * 60)))
{
return it->second->getCounterNum();
}
}
else if (CHANGE_WEEK == it->second->getCounterType())
{
if (tm_cur->tm_year == tm_ago->tm_year)
{
if (tm_cur->tm_yday - tm_ago->tm_yday == (7 - 1))
return it->second->getCounterNum();
}
else if (tm_cur->tm_year - tm_ago->tm_year == 1)
{
if (tm_cur->tm_yday + (31 - tm_ago->tm_mday) == (7 - 1))
return it->second->getCounterNum();
}
}
else if (CHANGE_MON == it->second->getCounterType())
{
if (tm_cur->tm_year == tm_ago->tm_year)
{
return tm_cur->tm_mon - tm_ago->tm_mon == 1 ? it->second->getCounterNum() : 0;
}
else if (tm_cur->tm_year - tm_ago->tm_year == 1)
{
return (tm_cur->tm_mon == 1 && tm_ago->tm_mon == 12) ? it->second->getCounterNum() : 0;
}
}
else if (CHANGE_YEAR == it->second->getCounterType())
{
return tm_cur->tm_year - tm_ago->tm_year == 1 ? it->second->getCounterNum() : 0;
}
else if (CHANGE_HOUR == it->second->getCounterType())
{
if (subTwoTime(se, *(it->second->getTimestr())) > 60 && (subTwoTime(se, *(it->second->getTimestr())) < 2 * 60))
return it->second->getCounterNum();
}
else
cout << "error : getCounterNum error,iType error" << endl;
return 1; //能进入循环证明有值,所以最低返回1
}
}
return 0;
}
int Counter::getMapCounterSize()
{
return mapCounter.size();
}
void Counter::insertCon(const int id, const int iNum, const int iType)
{
Con *co = new Con();
co->addCounter(iNum, iType);
mapCounter[id] = co;
//cout << mapCounter[id]->getCounterType() << "--" << mapCounter[id]->getCounterNum() << "--" << mapCounter[id]->getTimestr() << endl;
}
void Counter::addCounterNumByNone(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_NONE);
}
else
it->second->addCounter(iNum, CHANGE_NONE);
}
void Counter::addCounterNumByDay(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_DAY);
}
else
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if(tm_cur->tm_year == tm_ago->tm_year && (tm_cur->tm_yday - tm_ago->tm_yday == 1))
{
it->second->addCounter(iNum, CHANGE_DAY);
}
else if (tm_cur->tm_year - tm_ago->tm_year == 1)
{
if (tm_cur->tm_mon == 1 && (tm_ago->tm_mon == 12) && (tm_cur->tm_mday == 31) && (tm_ago->tm_mday == 1))
{
it->second->addCounter(iNum, CHANGE_DAY);
}
}
else
it->second->addCounter(1, CHANGE_DAY);
}
}
void Counter::addCounterNumByWeek(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_WEEK);
}
else
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if (tm_cur->tm_year == tm_ago->tm_year)
{
if (tm_cur->tm_yday - tm_ago->tm_yday == (7 - 1))
{
it->second->addCounter(iNum, CHANGE_WEEK);
}
}
else if (tm_cur->tm_year - tm_ago->tm_year == 1)
{
if (tm_cur->tm_yday + (31 - tm_ago->tm_mday) == (7 - 1))
{
it->second->addCounter(iNum, CHANGE_WEEK);
}
}
else
it->second->addCounter(1, CHANGE_WEEK);
}
}
void Counter::addCounterNumByMon(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_MON);
}
else
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if (tm_cur->tm_year == tm_ago->tm_year && (tm_cur->tm_mon - tm_ago->tm_mon == 1))
{
it->second->addCounter(iNum, CHANGE_MON);
}
else if (tm_cur->tm_year - tm_ago->tm_year == 1 && (tm_cur->tm_mon == 1 && (tm_ago->tm_mon == 12)))
{
it->second->addCounter(iNum, CHANGE_MON);
}
else
it->second->addCounter(1, CHANGE_MON);
}
}
void Counter::addCounterNumByYear(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_YEAR);
}
else
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if (tm_cur->tm_year - tm_ago->tm_year == 1)
{
it->second->addCounter(iNum, CHANGE_YEAR);
}
else
it->second->addCounter(1, CHANGE_YEAR);
}
}
void Counter::addCounterNumByHour(const int id, const int iNum)
{
std::map<int, Con*>::iterator it = mapCounter.find(id);
if (it == mapCounter.end())
{
insertCon(id, iNum, CHANGE_HOUR);
}
else
{
time_t se = time((time_t *)NULL);
struct tm *tm_cur = new tm();
gmtime_s(tm_cur, &se);// (&se);
struct tm *tm_ago = new tm();
gmtime_s(tm_ago, it->second->getTimestr());
if (subTwoTime(se, *(it->second->getTimestr())) > 60 && (subTwoTime(se, *(it->second->getTimestr())) < 2 * 60))
{
it->second->addCounter(iNum, CHANGE_HOUR);
}
else
it->second->addCounter(1, CHANGE_HOUR);
}
}
测试文件:
#include "CounterManager.h"
int main()
{
Counter con;
cout << con.getCounterNum(10) << endl;
con.addCounterNumByNone(10, 5); //没有规则,仅仅累加
cout << con.getCounterNum(10) << endl;
cout << con.getCounterNum(13) << endl;
cout << con.getCounterNum(13) << endl;
con.addCounterNumByDay(11);
cout << con.getCounterNum(11) << endl;
con.addCounterNumByDay(11);
cout << con.getCounterNum(11) << endl;
}