我正在开发一个applet程序,它可以从一副52张牌中显示10张随机牌。我使用for循环来循环显示10张卡片,并从我下载的图像中为它们提供一张随机卡片。当我编译并运行applet时,我有时会重复。有人可以给我任何关于如何在没有重复的情况下解决这个问题的指示吗?
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.util.Random;
public class Unit12Assignment1 extends Applet
{
Image card[] = new Image[10];
public void init()
{
String deckImages[] = {"cards_gif/c1.gif", "cards_gif/c2.gif", "cards_gif/c3.gif", "cards_gif/c4.gif",
"cards_gif/c5.gif", "cards_gif/c6.gif", "cards_gif/c7.gif", "cards_gif/c8.gif", "cards_gif/c9.gif",
"cards_gif/c10.gif", "cards_gif/cj.gif", "cards_gif/ck.gif", "cards_gif/cq.gif",
"cards_gif/s1.gif", "cards_gif/s2.gif", "cards_gif/s3.gif", "cards_gif/s4.gif",
"cards_gif/s5.gif", "cards_gif/s6.gif", "cards_gif/s7.gif", "cards_gif/s8.gif",
"cards_gif/s9.gif", "cards_gif/s10.gif", "cards_gif/sj.gif", "cards_gif/sk.gif",
"cards_gif/sq.gif", "cards_gif/d1.gif", "cards_gif/d2.gif", "cards_gif/d3.gif",
"cards_gif/d4.gif", "cards_gif/d5.gif", "cards_gif/d6.gif", "cards_gif/d7.gif",
"cards_gif/d8.gif", "cards_gif/d9.gif", "cards_gif/d10.gif", "cards_gif/dj.gif",
"cards_gif/dk.gif", "cards_gif/dq.gif", "cards_gif/h1.gif", "cards_gif/h2.gif",
"cards_gif/h3.gif", "cards_gif/h4.gif", "cards_gif/h5.gif", "cards_gif/h6.gif",
"cards_gif/h7.gif", "cards_gif/h8.gif", "cards_gif/h9.gif", "cards_gif/h10.gif",
"cards_gif/hj.gif", "cards_gif/hk.gif", "cards_gif/hq.gif"};
for( int i = 0; i < card.length; i++ )
{
int x = (int)(Math.random() * 52);
card[i] = getImage(getDocumentBase(), deckImages[x]);
}
}
public void paint(Graphics g)
{
setBackground( Color.green );
int x = -60;
for( int i = 0; i < card.length / 2; i++ )
{
x = x + 90;
g.drawImage(card[i], x, 30, this);
}
x = -60;
for( int i = card.length / 2; i < card.length; i++ )
{
x = x + 90;
g.drawImage(card[i], x, 150, this);
}
}
}
答案 0 :(得分:2)
有各种各样的可能性。您可以检测到重复,并在这种情况下生成新索引,直到您获得唯一的索引。其他选项可以是对一系列索引进行混洗,然后选择前10个。要有创意,这不是一项艰巨的任务。
另一种可能性:
// TODO initialize this to -1
int chosen[] = new int[10];
for( int i = 0; i < card.length; i++ )
{
int x = (int)(Math.random() * 52);
for(int j=0; j< chosen.length; j++)
if(x==chosen[j])
{
x++;
j=0;
if(x>51)
x=0;
}
card[i] = getImage(getDocumentBase(), deckImages[x]);
chosen[i] = x;
}
这并非严格意义上的随意,但即使您遇到一个实现如下的随机数生成器,您也可以确定它会结束:return 42;
答案 1 :(得分:1)
由于随机发生器,卡被选中。为了避免重复,您也可以存储以前生成的那一轮数。因此,您可以强制生成器选择一个新的数字,因为它通过将拾取的数字与之前的数字进行比较来选择一个新的数字。
答案 2 :(得分:-1)
它被称为Fisher-Yates shuffle(或Fisher-Yates-Knuth shuffle)。基本上,相当于从59个中选出6个中奖彩票球。 链接到说明http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
伪代码(更接近C ++,希望我不会犯很多错误)
void swap(int& a, int& b) {
int t = a;
a = b;
b = t;
}
// in-place shuffle
void shuffle(int cards[], int n) { // sample n non-repeating cards from the deck
int last_index = 51;
for(int k = 0; k != n; ++k) {
int idx = random(last_index); // random shall produce number from 0 to last_index inclusively
if (idx != last_index) {
swap(cards[idx], cards[last_index]);
}
--last_index;
}
}
int cards[52];
for(int k = 0; k != 52; ++k) {
cards[k] = k;
}
shuffle(cards, 10);
// now last 10 positions in cards array are sampled cards