www.gusucode.com > 一个VC++随机选号程序源码程序 > 一个VC++随机选号程序/Caipiao/Caipiao/Flottery.cpp

    /*==================================================================
=  文件名:彩票类实现文件                                           =  
=  主要功能:主要是完成彩票的选数的随机生成                         =
=  修改日期:2003-03-26                                             = 
=  作者:阿皮                                                       =
=  E_Mail:peijikui@sd365.com  QQ:122281932 msn:peijikui@sina.com   =  
====================================================================*/
#include "stdafx.h"
#include "Flottery.h"
//Download by http://www.codefans.net
Flottery::Flottery(int iTotalSel,int iToSel) : iTotalSelNum(iTotalSel),iToSelNum(iToSel)
{
	iModNum = iTotalSelNum + 1;
	bCareMax = FALSE;
	bCareMin = FALSE;
	bCareOdd = FALSE;
	iOddNum = 0;
	iMaxNum = 0;
	iMinNum = 0;
}
Flottery::~Flottery()
{
	
}
//加入必须要选的项目
void Flottery::BuildMustList(const int iNum)
{
	if(iNum != 0)
	{
		POSITION pos = listMust.GetHeadPosition();
		while(pos)
		{
			int iTemp = listMust.GetNext(pos);
			if( iNum == iTemp)//这个数再以前已经存在
				return ;
		}
		listMust.AddTail(iNum);
	}
	return ;
	
}
//加入必须要选的项目
void Flottery::BuildMustList( CString strMust)
{
	int iLen;
	iLen = strMust.GetLength();
	if(iLen == 0)
		return;
	int iNum = atoi(strMust.GetBuffer(iLen));
	strMust.ReleaseBuffer();
	if(iNum != 0)
	{
		POSITION pos = listMust.GetHeadPosition();
		while(pos)
		{
			int iTemp = listMust.GetNext(pos);
			if( iNum == iTemp)//这个数再以前已经存在
				return ;
		}
		listMust.AddTail(iNum);
	}
	return ;
}
//加入必须不要选的项目
void Flottery::BuildMustNotList(const int iNum)
{
	if(iNum != 0)
	{
		POSITION pos = listMustNot.GetHeadPosition();
		while(pos)
		{
			int iTemp = listMustNot.GetNext(pos);
			if( iNum == iTemp)//这个数再以前已经存在
				return ;
		}
		listMustNot.AddTail(iNum);
	}
	return ;
}
//加入必须不要选的项目
void Flottery::BuildMustNotList( CString strMustNot)
{
	int iLen;
	iLen = strMustNot.GetLength();
	if(iLen == 0)
		return;
	int iNum = atoi(strMustNot.GetBuffer(iLen));
	strMustNot.ReleaseBuffer();
	if(iNum != 0)
	{
		POSITION pos = listMustNot.GetHeadPosition();
		while(pos)
		{
			int iTemp = listMustNot.GetNext(pos);
			if( iNum == iTemp)//这个数再以前已经存在
				return;
		}
		listMustNot.AddTail(iNum);
	}
	return;

}
//开始选择
int Flottery::DoSelect(int iSortType)
{
	static int iTimes = 0;
	listTemp.RemoveAll();
	//判断listMust和listMustNot链表是否有重复的项目而且,listMust链表中的项不能多于要选择的项目,
	if(listMust.GetCount() > iToSelNum)
		return MUSTTOOMANY;
	if(bCareOdd &&(iOddNum > iToSelNum))
	{
		return ODDTOOMANY;//输入的奇数个数太多

	}

	POSITION posMust,posMustNot;
	int iMustNotNum = 0;
	int iTotalCanSel = iTotalSelNum;//可以选择的数
	int iMustNotOdd = 0;//mustnot链表中的奇数个数
	posMustNot = listMustNot.GetHeadPosition();
	while(posMustNot)
	{
		int iMustNot = listMustNot.GetNext(posMustNot);
	
		if(bCareOdd)
		{
			if(iMustNot %2 == 1)
				iMustNotOdd ++;//必不选的奇数
		}
		if(bCareMax && bCareMin)
		{
			if((iMustNot <= iMaxNum) && (iMustNot >= iMinNum))
				iMustNotNum ++;
			iTotalCanSel = iMaxNum - iMinNum + 1;
			
		}
		if(bCareMax && !bCareMin)
		{
			if(iMustNot <= iMaxNum)
				iMustNotNum ++;
			iTotalCanSel = iMaxNum;
		}
		if(!bCareMax && bCareMin)
		{
			if(iMustNot >= iMinNum)
				iMustNotNum ++;
			iTotalCanSel = iTotalSelNum - iMinNum +1;
		}
	}
		
	//两个链表是否冲突
	int iMustOdd = 0;//must链表中的奇数项
	posMust = listMust.GetHeadPosition();
	while(posMust)
	{
		int iMust = listMust.GetNext(posMust);
	
		if(iMust <= 0 || iMust > iTotalSelNum)
			return ITEMERROR;//链表中的元素不能小于 0 大于最大数
		if(bCareMax)
			if(iMust > iMaxNum)
				return MUSTBIGGERMAX;//必选项中的数字大于规定的最大数
		if(bCareMin && (iMust < iMinNum))
			return MUSTLESSMIN;//必选项中的数字小于规定的最小数

		posMustNot = listMustNot.GetHeadPosition();
		while(posMustNot)
		{
			int iMustNot = listMustNot.GetNext(posMustNot);
			if(iMust == iMustNot)
				return TWOLISTCOLLIPSE;//两个链表中存在相同项目
		}
	}
	if((iTotalCanSel - iMustNotNum ) <  iToSelNum)
		return MUSTNOTTOOMANY;
	int iCount = listMust.GetCount();
 	int iNum = iCount > iToSelNum ? iToSelNum : iCount;
	POSITION pos = listMust.GetHeadPosition();
	//把必选项加入结果链表
	for(int i = 0 ; i< iNum ; i ++)//把已经选择的项目加入结果链表中
	{
		int iTemp = listMust.GetNext(pos);
		if(iTemp % 2 == 1)
		{
			if(bCareOdd)
			{
				iMustOdd ++;
				
			}
		}
		listTemp.AddTail(iTemp);
	}
	if(bCareMax)
	{
		if(iMaxNum > iTotalSelNum || iMaxNum < iToSelNum)
			return MAXERROR;//输入的最大数错误
		if(bCareMin)
		{
			
			if(iMaxNum < iMinNum )
				return MINBIGGERMAX;//最大数比最小数小
			if(iMaxNum - iMinNum + 1 < iToSelNum)
				return ERRANTOOLITTLE;//最大数和最小数区间太小
			if(bCareOdd)
			{
				int iPad = 0;
				if(iMinNum % 2 == 0)//偶数开头
					iPad = 1;
				else
					iPad = 0;
				//程序说明:iMaxNum - iMinNum + 1 + iPad) /2 表示偶数的个数
				//(iMaxNum - iMinNum + 2 - iPad)/2表示奇数各个数
				if(((iMaxNum - iMinNum + 1 + iPad) / 2 + iOddNum ) < iToSelNum)
					return EVENTOOLITTLE;//最大数和最小数区间的偶数不足
				if(((iMaxNum - iMinNum + 1 + iPad) / 2 + iOddNum) > iMaxNum)
					return ODDTOOLITTLE;//最大数和最小数区间的奇数不足
				if((iOddNum + iMustNotOdd) > ((iMaxNum - iMinNum + 2 - iPad)/2))
					return ODDTOOLITTLE;
			}	
		}
	}

	iModNum = bCareMax?iMaxNum +1:iModNum ;//设定模数
	if(iMustOdd > iOddNum)
		return MUSTODDTOOMANY;
	//产生随机数
	CTime tCur = CTime::GetCurrentTime();
	srand(tCur.GetTime() + (iTimes ++));
	for( i = 0; i < 100; i ++)//尽量使得随机数的产生比较随机
		srand(rand());
	if(bCareOdd)//如果要指定奇数个数、
	{
		for(i = 0 ; i < iOddNum-iMustOdd;i ++)//产生奇数
		{
			int iTemp;
			do{
				iTemp = rand();
				iTemp %= iModNum;
			}while(!CheckValid(iTemp,1));
			listTemp.AddTail(iTemp);
		}
		
		for(i = iNum; i < iToSelNum-iOddNum; i++)//产生偶数
		{
			int iTemp ;
			do{
				iTemp = rand();
				iTemp %= iModNum;
			}while(!CheckValid(iTemp,2));
			listTemp.AddTail(iTemp);

		}
	}
	else//不指定奇数和偶数的个数。
	{
		for(i = 0; i < iToSelNum; i++)//随机生成
		{
			int iTemp ;
			do{
				iTemp = rand();
				iTemp %= iModNum;
			}while(!CheckValid(iTemp));
			listTemp.AddTail(iTemp);

		}
	}

	Sort(iSortType);//排序
	posResultList = listResult.GetHeadPosition();
	return 0;
}
//从结果链表得到一个结果
BOOL Flottery::GetNextInt(int &iVar)
{
	
	if(posResultList)
	{
		iVar = listResult.GetNext(posResultList);
		return TRUE;
	}
	return FALSE;
}
//判断生成的一项是否合法
BOOL Flottery::CheckValid(int iNum,const int iType)
{
	if(iNum == 0)
		return FALSE;
	if(iType == 1)//奇数
	{
		if(iNum % 2 ==0)
			return FALSE;
	}
	if(iType == 2)//偶数
	{
		if(iNum % 2 == 1)
			return FALSE;
	}
	if(bCareMax)
	{
		if(iNum > iMaxNum)
			return FALSE;
	}
	if(bCareMin)
	{
		if(iNum < iMinNum)
			return FALSE;
	}
	POSITION pos = listMustNot.GetHeadPosition();
	while(pos)
	{
		int iTemp = listMustNot.GetNext(pos);
		if(iNum == iTemp)
			return FALSE;
	}
	pos = listTemp.GetHeadPosition();
	while(pos)
	{
		int iTemp = listTemp.GetNext(pos);
		if(iNum == iTemp)
			return FALSE;
	}
	return TRUE;

}
//对与随机生成的结果进行排序
void Flottery::Sort(int iType)
{
	listResult.RemoveAll();

	POSITION pos = listTemp.GetHeadPosition();
	if(pos == NULL)
		return;
	int iTemp = listTemp.GetNext(pos);
	listResult.AddHead(iTemp);
	while(pos)
	{
		iTemp = listTemp.GetNext(pos);
		POSITION posResult = listResult.GetHeadPosition();
		POSITION posSub;
		BOOL bFinish = FALSE;
		while(posResult)
		{
			posSub = posResult;
			int iTempResult = listResult.GetNext(posResult);
			if(iType == 0)//从小到大排列
			{
				if(iTemp < iTempResult)//如果必元素小则加入
				{
					listResult.InsertBefore(posSub,iTemp);
					bFinish = TRUE;
					break;
				}
			}
			else
			{
				if(iTemp > iTempResult)//如果必元素小则加入
				{
					listResult.InsertBefore(posSub,iTemp);
					bFinish = TRUE;
					break;
				}

			}
		}
		if(!bFinish)
			listResult.AddTail(iTemp);
		
	}

	pos = listResult.GetHeadPosition();
	while(pos)
	{
		int iTemp = listResult.GetNext(pos);
		TRACE("%d\n",iTemp);
	}
	return;
}