Arrays 数组洗牌后不重复结果
基本上,我有一个被洗牌的数组。阵列是一副卡片,例如:Arrays 数组洗牌后不重复结果,arrays,swift,string,for-loop,append,Arrays,Swift,String,For Loop,Append,基本上,我有一个被洗牌的数组。阵列是一副卡片,例如: var rank = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"] var suit = ["♠", "♥","♦","♣"] var deck = [String]() 我有一个for循环来创建甲板 for t in suit { for r in rank { deck.append("\(r)\(t)") }
var rank = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
var suit = ["♠", "♥","♦","♣"]
var deck = [String]()
我有一个for循环来创建甲板
for t in suit {
for r in rank {
deck.append("\(r)\(t)")
}
}
然后,我在一个函数中调用了一个扩展,我创建了这个扩展来洗牌牌。这给我带来了52张随机分类的卡片
deck.shuffle()
唯一的问题是,虽然结果是随机的,但我不希望卡片重复。例如,如果结果为2♠, 我不想要两个♥, 2.♦, 2.♣ 下面是打印的列表
感谢您的帮助!谢谢 我认为最好的方法是使用改进的Knuth shuffle。下面的代码是一个完整的示例。在customshuffle.swift中保存内容后,只需使用swiftc-o customshuffle customshuffle.swift&&./customshuffle在shell中运行它
这可以很快地计算出来,这是合理的公平,但并非毫无偏见。我怀疑,如果您的约束运行得很快,可能很难生成一个公平的洗牌。您是否考虑过再次洗牌,直到不再重复?有52个!=8.065 x 10^67洗牌的方法因此你洗牌的机会非常小是的,尽管发生的是UILabel打印了什么牌组。首先是,然后洗牌。我唯一的问题是,我从不希望洗牌后打印的顺序有重复。你真的不希望牌组洗牌?所以你永远不希望一张牌后面跟着另一张相同等级的牌?是的,基本上我想要洗牌,但结果不是相同等级的。谢谢你的回复!
import Foundation
let decksize = 52
let rankStrings = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
let suitStrings = ["♠", "♥","♦","♣"]
struct card : Hashable, Equatable, CustomStringConvertible {
var rank: Int //1,2...,11,12,13
var suit: Int // 1,2,3,4
var hashValue: Int {
return rank + suit
}
static func == (lhs: card, rhs: card) -> Bool {
return lhs.rank == rhs.rank && lhs.suit == rhs.suit
}
var description: String {
return rankStrings[self.rank - 1] + suitStrings[self.suit - 1]
}
}
// seems like Swift still lacks a portable random number generator
func portablerand(_ max: Int)->Int {
#if os(Linux)
return Int(random() % (max + 1)) // biased but I am in a hurry
#else
return Int(arc4random_uniform(UInt32(max)))
#endif
}
// we populate a data structure where the
// cards are partitioned by rank and then suit (this is not essential)
var deck = [[card]]()
for i in 1...13 {
var thisset = [card]()
for j in 1...4 {
thisset.append(card(rank:i,suit:j))
}
deck.append(thisset)
}
// we write answer in "answer"
var answer = [card]()
// we pick a card at random, first card is special
var rnd = portablerand(decksize)
answer.append(deck[rnd / 4].remove(at: rnd % 4))
while answer.count < decksize {
// no matter what, we do not want to repeat this rank
let lastrank = answer.last!.rank
var myindices = [Int](deck.indices)
myindices.remove(at: lastrank - 1)
var totalchoice = 0
var maxbag = -1
for i in myindices {
totalchoice = totalchoice + deck[i].count
if maxbag == -1 || deck[i].count > deck[maxbag].count {
maxbag = i
}
}
if 2 * deck[maxbag].count >= totalchoice {
// we have to pick from maxbag
rnd = portablerand(deck[maxbag].count)
answer.append(deck[maxbag].remove(at: rnd))
} else {
// any bag will do
rnd = portablerand(totalchoice)
for i in myindices {
if rnd >= deck[i].count {
rnd = rnd - deck[i].count
} else {
answer.append(deck[i].remove(at: rnd))
break
}
}
}
}
for card in answer {
print(card)
}