Java 随机卡片生成

Java 随机卡片生成,java,Java,我需要从数组中随机生成三张卡,我有52张卡的数组,从card1到card52 String rank[]=new String[52]; for(int i=0;i<rank.length;i++) { rank[i]= "card"+i; } String rank[]=新字符串[52]; 对于(int i=0;i而言,每当您选择一张卡时,都要有一个数组(甚至一个字符串)并添加到其中。这样,每当您选择第二张或第三张卡时,如果它在数组(或字符串)中,您就可以选择另一张卡 这里有一个方法…

我需要从数组中随机生成三张卡,我有52张卡的数组,从card1到card52

String rank[]=new String[52];
for(int i=0;i<rank.length;i++)
{
rank[i]= "card"+i;
}
String rank[]=新字符串[52];
对于(int i=0;i而言,每当您选择一张卡时,都要有一个数组(甚至一个字符串)并添加到其中。这样,每当您选择第二张或第三张卡时,如果它在数组(或字符串)中,您就可以选择另一张卡

这里有一个方法…我没有检查它是否有效

String pickedCards = ""
int totalPickedCards = 0
boolean continue = true;
for(continue) 
{
  tempVariable = pickedCard
  if (pickedCard.contains("/"+tempVariable+"/") == false) { // if you didn't already pick it then
    pickedCards = pickedCards + "/" + tempVariable + "/";
    // save the card you picked - stored in tempVariable
    ++totalPickedCards
  }
  if (totalPickedCards >= 3) { // exit loop if you have 3 cards picked
    continue = false;
  }
}
您可以尝试以下方法:

String rank[]=新字符串[52];
for(int i=0;i
如果你将数组转换成一个
列表,你可以使用它进行随机操作。如果你只取列表的前三个条目,你将得到三张没有重复的随机卡片

List<String> ranklist = Arrays.asList(rank);
Collections.shuffle(ranklist);
String rank1 = ranklist.get(0);
String rank2 = ranklist.get(1);
String rank3 = ranklist.get(2);
List ranklist=Arrays.asList(rank);
收藏。洗牌(ranklist);
字符串rank1=ranklist.get(0);
字符串rank2=ranklist.get(1);
String rank3=ranklist.get(2);

比洗牌整个阵列更快的东西:

java.util.Random r = new java.util.Random();
int c1 = r.nextInt(52),
  c2 = r.nextInt(51),
  c3 = r.nextInt(50);
if(c2 >= c1) c2++;
if(c3 >= Math.min(c1, c2)) c3++;
if(c3 >= Math.max(c1, c2)) c3++;
System.out.println("Card 1: " + rank[c1]);
System.out.println("Card 2: " + rank[c2]);
System.out.println("Card 3: " + rank[c3]);
事实上,我使用vs(屏幕截图)的通用(较慢)形式进行的一些计时测试表明,对于3张卡,该方法的速度大约是3.7倍,而实际上,对于选择多达24张随机卡,该方法的速度是3.7倍

向怀疑者解释算法:

概率 我们选择随机数-首先,52张牌中的一张。如果我们移除那张牌,然后选择另一张牌,那将是51张牌中的一张……所以我们选择的索引的随机数范围是可以接受的

如果我们从一个数组中拾取和移除,那么我们只需要取出索引1处的项,然后取出索引2处的项,对于索引3也是如此

我在上面所做的是调整索引,使其具有与从数组中取出项相同的效果

对于索引2,我们有一个数字,可以是0到50之间的任何数字。但是,让我们假设我们在索引6处取出了卡片

这意味着,我们不需要一个分布在0到50之间的随机数,而是需要一个分布在0-5和7-51之间的随机数。这仍然是51种可能性的总和。我们通过在第二个索引中添加1来实现这一点,如果它大于等于6。现在,我们有一个分布正确的正确范围内的数字,如果击中一个目标,则具有相同的概率允许的索引的y

第三张牌的逻辑也稍微复杂一些:牌组中有两个点“缺失”——因此我们调整第三个索引以覆盖可用范围。首先,如果它等于或高于第一个缺失位置,则将其向上移动。然后,如果它等于或高于第二个缺失位置,则将其再次向上移动。这不会使选择偏向高er值—我们所做的只是避免使用已经使用过的索引

概率没有偏差

效率
评论中提到,此算法和使用集合的算法具有相同的复杂性(即,O(n)),此方法的可读性稍差。首先要指出的是,此算法更复杂;即,对整个数组进行洗牌时,它是O(n^2).对于低n,该算法更有效。而且,我认为效率的差异保证了可读性的牺牲。比较:

收藏。洗牌

  • 随机数
  • 从列表中删除项目
  • 将项目插入列表
  • 再重复51次
  • 此方法

  • 随机数
  • 随机数
  • 随机数
  • 最多3个增量
  • 这忽略了使用第一种方法时从数组到容器的必要转换。不可避免的结论是,这种方法更有效

    顺便说一句,当你考虑挑选4张牌时,你可以想象O(n^2)的性质-这需要最多6张增量…5张牌,最多10张…6张牌,最多15张…n,(n^2-n)/2

    概括 在本例中,我使用了
    Math.min
    Math.max
    作为一种简单的方法来对2个项目的列表进行排序。在一般情况下(即选择“n”[1-52]非重复随机卡),我们需要对最多52个项目的列表进行排序。这可以在O(n)中完成最坏的情况是使用插入排序,方法是保留选定索引的有序列表。通过

  • 使用
    random.nextInt(52-selectedIndexListSize)
  • 在排序列表上迭代,在每个节点上,如果大于等于节点值,则增加所选索引,如果小于,则停止
  • 阵列中选定索引处的输出卡
  • 将所选索引插入到排序列表中,即我们停止的位置
  • 每个选项都是O(n)-但如果给出52个选项,则为O(n^2)

    然而,就效率而言,当m^2
    Random Random=new Random();
    
            Random random = new Random();
            List<Integer> randomList = new ArrayList<Integer>();
            int randomInt;
    
            do {
                randomInt = random.nextInt(52);
                if (randomList.contains(new Integer(randomInt)))
                    continue;
                randomList.add(randomInt);
            } while (randomList.size() < 3);
    
    List randomList=新建ArrayList(); int-randomInt; 做{ randomInt=random.nextInt(52); if(randomList.contains(新整数(randomInt))) 继续; 添加(randomInt); }while(randomList.size()<3);

    随机列表将包含三张卡片的索引

    基本上有两种数学上有效的方法:

  • 正如其他人所建议的,洗牌整个阵列,然后从一开始按顺序拾取

  • 随机选取第一个。然后随机选取第二个。如果第二个与第一个相同,则再次随机选取。也就是说,将选取放入一个保持t的循环中
            Random random = new Random();
            List<Integer> randomList = new ArrayList<Integer>();
            int randomInt;
    
            do {
                randomInt = random.nextInt(52);
                if (randomList.contains(new Integer(randomInt)))
                    continue;
                randomList.add(randomInt);
            } while (randomList.size() < 3);