洗牌
December 3, 2021洗牌就是給定一組資料…將之打亂、重新排列。
解法思路
單純地隨機產生 1 ∼ N 的亂數,逐一將資料根據亂數放到指定位置,後續就必須考慮產生的亂數是否重複的問題,運氣不好重複次數多的話,執行速度就慢了,這不是一個好方法。
可以逐一走訪資料,每次產生一個資料長度內的一個亂數,將目前位置與該亂數位置的資料交換,走訪完畢後,也就重新排列了。
程式實作
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 52
typedef struct {
char suit[3];
char symbol[3];
} Card;
void shuffle(Card*);
void card(int, char*);
void suit(int, char*);
void symbol(int, char*);
int main(void) {
srand(time(0));
Card cards[N];
shuffle(cards);
int i;
for(i = 0; i < N; i++) {
printf("%s%s%c", cards[i].suit, cards[i].symbol,
(i + 1) % 13 ? ' ' : '\n');
}
return 0;
}
void shuffle(Card* cards) {
int i;
for(i = 0; i < N; i++) {
suit(i + 1, cards[i].suit);
symbol(i + 1, cards[i].symbol);
}
for(i = 0; i < N; i++) {
int j = rand() % 52;
Card tmp = cards[i];
cards[i] = cards[j];
cards[j] = tmp;
}
}
void suit(int number, char* suit) {
switch((number - 1) / 13) {
case 0: strcpy(suit, "桃"); break;
case 1: strcpy(suit, "心"); break;
case 2: strcpy(suit, "磚"); break;
case 3: strcpy(suit, "梅");
}
}
void symbol(int number, char* symbol) {
int remain = number % 13;
switch(remain) {
case 0: sprintf(symbol, "%c ", 'K'); break;
case 1: sprintf(symbol, "%c ", 'A'); break;
case 11: sprintf(symbol, "%c ", 'J'); break;
case 12: sprintf(symbol, "%c ", 'Q'); break;
default: sprintf(symbol, "%-2d", remain);
}
}
import java.util.*;
class Card {
private String suit;
private String symbol;
public Card(String suit, String symbol) {
this.suit = suit;
this.symbol = symbol;
}
public String toString() { return suit + symbol; }
}
public class Poker {
private static List<Card> cards = new ArrayList<>(52);
static {
for(int i = 0; i < 52; i++) {
cards.add(new Card(suit(i + 1), symbol(i + 1)));
}
}
private static String suit(int number) {
switch((number - 1) / 13) {
case 0 : return "桃";
case 1 : return "心";
case 2 : return "磚";
default: return "梅";
}
}
private static String symbol(int number) {
int remain = number % 13;
switch(remain) {
case 0 : return String.format("%c ", 'K');
case 1 : return String.format("%c ", 'A');
case 11: return String.format("%c ", 'J');
case 12: return String.format("%c ", 'Q');
default: return String.format("%-2d", remain);
}
}
public static Card[] shuffle() {
for(int i = 0; i < cards.size(); i++) {
Collections.swap(cards, i,
(int) (Math.random() * cards.size() - 1));
}
return cards.toArray(new Card[52]);
}
public static void main(String args[]) {
Card[] cards = shuffle();
for(int i = 0; i < cards.length; i++) {
System.out.printf(
"%s%c", cards[i], (i + 1) % 13 == 0 ? '\n' : ' ');
}
}
}
from random import randint
from functools import reduce
class Card:
def __init__(self, suit, symbol):
self.suit = suit
self.symbol = symbol
def __str__(self):
return self.suit + self.symbol
class Poker:
cards = [Card(
{0: "桃", 1: "心", 2: "磚", 3: "梅"}[i // 13],
{0: "K ", 1: "A ", 11: "J ", 12: "Q "}.get(
(i + 1) % 13, "%-2d" % ((i + 1) % 13))
) for i in range(52)]
@staticmethod
def shuffle():
def swap(cards, i, j):
a, b = sorted([i, j])
return cards if a == b else (cards[0:a] + [cards[b]] +
cards[a + 1:b] + [cards[a]] + cards[b + 1:])
return reduce(lambda cards, i: swap(cards, i, randint(0, 51)),
range(len(Poker.cards)), Poker.cards)
cards = Poker.shuffle()
for i in range(len(cards)):
print(cards[i], end = "\n" if (i + 1) % 13 == 0 else " ")
import scala.util.Random
class Card(st: String, sym: String) {
def suit = st
def symbol = sym
override def toString = st + sym
}
object Poker {
private def suit(number: Int) = (number - 1) / 13 match {
case 0 => "桃";
case 1 => "心"
case 2 => "磚"
case 3 => "梅"
}
private def symbol(number: Int) = {
val remain = number % 13
remain match {
case 0 => "%c ".format('K')
case 1 => "%c ".format('A')
case 12 => "%c ".format('Q')
case 11 => "%c ".format('J')
case _ => "%-2d".format(remain)
}
}
val cards = (for(i <- 0 until 52)
yield new Card(suit(i), symbol(i))).toList
private val random = new Random
def shuffle = {
def swap(cards: List[Card], i: Int, j: Int) = {
val List(a, b) = List(i, j).sortWith(_ < _)
if(a == b) cards else (cards.take(a) ++
(cards(b) :: cards.slice(a + 1, b)) ++
(cards(a) :: cards.drop(b + 1)))
}
(cards /: (0 until cards.size))((cards, i) =>
swap(cards, i, (random.nextDouble * cards.size - 1).toInt))
}
}
val cards = Poker.shuffle
for(i <- 0 until cards.size) {
printf("%s%c", cards(i), if((i + 1) % 13 == 0) '\n' else ' ')
}
# encoding: UTF-8
class Card
def initialize(suit, symbol)
@suit = suit
@symbol = symbol
end
def to_s
@suit + @symbol
end
end
class Poker
def self.suit(number)
case (number - 1) / 13
when 0; "桃"
when 1; "心"
when 2; "磚"
when 3; "梅"
end
end
def self.symbol(number)
remain = number % 13
case remain
when 0; "K "
when 1; "A "
when 11; "J "
when 12; "Q "
else; sprintf("%-2d", remain)
end
end
def self.shuffle
swap = ->(cards, i, j) {
a, b = [i, j].sort
a == b ? cards : (cards.take(a) + [cards[b]] +
cards[a + 1...b] + [cards[a]] + cards.drop(b + 1))
}
(0...(@@cards.size)).reduce(@@cards) { |cards, i|
swap.call(cards, i, (rand() * 51).to_i)
}
end
@@cards = (0...52).map { |i| Card.new(suit(i + 1), symbol(i + 1))}
end
cards = Poker.shuffle
(0...cards.size).each do |i|
printf("%s%c", cards[i], (i + 1) % 13 == 0 ? "\n" : " ")
end
function Card(suit, symbol) {
this.suit = suit;
this.symbol = symbol;
}
Card.prototype.toString = function() {
return this.suit + this.symbol;
};
var Poker = function() {
function suit(number) {
switch(parseInt((number - 1) / 13)) {
case 0 : return "桃";
case 1 : return "心";
case 2 : return "磚";
case 3 : return "梅";
}
}
function symbol(number) {
var remain = number % 13;
switch(remain) {
case 0 : return 'K ';
case 1 : return 'A ';
case 11: return 'J ';
case 12: return 'Q ';
default: return remain +
new Array(3 - (remain + '').length).join(' ');
}
}
var cards = [];
for(var i = 0; i < 52; i++) {
cards.push(new Card(suit(i + 1), symbol(i + 1)));
}
return {
shuffle: function() {
for(var i = 0; i < cards.length; i++) {
var j = parseInt(Math.random() * cards.length - 1);
var tmp = cards[i];
cards[i] = cards[j];
cards[j] = tmp;
}
return cards.slice(0, cards.length);
}
};
}();
print(Poker.shuffle());
import Data.List
import System.Random
data Card = Card {suit :: [Char], symbol :: [Char]}
instance Show Card where
show card = (suit card) ++ (symbol card)
shuffle rList =
foldl (\cards (i, r) -> swap cards i r) cards (zip [0..51] rList)
where suit number =
case (number - 1) `div` 13 of 0 -> "S"
1 -> "H"
2 -> "D"
3 -> "C"
symbol number =
case remain of 0 -> "K"
1 -> "A"
11 -> "J"
12 -> "Q"
_ -> show(remain)
where remain = number `mod` 13
slice from to = take (to - from) . drop from
swap cards i j =
if a == b then cards
else (take a cards) ++
((cards !! b) : (slice (a + 1) b cards)) ++
((cards !! a) : (drop (b + 1) cards))
where [a, b] = sort [i, j]
cards = [Card (suit $ i + 1) (symbol $ i + 1) | i <- [0..51]]
main = do
gen <- getStdGen
print $ shuffle $ rand gen 52
where rand gen n= take n $ randomRs (0, 51) gen::[Int]