我正在尝试使用一副52张牌生成4张牌的所有组合。生成所有排列将很容易(和长),但在卡片中,顺序无关紧要,所以例如Ah,Kh,Qh,Jh将与Kh,Ah,Qh,Jh相同。有人能指出我正确的方向或向我展示一些我可以使用的示例代码吗?发现很奇怪,之前没人试过。
答案 0 :(得分:3)
使用4个嵌套循环。为了防止重复并且仅计算“唯一集合”,我认为您必须从每个循环开始:[the 'parent' loop's current value] + 1
Option Explicit
Sub All4Combos()
'Caution! Save your work before runnning! (or set constant smaller)
Const NumCardsInDeck = 52
Dim c1, c2, c3, c4
Dim p As Long
For c1 = 1 To NumCardsInDeck
For c2 = c1 + 1 To NumCardsInDeck
For c3 = c2 + 1 To NumCardsInDeck
For c4 = c3 + 1 To NumCardsInDeck
p = p + 1
Debug.Print c1, c2, c3, c4
Next c4
Next c3
Next c2
Next c1
Debug.Print p & " Combinations of " & NumCardsInDeck & " cards"
End Sub
排列数量:
52 x 51 x 50 x 49
组合数量:
Permuations / slots!
--OR--
(52 x 51 x 50 x 49) / (4 x 3 x 2 x 1)
结果是270725种组合。
以下是10张卡的结果集:
1,2,4,10
1,2,5,6
1,2,5,7
1,2,5,8
1,2,5,9
1,2,5,10
1,2,6,7
1,2,6,8
1,2,6,9
1,2,6,10
1,2,7,8
1,2,7,9
1,2,7,10
1,2,8,9
1,2,8,10
1,2,9,10
1,3,4,5
1,3,4,6
1,3,4,7
1,3,4,8
1,3,4,9
1,3,4,10
1,3,5,6
1,3,5,7
1,3,5,8
1,3,5,9
1,3,5,10
1,3,6,7
1,3,6,8
1,3,6,9
1,3,6,10
1,3,7,8
1,3,7,9
1,3,7,10
1,3,8,9
1,3,8,10
1,3,9,10
1,4,5,6
1,4,5,7
1,4,5,8
1,4,5,9
1,4,5,10
1,4,6,7
1,4,6,8
1,4,6,9
1,4,6,10
1,4,7,8
1,4,7,9
1,4,7,10
1,4,8,9
1,4,8,10
1,4,9,10
1,5,6,7
1,5,6,8
1,5,6,9
1,5,6,10
1,5,7,8
1,5,7,9
1,5,7,10
1,5,8,9
1,5,8,10
1,5,9,10
1,6,7,8
1,6,7,9
1,6,7,10
1,6,8,9
1,6,8,10
1,6,9,10
1,7,8,9
1,7,8,10
1,7,9,10
1,8,9,10
2,3,4,5
2,3,4,6
2,3,4,7
2,3,4,8
2,3,4,9
2,3,4,10
2,3,5,6
2,3,5,7
2,3,5,8
2,3,5,9
2,3,5,10
2,3,6,7
2,3,6,8
2,3,6,9
2,3,6,10
2,3,7,8
2,3,7,9
2,3,7,10
2,3,8,9
2,3,8,10
2,3,9,10
2,4,5,6
2,4,5,7
2,4,5,8
2,4,5,9
2,4,5,10
2,4,6,7
2,4,6,8
2,4,6,9
2,4,6,10
2,4,7,8
2,4,7,9
2,4,7,10
2,4,8,9
2,4,8,10
2,4,9,10
2,5,6,7
2,5,6,8
2,5,6,9
2,5,6,10
2,5,7,8
2,5,7,9
2,5,7,10
2,5,8,9
2,5,8,10
2,5,9,10
2,6,7,8
2,6,7,9
2,6,7,10
2,6,8,9
2,6,8,10
2,6,9,10
2,7,8,9
2,7,8,10
2,7,9,10
2,8,9,10
3,4,5,6
3,4,5,7
3,4,5,8
3,4,5,9
3,4,5,10
3,4,6,7
3,4,6,8
3,4,6,9
3,4,6,10
3,4,7,8
3,4,7,9
3,4,7,10
3,4,8,9
3,4,8,10
3,4,9,10
3,5,6,7
3,5,6,8
3,5,6,9
3,5,6,10
3,5,7,8
3,5,7,9
3,5,7,10
3,5,8,9
3,5,8,10
3,5,9,10
3,6,7,8
3,6,7,9
3,6,7,10
3,6,8,9
3,6,8,10
3,6,9,10
3,7,8,9
3,7,8,10
3,7,9,10
3,8,9,10
4,5,6,7
4,5,6,8
4,5,6,9
4,5,6,10
4,5,7,8
4,5,7,9
4,5,7,10
4,5,8,9
4,5,8,10
4,5,9,10
4,6,7,8
4,6,7,9
4,6,7,10
4,6,8,9
4,6,8,10
4,6,9,10
4,7,8,9
4,7,8,10
4,7,9,10
4,8,9,10
5,6,7,8
5,6,7,9
5,6,7,10
5,6,8,9
5,6,8,10
5,6,9,10
5,7,8,9
5,7,8,10
5,7,9,10
5,8,9,10
6,7,8,9
6,7,8,10
6,7,9,10
6,8,9,10
7,8,9,10
210 Combinations of 10 cards
答案 1 :(得分:1)
为了它的乐趣
基于ashleedawg的代码并将结果写入文本文件我得到了这个结果:
Run took 2293 milliseconds
Wrote cardcombos.txt with 270725 lines of 4-card combinations of totally 52 cards
将代码移植到C ++产生了这个:
Run took 203 milliseconds
Wrote cardcombos.txt with 270725 lines of 4-card combinations of totally 52 cards
答案 2 :(得分:0)
这基本上是“多少握手”问题的扩展版本......
有几种方法可以解决这个问题 - 一种方法是强制它(生成所有排列,将所有元素分类为卡/套装顺序,然后删除重复项)
第二个选项是创建一个套牌并按顺序处理(“卡1
可以与卡2
配对 - 52
,对1&2
可以使用卡片3
- 52
,三位一体1&2&3
可以使用卡片4
- 52
“对其进行整理,然后从卡片中移除”已用过的“卡片用于下一个循环的堆栈(“triad 1&2&4
可以使用卡5
- 52
进行四舍五入,对1&3
可以使用卡4
- { {1}},卡52
可以与卡2
- 3
配对。“这将在四重奏52
停止
而且,是的,您的工作簿需要很长时间才能完成这些工作。只要完整的6,497,400个排列,但仍然有270,725个组合。
答案 3 :(得分:0)
对上面提供的代码进行了一些更改。这是最终结果。
Option Explicit
Sub All4Combos()
Dim Cards() As String
'Caution! Save your work before runnning! (or set constant smaller)
Cards = Split("As,Ks,Qs,Js,Ts,9s,8s,7s,6s,5s,4s,3s,2s,Ah,Kh,Qh,Jh,Th,9h,8h,7h,6h,5h,4h,3h,2h,Ad,Kd,Qd,Jd,Td,9d,8d,7d,6d,5d,4d,3d,2d,Ac,Kc,Qc,Jc,Tc,9c,8c,7c,6c,5c,4c,3c,2c", ",")
Const NumCardsInDeck = 51
Dim c1, c2, c3, c4
Dim p As Long
p = 0
For c1 = 0 To NumCardsInDeck
For c2 = c1 + 1 To NumCardsInDeck
For c3 = c2 + 1 To NumCardsInDeck
For c4 = c3 + 1 To NumCardsInDeck
p = p + 1
Cells(p, 1) = Cards(c1) & Cards(c2) & Cards(c3) & Cards(c4)
Next c4
Next c3
Next c2
Next c1
End Sub
答案 4 :(得分:0)
如果我们将卡片拆分为4件套装,每件都有13张卡片并以此作为我们的基础,则有4种卡片的5种不同组合可以撤销,如果我们只将套装作为唯一性:< / p>
现在,差不多,如果为所有套装模拟所有这些可能性,5次模拟的总和应该等于(49x50x51x52)/(4x3x2)= 270725
♥♦♣♠
For cnt1 = 1 To totalCards
For cnt2 = 1 To totalCards
For cnt3 = 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next : Next : Next : Next
四个嵌套循环正是所需要的。对于每件套装,totalCards=13
和numberResult*4
,我们会获得 28561 。或13^4
。
♥♦♣♣
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cntA = 1 To 3
For cnt3 = 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next : Next : Next : Next : Next
这里的想法是,对于同一套装的每两张牌,有一套,在我们的计算中不会发生。因此,cntA = 1 To 3
。最后,我们为每件套装乘以4
以获得 158184 。
♣♣♥♥
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = 1 To totalCards
For cnt4 = cnt3 + 1 To totalCards
numberResult = numberResult + 1
: Next : Next : Next : Next
我们有78种可能来自同一套装的2张牌。这是使用前两个嵌套循环进行模拟的。另外两种颜色的78种可能性是接下来的2个嵌套循环。因此,我们有6084种变体。然而,将4个套装组合成2个联合的方法是6(♥♣,♥♦,♥♠,♣♦,♣♠,♦♠),因此我们将结果乘以6
得到 36504 强>
♣♣♣♥
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = cnt2 + 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next : Next : Next : Next
这里我们有3张相同的牌和一张不同牌。每1套3张相同的卡,我们可能有3张不同的卡。我们有4套西装,因此,我们必须乘以12
(4x3)才能获得 44616 。
♥♥♥♥
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = cnt2 + 1 To totalCards
For cnt4 = cnt3 + 1 To totalCards
numberResult = numberResult + 1
Next : Next : Next : Next
这与接受的答案完全一样,但在这种情况下我们totalCards = 13
。至于我们有4种不同的套装,我们乘以4
得到 2860 。
这是代码的结果:
28561 4 different suits.
158184 3 different suits.
36504 2(2:2) different suits.
44616 2(3:1) different suits.
2860 1 suit only.
270725 All.270725
最后,代码来了:
Public Sub TestMe()
Dim cnt1&, cnt2&, cnt3&, cnt4&, cntA&
Dim totalCards&: totalCards = 13
Dim numberResult&, totalResult&
'4 different suits
For cnt1 = 1 To totalCards
For cnt2 = 1 To totalCards
For cnt3 = 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next: Next: Next: Next
numberResult = numberResult
Debug.Print " " & numberResult & vbTab & "4 different suits."
totalResult = numberResult + totalResult
numberResult = 0
'3 different suits
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cntA = 1 To 3
For cnt3 = 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next: Next: Next: Next: Next
numberResult = numberResult * 4
Debug.Print numberResult & vbTab & "3 different suits."
totalResult = numberResult + totalResult
numberResult = 0
'2 different suits (2+2)
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = 1 To totalCards
For cnt4 = cnt3 + 1 To totalCards
numberResult = numberResult + 1
Next: Next: Next: Next
numberResult = numberResult * 6
Debug.Print " " & numberResult & vbTab & "2(2:2) different suits."
totalResult = numberResult + totalResult
numberResult = 0
'2 different suits (3+1)
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = cnt2 + 1 To totalCards
For cnt4 = 1 To totalCards
numberResult = numberResult + 1
Next: Next: Next: Next
numberResult = numberResult * 12
Debug.Print " " & numberResult & vbTab & "2(3:1) different suits."
totalResult = numberResult + totalResult
numberResult = 0
'1 different suit
For cnt1 = 1 To totalCards
For cnt2 = cnt1 + 1 To totalCards
For cnt3 = cnt2 + 1 To totalCards
For cnt4 = cnt3 + 1 To totalCards
numberResult = numberResult + 1
Next: Next: Next: Next
numberResult = numberResult * 4
Debug.Print " " & numberResult & vbTab & "1 suit only."
totalResult = numberResult + totalResult
numberResult = 0
Debug.Print totalResult & vbTab & "All." & (49& * 50 * 51 * 52) / (4 * 3 * 2)
End Sub