📄 flottery.cpp
字号:
// Flottery.cpp
//
#include "stdafx.h"
#include "Flottery.h"
// 初始化变量
Flottery::Flottery(int nTotalSel,int nToSel) : m_nTotalSelNum(nTotalSel),m_nToSelNum(nToSel)
{
m_nModNum = m_nTotalSelNum + 1;
m_bCareMax = FALSE;
m_bCareMin = FALSE;
m_bCareOdd = FALSE;
m_nOddNum = 0;
m_nMaxNum = 0;
m_nMinNum = 0;
}
Flottery::~Flottery()
{
}
// 加入必须要选的项目
void Flottery::BuildMustList(const int nNum)
{
if (nNum != 0)
{
POSITION pos = listMust.GetHeadPosition();
while (pos)
{
int nTemp = listMust.GetNext(pos);
if ( nNum == nTemp)//这个数再以前已经存在
{
return ;
}
}
listMust.AddTail(nNum);
}
return ;
}
// 加入必须要选的项目
void Flottery::BuildMustList( CString csMust)
{
int nLen = 0;
nLen = csMust.GetLength();
if (nLen == 0)
{
return;
}
int nNum = atoi(csMust.GetBuffer(nLen));
csMust.ReleaseBuffer();
if (nNum != 0)
{
POSITION pos = listMust.GetHeadPosition();
while (pos)
{
int nTemp = listMust.GetNext(pos);
if ( nNum == nTemp) // 这个数再以前已经存在
{
return ;
}
}
listMust.AddTail(nNum);
}
return ;
}
// 加入必须不要选的项目
void Flottery::BuildMustNotList(const int nNum)
{
if (nNum != 0)
{
POSITION pos = listMustNot.GetHeadPosition();
while (pos)
{
int nTemp = listMustNot.GetNext(pos);
if ( nNum == nTemp)//这个数再以前已经存在
{
return ;
}
}
listMustNot.AddTail(nNum);
}
return ;
}
// 加入必须不要选的项目
void Flottery::BuildMustNotList( CString csMustNot)
{
int nLen = 0;
nLen = csMustNot.GetLength();
if (nLen == 0)
{
return;
}
int nNum = atoi(csMustNot.GetBuffer(nLen));
csMustNot.ReleaseBuffer();
if (nNum != 0)
{
POSITION pos = listMustNot.GetHeadPosition();
while (pos)
{
int nTemp = listMustNot.GetNext(pos);
if ( nNum == nTemp)// 这个数再以前已经存在
{
return;
}
}
listMustNot.AddTail(nNum);
}
return;
}
// 开始选择
int Flottery::DoSelect(int nSortType)
{
static int nTimes = 0;
listTemp.RemoveAll();
// 判断listMust和listMustNot链表是否有重复的项目而且,
// listMust链表中的项不能多于要选择的项目,
if (listMust.GetCount() > m_nToSelNum)
{
return MUSTTOOMANY;
}
if (m_bCareOdd &&(m_nOddNum > m_nToSelNum))
{
return ODDTOOMANY;// 输入的奇数个数太多
}
POSITION posMust,posMustNot;
int nMustNotNum = 0;
int nTotalCanSel = m_nTotalSelNum;// 可以选择的数
int nMustNotOdd = 0;// mustnot链表中的奇数个数
posMustNot = listMustNot.GetHeadPosition();
while (posMustNot)
{
int nMustNot = listMustNot.GetNext(posMustNot);
if (m_bCareOdd)
{
if (nMustNot %2 == 1)
{
nMustNotOdd ++;// 必不选的奇数
}
}
if (m_bCareMax && m_bCareMin)
{
if ((nMustNot <= m_nMaxNum) && (nMustNot >= m_nMinNum))
nMustNotNum ++;
nTotalCanSel = m_nMaxNum - m_nMinNum + 1;
}
if (m_bCareMax && !m_bCareMin)
{
if (nMustNot <= m_nMaxNum)
nMustNotNum ++;
nTotalCanSel = m_nMaxNum;
}
if (!m_bCareMax && m_bCareMin)
{
if (nMustNot >= m_nMinNum)
nMustNotNum ++;
nTotalCanSel = m_nTotalSelNum - m_nMinNum +1;
}
}
// 两个链表是否冲突
int nMustOdd = 0;// must链表中的奇数项
posMust = listMust.GetHeadPosition();
while (posMust)
{
int nMust = listMust.GetNext(posMust);
if (nMust <= 0 || nMust > m_nTotalSelNum)
{
return ITEMERROR; // 链表中的元素不能小于 0 大于最大数
}
if (m_bCareMax)
{
if (nMust > m_nMaxNum)
{
return MUSTBIGGERMAX; // 必选项中的数字大于规定的最大数
}
}
if (m_bCareMin && (nMust < m_nMinNum))
{
return MUSTLESSMIN; // 必选项中的数字小于规定的最小数
}
posMustNot = listMustNot.GetHeadPosition();
while (posMustNot)
{
int nMustNot = listMustNot.GetNext(posMustNot);
if (nMust == nMustNot)
{
return TWOLISTCOLLIPSE;// 两个链表中存在相同项目
}
}
}
if ((nTotalCanSel - nMustNotNum ) < m_nToSelNum)
{
return MUSTNOTTOOMANY;
}
int nCount = listMust.GetCount();
int nNum = nCount > m_nToSelNum ? m_nToSelNum : nCount;
POSITION pos = listMust.GetHeadPosition();
// 把必选项加入结果链表
for (int i = 0 ; i< nNum ; i ++)
{
int nTemp = listMust.GetNext(pos);
if (nTemp % 2 == 1)
{
if (m_bCareOdd)
{
nMustOdd ++;
}
}
listTemp.AddTail(nTemp);
}
if (m_bCareMax)
{
if (m_nMaxNum > m_nTotalSelNum || m_nMaxNum < m_nToSelNum)
{
return MAXERROR;// 输入的最大数错误
}
if (m_bCareMin)
{
if (m_nMaxNum < m_nMinNum )
{
return MINBIGGERMAX;//最大数比最小数小
}
if (m_nMaxNum - m_nMinNum + 1 < m_nToSelNum)
{
return ERRANTOOLITTLE;//最大数和最小数区间太小
}
if (m_bCareOdd)
{
int nPad = 0;
if (m_nMinNum % 2 == 0)//偶数开头
{
nPad = 1;
}
else
{
nPad = 0;
}
// (m_nMaxNum - m_nMinNum + 1 + nPad)/2 表示偶数的个数
// (m_nMaxNum - m_nMinNum + 2 - nPad)/2表示奇数各个数
if (((m_nMaxNum - m_nMinNum + 1 + nPad) / 2 + m_nOddNum ) < m_nToSelNum)
{
return EVENTOOLITTLE;//最大数和最小数区间的偶数不足
}
if (((m_nMaxNum - m_nMinNum + 1 + nPad) / 2 + m_nOddNum) > m_nMaxNum)
{
return ODDTOOLITTLE;//最大数和最小数区间的奇数不足
}
if ((m_nOddNum + nMustNotOdd) > ((m_nMaxNum - m_nMinNum + 2 - nPad)/2))
{
return ODDTOOLITTLE;
}
}
}
}
m_nModNum = m_bCareMax?m_nMaxNum +1:m_nModNum ; // 设定模数
if (nMustOdd > m_nOddNum)
{
return MUSTODDTOOMANY;
}
// 产生随机数
CTime tCur = CTime::GetCurrentTime();
srand(tCur.GetTime() + (nTimes ++));
for ( i = 0; i < 100; i ++) // 尽量使得随机数的产生比较随机
{
srand(rand());
}
if (m_bCareOdd) // 如果要指定奇数个数、
{
for (i = 0 ; i < m_nOddNum-nMustOdd;i ++) // 产生奇数
{
int nTemp;
do{
nTemp = rand();
nTemp %= m_nModNum;
}while(!CheckValid(nTemp,1));
listTemp.AddTail(nTemp);
}
for (i = nNum; i < m_nToSelNum-m_nOddNum; i++)//产生偶数
{
int nTemp = 0;
do{
nTemp = rand();
nTemp %= m_nModNum;
}while(!CheckValid(nTemp,2));
listTemp.AddTail(nTemp);
}
}
else // 不指定奇数和偶数的个数。
{
for (i = 0; i < m_nToSelNum; i++) // 随机生成
{
int nTemp = 0;
do{
nTemp = rand();
nTemp %= m_nModNum;
}while(!CheckValid(nTemp));
listTemp.AddTail(nTemp);
}
}
// 排序
Sort(nSortType);
posResultList = listResult.GetHeadPosition();
return 0;
}
// 从结果链表得到一个结果
BOOL Flottery::GetNextInt(int &nVar)
{
if (posResultList)
{
nVar = listResult.GetNext(posResultList);
return TRUE;
}
return FALSE;
}
// 判断产生的数字是否合法,nType = 0 表示不关心奇数还是偶数。=1 表示是奇数 = 2表示是偶数
BOOL Flottery::CheckValid(int nNum,const int nType)
{
if (nNum == 0)
{
return FALSE;
}
if (nType == 1)// 奇数
{
if (nNum % 2 ==0)
{
return FALSE;
}
}
if (nType == 2)// 偶数
{
if (nNum % 2 == 1)
{
return FALSE;
}
}
if (m_bCareMax)
{
if (nNum > m_nMaxNum)
{
return FALSE;
}
}
if (m_bCareMin)
{
if (nNum < m_nMinNum)
{
return FALSE;
}
}
POSITION pos = listMustNot.GetHeadPosition();
while (pos)
{
int nTemp = listMustNot.GetNext(pos);
if (nNum == nTemp)
{
return FALSE;
}
}
pos = listTemp.GetHeadPosition();
while (pos)
{
int nTemp = listTemp.GetNext(pos);
if (nNum == nTemp)
{
return FALSE;
}
}
return TRUE;
}
// 对与随机生成的结果进行排序,nType == 0 时,从小到大排列。
void Flottery::Sort(int nType)
{
listResult.RemoveAll();
POSITION pos = listTemp.GetHeadPosition();
if (pos == NULL)
{
return;
}
int nTemp = listTemp.GetNext(pos);
listResult.AddHead(nTemp);
while (pos)
{
nTemp = listTemp.GetNext(pos);
POSITION posResult = listResult.GetHeadPosition();
POSITION posSub;
BOOL bFinish = FALSE;
while (posResult)
{
posSub = posResult;
int nTempResult = listResult.GetNext(posResult);
if (nType == 0)// 从小到大排列
{
if (nTemp < nTempResult)// 如果必元素小则加入
{
listResult.InsertBefore(posSub,nTemp);
bFinish = TRUE;
break;
}
}
else
{
if (nTemp > nTempResult)// 如果必元素小则加入
{
listResult.InsertBefore(posSub,nTemp);
bFinish = TRUE;
break;
}
}
}
if (!bFinish)
{
listResult.AddTail(nTemp);
}
}
pos = listResult.GetHeadPosition();
while (pos)
{
int nTemp = listResult.GetNext(pos);
TRACE("%d\n",nTemp);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -