STL之map常用功能

 

#include <string.h>
#include <map>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

map<long,Number> num;


/**
 * 用分隔符解析字符串
 */
void splitToArray(const std::string &src, const std::string &sep, std::vector<std::string> &destArray, bool filtEmpty = false)
{
	if (src.empty())
	{
		return;
	}

	std::string::size_type posBegin = 0;
	std::string::size_type posEnd   = src.find(sep);
	std::string value;
	while (posEnd != std::string::npos)
	{
		value = src.substr(posBegin, posEnd - posBegin);
		if (!(filtEmpty && value.empty()))
		{
			destArray.push_back(value);
		}
		posBegin = posEnd + 1;
		posEnd = src.find(sep, posBegin);
	}

	value = src.substr(posBegin, src.size() - posBegin);
	if (!(filtEmpty && value.empty()))
	{
		destArray.push_back(value);
	}
}

/**
 * 号码解析:把文件中读取到的一条号码记录解析成一个结构体
 */
RET_ERRORCODE parseNumber(const char* record, Number& number)
{
	if ((NULL == record) || (strlen(record) == 0))
	{
		return E001;
	}

	std::string numberRecord(record);
	std::vector<std::string> recordArray;

	std::string::size_type posBegin = 0;
	std::string::size_type posEnd   = numberRecord.find("\r\n");

	//去掉回车换行
	if (posEnd != std::string::npos)
	{
		numberRecord = numberRecord.substr(0, posEnd);
	}
	else
	{
		//去掉换号
		posEnd = numberRecord.find("\n");
		if (posEnd != std::string::npos)
		{
			numberRecord = numberRecord.substr(0, posEnd);
		}
	}

	//获取|分隔符分割的数据
	splitToArray(numberRecord, "|", recordArray);
    
	//合法数据只有6个字段
	if (recordArray.size() != 6)
	{
		return E004;
	}
	
	strcpy_s(number.id, recordArray[0].c_str());
	number.price = (float)atof(recordArray[1].c_str());
	strcpy_s(number.brand, recordArray[2].c_str());
	number.status = atoi(recordArray[3].c_str());
	strcpy_s(number.customer, recordArray[4].c_str());
	number.time   = atoi(recordArray[5].c_str());
	
	return E001;
}
long tolong(const char *p)
{
	int i;
	long r=0;
	for (i = 0; i < 11; i++)
	{
		r += p[i] - 48;
		r = r * 10;
	}
	return r;
}
/**
 * 初始化:使用初始化指令让系统重新完成初始化,各条记录(如号码记录)清空,时间状态初始化等。
 */
RET_ERRORCODE initSys()
{
	num.clear();
	initTimeSeconds();
	return E001;
}

/**
 * 加载号码:读取numbers.txt格式的数据文件,加载所有号码信息到系统中。
 */
RET_ERRORCODE loadNumbers(const char* fileName)
{
	if (fileName[0] == 0)
		return E002;
	ifstream infile(fileName);
	RET_ERRORCODE ret;
	if (!infile.is_open())
	{
		return E003;
	}
	Number tem;
	string s;
	while (getline(infile, s))
	{
		ret=parseNumber(s.data(),tem);
		if (ret == E004)
		{
			infile.close();
			return E004;
		}
		num[tolong(tem.id)] = tem;
	}
	infile.close();             //关闭文件输入流 
	return E001;
}

/**
 * 查询:号码信息查询。
 */
RET_ERRORCODE queryNumber(const Number& number, Number numbers[], int& count)
{
	int i = 0,j = 0;
	int numsize = num.size();
	int *tem=new int[numsize]();
	map<long, Number>::iterator it;
	if (number.id[0] == 0)
		;
	else
	{
		for (i = 0,it=num.begin(); i < numsize&&it!=num.end(); i++,it++)
			if (strcmp(number.id, it->second.id) != 0)
				tem[i] = 1;
	}
	if (number.price == 0)
		;
	else
	{
		for (i = 0, it = num.begin(); i < numsize&&it != num.end(); i++, it++)
			if(number.price != it->second.price)
				tem[i] = 1;
	}
	if (number.time == 0)
		;
	else
	{
		for (i = 0, it = num.begin(); i < numsize&&it != num.end(); i++, it++)
			if (number.time != it->second.time)
				tem[i] = 1;
	}
	if (number.status == 0)
		;
	else
	{
		for (i = 0, it = num.begin(); i < numsize&&it != num.end(); i++, it++)
			if (number.status != it->second.status)
				tem[i] = 1;
	}
	if (number.brand[0] == 0)
		;
	else
	{
		for (i = 0, it = num.begin(); i < numsize&&it != num.end(); i++, it++)
			if (strcmp(number.brand, it->second.brand) != 0)
				tem[i] = 1;
	}
	for (i = 0,it=num.begin(); i < numsize && j< count; i++,it++)
		if (tem[i] == 0)
			numbers[j++] = it->second;
	count = j;
	delete[] tem;
	return E001;
}

/**
 * 随机选号:根据品牌,随机选取未被预定的号码,供客户选择
 */
