微信红包算法,拆分最大的红包法

我的算法是,通过不断拆分最大的红包,完成所有红包金额的分配。

先把总金额存入红包列表中,然后开始。

第一步:从列表中找出已分配的红包中最大的红包金额,通过随机数将这个红包金额拆分成两个金额,然后保存在红包列表中。

第二步:继续第一步,直到红包拆分完毕。

为了方便运算,金额统一转换为分,输出结果时再转换回元和分。

头文件:

#pragma onceconst unsigned int g_unMaxMoney = 10000 * 100;	// 最大允许发10000元红包class CSendRadPacket
{
public:CSendRadPacket();~CSendRadPacket();bool CalRadPacket(unsigned int unYuan, unsigned int unFen, unsigned int unCount);void PrintRadPacket();protected:unsigned int GetMaxNum();void SaveMoney(unsigned int unNum);protected:unsigned int *m_pPackeData;		// 保存计算好的每一个红包金额unsigned int m_unPacketCount;	// 红包数量unsigned int m_unAllMoney;		// 红包总金额
};

cpp代码:

#include "stdafx.h"
#include "CSendRadPacket.h"
#include 
#include using namespace std;CSendRadPacket::CSendRadPacket() :m_pPackeData(nullptr),m_unPacketCount(0),m_unAllMoney(0)
{
}CSendRadPacket::~CSendRadPacket()
{if (nullptr == m_pPackeData){delete[] m_pPackeData;m_pPackeData = nullptr;}
}bool CSendRadPacket::CalRadPacket(unsigned int unYuan, unsigned int unFen, unsigned int unCount)
{// 先把总金额转换成分。红包数量少于1,返回;总金额数小于红包数,返回;超过最大红包值,返回。unsigned int unMoney = unYuan * 100 + unFen;bool bRes = ((unCount < 1) || (unMoney < unCount) || (unMoney > g_unMaxMoney) || (unFen > 99));if (bRes){return false;}if (nullptr != m_pPackeData){delete[] m_pPackeData;m_pPackeData = nullptr;}m_pPackeData = new unsigned int[unCount];if (nullptr == m_pPackeData){return false;}memset(m_pPackeData, 0, sizeof(int) * unCount);m_pPackeData[0] = unMoney;m_unPacketCount = unCount;m_unAllMoney = unMoney;for (unsigned int unIndex = 0; unIndex < unCount - 1; ++unIndex){unsigned int unMaxMoney = GetMaxNum();unsigned int nRandom = ((rand() + rand()) << 16) + rand() + rand();unsigned int unLeft = nRandom % unMaxMoney;	// 有余数为0的可能unsigned int unRight = unMaxMoney - unLeft;// 如果遇到 nLeft 或 nRight 有一个为0的情况,需要再分配一次if (0 == unLeft || 0 == unRight){--unIndex;}//如果遇到 nLeft 或 nRight 有一个为0的情况,还需要将 nLeft 或 nRight 重新存一遍。// 因为 GetMaxNum() 函数取出最大值后,会将列表中的最大值置为0SaveMoney(unLeft);SaveMoney(unRight);}return true;
}void CSendRadPacket::PrintRadPacket()
{if (m_unPacketCount < 1){return;}cout << endl;cout << "红包总金额:" << m_unAllMoney / 100 << "." << setfill('0') << setw(2) << m_unAllMoney % 100 << endl;cout << "红包个数:" << m_unPacketCount << endl;unsigned int unMaxMoney = 0;unsigned int unMinMoney = -1;for (unsigned int unIndex = 0; unIndex < m_unPacketCount; ++unIndex){unsigned int unNum = m_pPackeData[unIndex];cout << unNum / 100 << "." << setfill('0') << setw(2) << unNum % 100 << "  ";if (unNum > unMaxMoney){unMaxMoney = unNum;}if (unNum < unMinMoney){unMinMoney = unNum;}}cout << endl;cout << "最大的红包是:" << unMaxMoney / 100 << "." << setfill('0') << setw(2) << unMaxMoney % 100 << "  " << endl;cout << "最小的红包是:" << unMinMoney / 100 << "." << setfill('0') << setw(2) << unMinMoney % 100 << "  " << endl;
}unsigned int CSendRadPacket::GetMaxNum()
{unsigned int unMaxIndex = 0;for (unsigned int unIndex = 1; unIndex < m_unPacketCount; ++unIndex){if (m_pPackeData[unIndex] > m_pPackeData[unMaxIndex]){unMaxIndex = unIndex;}if (0 == m_pPackeData[unIndex]){break;}}unsigned int unMaxNum = m_pPackeData[unMaxIndex];m_pPackeData[unMaxIndex] = 0;return unMaxNum;
}void CSendRadPacket::SaveMoney(unsigned int unNum)
{for (unsigned int unIndex = 0; unIndex < m_unPacketCount; ++unIndex){if (0 == m_pPackeData[unIndex]){m_pPackeData[unIndex] = unNum;break;}}
}

主函数:

void main()
{unique_ptr oPacket(new CSendRadPacket);
	oPacket->CalRadPacket(0, 99, 1);
	oPacket->PrintRadPacket();
	oPacket->CalRadPacket(1, 0, 2);
	oPacket->PrintRadPacket();oPacket->CalRadPacket(0, 5, 5);oPacket->PrintRadPacket();oPacket->CalRadPacket(0, 8, 7);oPacket->PrintRadPacket();oPacket->CalRadPacket(1, 0, 7);oPacket->PrintRadPacket();oPacket->CalRadPacket(5, 20, 7);oPacket->PrintRadPacket();oPacket->CalRadPacket(10, 0, 10);oPacket->PrintRadPacket();oPacket->CalRadPacket(520, 0, 10);oPacket->PrintRadPacket();oPacket->CalRadPacket(1000, 0, 10);oPacket->PrintRadPacket();oPacket->CalRadPacket(8888, 88, 9);oPacket->PrintRadPacket();
}

执行结果:



从多次运行的结果来看,红包金额分布的状况和微信红包差不多。并且从我的算法来看,不存在第几个红包为最大红包的概率最大。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部