优化混洗ArrayList

时间:2014-02-23 20:11:23

标签: java android optimization arraylist

问题在于:我需要洗牌一副牌(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;
}

2 个答案:

答案 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 []索引。要获取随机条目,请将所选索引设置为零(当您获得随机数时,查看该值是否已为零,如果是选择新卡)