德州扑克-面对五重循环算法该如何优化?

      最近在做德州扑克项目,写到从7张牌中选择5张最优组合牌时,翻看了旧项目的代码,发现居然有人写出了五重循环算法,如图

-- //最大牌型
function GameLogic:FiveFromSeven( cbHandCardData, cbCenterCardData,cbCardCount)
-- //临时变量
local cbTempCardData={}
local cbLastCardData={}
-- //拷贝数据s
cbTempCardData=mytools.clone(cbHandCardData)
self:ArrayConcat(cbTempCardData,cbCenterCardData)
-- //排列扑克
self:SortCardList(cbTempCardData,#cbTempCardData);
-- -- //组合算法
for i=1,3 do
for j= i+1,4 do
for k = j+1,5 do
for l =k+1,6 do
for m=l+1,7 do
local cbTempLastCardData={}
-- //获取数据
cbTempLastCardData[1]=cbTempCardData[i];
cbTempLastCardData[2]=cbTempCardData[j];
cbTempLastCardData[3]=cbTempCardData[k];
cbTempLastCardData[4]=cbTempCardData[l];
cbTempLastCardData[5]=cbTempCardData[m];
-- //获取牌型
-- //牌型大小
if #cbLastCardData>0 then
if(self:CompareCard(cbLastCardData,cbTempLastCardData)==1)then
cbLastCardData= mytools.clone(cbTempLastCardData)
end
else
cbLastCardData= mytools.clone(cbTempLastCardData)
end
end
end
end
end
end

return cbLastCardData
end

以前也有发现过有人写出了5重循环的算法,不过不是自己的项目不好挑刺。这其实也是新手,或者是10年重复了一年经验的10年老手也会经常写出这种代码,一点都不出奇,如果没受过基础算法训练,或者见过类似写法的代码,还真有点难度。

      上面的算法有几个毛病,超过3重的循环是大忌,第二如果有需求是10个里面选择7个呢?还得改代码。如果是100选5呢?你会发现这算法已经改不下去了?要改动的算法稳定性就会变差!真正好用的算法,应该是通用的,通过传参就能达到需求应变的,这样才是合格的算法。

        写棋牌算法,我可以说是驾轻就熟,我尝试改写一下,我要以两种方式实现它,一种是递归,一种是非递归,且看非递归算法

-- //最大牌型
function GameLogic:FiveFromSeven2( cbHandCardData, cbCenterCardData,cbCardCount)
-- //临时变量
local cbTempCardData={}
local cbLastCardData={}
-- //拷贝数据s
cbTempCardData=mytools.clone(cbHandCardData)
self:ArrayConcat(cbTempCardData,cbCenterCardData)
-- //排列扑克
self:SortCardList(cbTempCardData,#cbTempCardData);

local cbIndex = {}
for j = 1, cbCardCount do
table.insert(cbIndex,j)
end
while(true) do
local cbTempLastCardData={}
-- //获取数据
for j = 1, #cbIndex do
table.insert(cbTempLastCardData,cbTempCardData[cbIndex[j]])
end
-- //获取牌型
-- //牌型大小
if #cbLastCardData>0 then
if(self:CompareCard(cbLastCardData,cbTempLastCardData)==1)then
cbLastCardData= mytools.clone(cbTempLastCardData)
end
else
cbLastCardData= mytools.clone(cbTempLastCardData)
end

if (cbIndex[cbCardCount] == #cbTempCardData) then
local index = cbCardCount
for i = cbCardCount, 2, -1 do
if ((cbIndex[i - 1] + 1) ~= cbIndex[i]) then
local cbNewIndex = cbIndex[i - 1]
for j = (i - 1), cbCardCount do
cbIndex[j] = cbNewIndex + j - i + 2
end
break
end
index = index - 1
end
if (index == 1) then
break
end
else
cbIndex[cbCardCount] = cbIndex[cbCardCount] + 1
end
end

return cbLastCardData
end

且看关键算法部分,代码行数大家相当,但是这种写法,在需要从100个选5时,也不需要改代码了,就只需要你传递参数来确定就可以了,可逻辑上不说明,一般人还是不太好理解,不像第一种直观一些。它的逻辑是这样的,七张牌

{0x32, 0x33,0x22, 0x12, 0x13, 0x23, 0x37}

循环1:【1】【2】【3】【4】【5】

循环2:【1】【2】【3】【4】【6】

循环3:【1】【2】【3】【4】【7】

循环4:【1】【2】【3】【5】【6】

循环5:【1】【2】【3】【5】【7】

。。。。。。。

相信你运行调试一下就明白了。

第二种递归算法:

function  GameLogic:Combination( cbCombineCardData,  cbResComLen,   cbResultCardData, cbSrcCardData ,  cbCombineLen1,  cbSrcLen,  cbCombineLen2)

if( cbResComLen == cbCombineLen2 )then
local cbResCardLen=#cbResultCardData+1
cbResultCardData[cbResCardLen]={}
for i = 1, cbResComLen do
cbResultCardData[cbResCardLen][i]= cbCombineCardData[i]
end
else

if(cbCombineLen1 >= 1 and cbSrcLen > 0 and (cbSrcLen+1) >= 0 )then
cbCombineCardData[cbCombineLen2-cbCombineLen1+1] = cbSrcCardData[cbSrcLen];
cbResComLen =cbResComLen+1
self:Combination(cbCombineCardData,cbResComLen, cbResultCardData, cbSrcCardData,cbCombineLen1-1, cbSrcLen-1, cbCombineLen2);

cbResComLen=cbResComLen-1
self:Combination(cbCombineCardData,cbResComLen, cbResultCardData, cbSrcCardData,cbCombineLen1, cbSrcLen-1, cbCombineLen2);
end
end
end

-- //最大牌型
function GameLogic:FiveFromSeven3( cbHandCardData, cbCenterCardData,cbCardCount)
-- //临时变量
local cbTempCardData={}
local cbLastCardData={}
-- //拷贝数据s
cbTempCardData=mytools.clone(cbHandCardData)
self:ArrayConcat(cbTempCardData,cbCenterCardData)
-- //排列扑克
self:SortCardList(cbTempCardData,#cbTempCardData);
-- //对牌组合
local cbComCard = {}
local cbComResCard = {}
local cbComResLen = 0
self:Combination( cbComCard, 0, cbComResCard, cbTempCardData,cbCardCount,#cbTempCardData,cbCardCount)
for i = 1, #cbComResCard do
-- //保存对牌
-- //牌型大小
if #cbLastCardData>0 then
if(self:CompareCard(cbLastCardData,cbComResCard[i])==1)then
cbLastCardData= mytools.clone(cbComResCard[i])
end
else
cbLastCardData= mytools.clone(cbComResCard[i])
end

end
return cbLastCardData
end

这种逻辑上也直观简单,最后得出结果集时,再进行比较,这种写法有点损耗效率,当你真正有性能瓶颈时,可以把结果放在递归里面去处理。这样的写法,在有需求100选5时,也不需要改动代码,也能达到应用上的需求,但他有一个缺点,就是如果是数目巨大,递归过深,程序会崩掉。这个也是它的局限性,所以用这个你要预见到你的项目需求。

那么这三种的效率pk呢?在7选5的情况下,我们看看运行结果

德州扑克-面对五重循环算法该如何优化?

第一种效率相对低一些,第二种和第三种不相上下。

       到了这里大家都明白了,第一种你没有理由选择它,但是它又是程序员最容易写出来的东西,有时为了项目稳定,它会长期存在。我更加倾向于使用第二种,因为第二种不存在递归的弱点,有的人会选择第三种,因为有时递归在表达一些东西时代码会更加简洁,看各人思维了。

还有更加好写法的欢迎拍砖,秋:460000713

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

德州扑克-面对五重循环算法该如何优化?

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 德州扑克-面对五重循环算法该如何优化?
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