问题在于:我需要洗牌一副牌(ArrayList或52个整数的数组(0到51))。我还需要在Android处理器上执行此操作200,000次。请帮助我优化这一点,因为即使在更高端的设备上(最多10秒),这也需要花费不可思议的时间。
我试过的方法:
1)使用Collections.shuffle对牌组进行随机抽牌并绘制我得到的第一张牌(在Nexus7上花费8秒):
for(long i = 0; i < ITERATIONS; i++) { // ITERATIONS is 200,000
ArrayList<Integer> fakeDeck = (ArrayList) deck.clone(); // deck is the sorted deck.
Collections.shuffle(fakeDeck);
int card1 = fakeDeck.get(0);
int card2 = fakeDeck.get(1);
int card3 = fakeDeck.get(2);
int card4 = fakeDeck.get(3);
int card5 = fakeDeck.get(4);
// do something with cards.
}
2)从未洗过的牌组中随机挑选牌(更好一点,需要5秒):
for(long i = 0; i < ITERATIONS; i++) { // ITERATIONS is 200,000
ArrayList<Integer> fakeDeck = (ArrayList) deck.clone(); // deck is the sorted deck.
int card1 = pullCardFromDeck(fakeDeck);
int card2 = pullCardFromDeck(fakeDeck);
int card3 = pullCardFromDeck(fakeDeck);
int card4 = pullCardFromDeck(fakeDeck);
int card5 = pullCardFromDeck(fakeDeck);
// do something with cards.
}
// pullCardFromDeck是:
private int pullCardFromDeck(ArrayList<Integer> deck) {
int randomNumber = new Random().nextInt(deck.size());
int card = deck.get(randomNumber); // get a random card.
deck.remove(randomNumber); // remove the card from the deck.
return card;
}
答案 0 :(得分:3)
如果你只需要五张牌,你每次只需要洗牌5张牌。这可能快20倍。
public static void main(String... ignored) {
int[] cards = new int[52];
for (int i = 0; i < cards.length; i++) cards[i] = i;
long start = System.currentTimeMillis();
int runs = 1000000;
for (int i = 0; i < runs; i++) {
shuffleN(cards, 5);
int card1 = cards[0], card2 = cards[1], card3 = cards[2], card4 = cards[3], card5 = cards[4];
}
long time = System.currentTimeMillis() - start;
System.out.printf("Took %.3f seconds to shuffle %,d times%n", time / 1e3, runs);
}
private static final Random RND = new Random();
public static void shuffleN(int[] numbers, int count) {
for (int i = 0; i < count; i++) {
int r = RND.nextInt(numbers.length - i) + i;
if (i == r) continue;
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
}
}
打印
Took 0.115 seconds to shuffle 1,000,000 times
答案 1 :(得分:0)
你可能最好考虑使用你洗牌并用来访问单个牌组的int []索引。要获取随机条目,请将所选索引设置为零(当您获得随机数时,查看该值是否已为零,如果是选择新卡)