2017-02-07 27 views
0

基本上,我有一個混洗的數組。陣列是一副撲克牌爲這樣:陣列洗牌後沒有重複結果

var rank = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"] 
var suit = ["♠", "♥","♦","♣"] 
var deck = [String]() 

我有一個用於循環與

for t in suit { 
     for r in rank { 
      deck.append("\(r)\(t)") 
     } 
    } 

創建甲板我然後在一個函數調用哪個我創建洗牌的延伸。 (這會給我帶來52張隨機分配的卡片)

 deck.shuffle() 

結果是隨機的,我不希望卡片重複。例如,如果結果是2♠,我不想在打印的列表中輸入2♥,2♦,2♣。

任何幫助表示讚賞!謝謝!

+0

你有沒有考慮只是洗這些52,直到沒有重複?有'52! = 8.065 x 10^67'方式來洗牌,所以你洗牌次數很少的機會是 –

+0

是的,儘管會發生什麼是UILabel會打印什麼牌。首先是,然後洗牌。我唯一的問題是,我不希望在洗牌之後打印的訂單重複。 –

+0

你真的不想要甲板洗牌? –

回答

0

我認爲最好的處理方法是使用修改後的Knuth shuffle。下面的代碼是一個完整的例子。在將內容保存到customshuffle.swift之後,在swiftc -o customshuffle customshuffle.swift && ./customshuffle的殼中運行它。

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) 
} 

這可以計算速度快,這是公平合理的,但不帶偏見黯然。我懷疑你的約束很快會產生一個「公平的洗牌」很難。