RET_ERRORCODE randomPick(const char* brand, const int randNumber, Number number[], int& count)
{
	Number serch;
	int j = 0;
	serch.id[0] = 0;
	serch.price = 0;
	strcpy(serch.brand, brand);
	serch.time = 0;
	Number *tem=new Number[count];
	queryNumber(serch, tem, count);
	for (int i = 0; i < count && j<randNumber; i++)
	{
		if (tem[i].status == 0)
			number[j++] = tem[i];
	}
	count = j;
	delete[] tem;
	return E001;
}
void findbra(const char* brand, Number number[], int& count)
{
	int i = 0, j = 0;
	int numsize = num.size();
	int *tem = new int[numsize]();
	map<long, Number>::iterator it;
	for (i = 0, it = num.begin(); i < numsize&&it != num.end(); i++, it++)
		if (strcmp(brand, it->second.brand) != 0)
			tem[i] = 1;
	for (i = 0, it = num.begin(); i < numsize && j < count; i++, it++)
		if (tem[i] == 0)
			number[j++] = it->second;
	count = j;
	delete[] tem;
}
/**
 * 自助选号:根据选号表达式,返回满足条件的未被预定的号码列表
 */
RET_ERRORCODE selfServicePick(const char* brand, const char* expression1, const char* expression2, Number number[], int& count)
{
	char s;
	int i = 0, k = 0;
	Number *t = new Number[num.size()];
	findbra(brand, number, count);
	if (expression1[0] == 0)
		;
	else
	{
		for (i = 0; i < count; i++)
			for (k = 0; k < 11; k++)
				if (expression1[k] != number[i].id[k] && expression1[k] != '*')
					t[i] = number[i];
	}
	if (expression2[0] == 0)
		;
	else
	{
		std::string numberRecord(expression2);
		std::vector<std::string> recordArray;
		splitToArray(numberRecord, "!", recordArray, true);
		for (int j = 0; j < recordArray.size(); j++)
		{
			s = recordArray[j][0];
			for (i = 0; i < count; i++)
				if (s == number[i].id[10])
					t[i] = number[i];
		}
	}
	for (k = 0,i = 0; i < count; i++)
		if (t[i].id[0] == 0)
			number[k++] = t[i];
	count = k;
	delete[] t;
	return E001;
}

/**
 * 锁定:根据号码信息,对号码资源进行锁定(预定)。
 */
RET_ERRORCODE lockNumber(const Number& number)
{	
	map<long, Number>::iterator it;
	it = num.find(tolong(number.id));
	if (it == num.end())
		return E007;
	if (it->second.status == 1)
		return E005;
	it->second.status = 1;
	it->second.time = getCurrentTimeSeconds() + ONE_DAY_SECONDS;
	return E001;
}

/**
 * 解锁:根据时间对预定号码到期时间未处理的号码资源进行解锁,供其他客户选择。
 */
RET_ERRORCODE unLockNumber()
{
	map<long, Number>::iterator it;
	for (it = num.begin(); it != num.end(); it++)
		if (it->second.time  < getCurrentTimeSeconds())
		{
			it->second.customer[0] = 0;
			it->second.status = 0;
			it->second.time = 0;
		}
	return E001;
}


void selfServiceTerminal_TestCase()
{
	//1 系统初始化
	RET_ERRORCODE ret = initSys();
	assert(ret ==  E001);

    //2 正常号码加载
	ret = loadNumbers("../output/template/numbers.txt");
	assert(ret == E001);

	//3 文件名校验
	ret = loadNumbers("");
	assert(ret == E002);

	//4 号码格式校验
	ret = loadNumbers("../output/template/numbers_err.txt");
	assert(ret == E004);
	ret = loadNumbers("../output/template/numbers_rep.txt");
	assert(ret == E001);
	//5 号码查询/重复检验
	Number inNumber;
	strcpy_s(inNumber.id, "13900000168");
	Number number[10];
	int numberCount = 10;
	ret = queryNumber(inNumber, number, numberCount);
	assert(ret == E001);
	assert(numberCount == 1);
	assert(number[0].price == 500);

	//6 随机选号
	int randNumber = 3;
	Number selectNumber[10];
	int selectNumberCount = 10;
	ret = randomPick("2", randNumber, selectNumber, selectNumberCount);
	assert(ret == E001);
	assert(selectNumberCount == 3);

	//7 自助选号规则
	Number selfNumber[10];
	int selfNumberCount = 10;
	ret = selfServicePick("2", "", "", selfNumber, selfNumberCount);
	assert(ret == E001);
	assert(selfNumberCount == 4);
		
	//8 自助选号规则
	ret = selfServicePick("2", "**7********", "!3!4", selfNumber, selfNumberCount);
	assert(ret == E001);
	assert(selfNumberCount == 2);

	//9 锁定号码
	ret = lockNumber(inNumber);
	assert(ret == E001);

	numberCount = 10;
	inNumber.status = 1;
	ret = queryNumber(inNumber, number, numberCount);
	assert(ret == E001);
	assert(numberCount == 1);
	assert(number[0].status == 1);
	assert(number[0].time == ONE_DAY_SECONDS);

	//10 解锁预约号码
	ret = initSys();
	assert(ret == E001);

	ret = loadNumbers("../output/template/numbers_unlock.txt");
	assert(ret == E001);

	//系统时间调整
	elapseTimeSeconds(86400);
	
	ret = unLockNumber();
	assert(ret == E001);

	inNumber.id[0]    = 0;
	inNumber.status   = 0;
	inNumber.brand[0] = 0;
	numberCount       = 10;
	
	ret = queryNumber(inNumber, number, numberCount);
	assert(ret == E001);
	assert(numberCount == 1);
	for (int i = 0; i < numberCount; ++i)
	{
		assert(number[i].status == 0);
		assert(number[i].time   == 0);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值