虽然(true)循环不会中断,但永远运行


import java.util.*;
import java.awt.*;
public class Lab11bst
{
public static void main(String args[])
{
System.out.println("Pick A Card, Any Card");
System.out.println();     
Deck deck = new Deck();
System.out.println(deck);
}
}
class Card
{
private String suit;
private String rank;
private int pointValue;
public Card(String s, String r, int pV)
{
suit = s;
rank = r;
pointValue = pV;
}
public String suit()      { 
return suit; }
public String rank()      { 
return rank; }
public int pointValue()   { 
return pointValue; }
public boolean matches(Card otherCard) 
{
return otherCard.suit().equals(this.suit())
&& otherCard.rank().equals(this.rank())
&& otherCard.pointValue() == this.pointValue();
}
public String toString()
{
return rank + " of " + suit + " (Point Value = " + pointValue + ")";
}
}
class Deck 
{
private Card[] cards;
private int size;
private Card[] newcards;
private String[] Suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
private String[] Ranks = {"Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"};
private int[] pointValues = {2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11};
public Deck() 
{
size = 52;
cards = new Card[size];
int index = 0;
for (int s = 0; s < 4; s++)
{
for (int r = 0; r < 13; r++)
{
cards[index] = new Card(Suits[s], Ranks[r], pointValues[r]);
index +=1;
}
}
//SwapShuffle();
OneBigShuffle();
}
public String toString()
{
String temp = "";
for (int k = 0; k <= size -1; k++)
{
temp += cards[k];
temp += "rn";
}
return temp;
}
private void SwapShuffle()
{
int uno;
int due;
Card temp;
for (int w = 0; w < 1000; w++)
{
uno =  (int)( Math.random() *52 );
due = (int)( Math.random() *52 );
temp = cards[uno];
cards[uno] = cards[due];
cards[due] = temp;
}
}
public static boolean repeat (int[] array, int e) 
{
boolean result = false;
for (int i : array)
{
if (i == e)
{
result = true;
break;
}
}
return result;
}
private void OneBigShuffle()
{
newcards = new Card[size];
int spot;
int[]  prevSpots = new int[size];
boolean running = true;
for (int k = 0; k < size; k++)
{
while(true)
{
spot = (int)( Math.random() *52 );
if (repeat(prevSpots, spot) == false)
{
break;
}
}
newcards[k]  = cards[spot];
prevSpots[k] = spot;
}
cards = newcards;
}
}

某处可能完全存在一个愚蠢的错误,但我的 while 循环拒绝终止。我对OneBigShuffle方法的目标是让while循环运行,直到Math.random生成一个不包含在prevSpots数组中的数字(使用"repeat"方法检查数组(。但是,该程序似乎无限期运行,尽管 if 语句带有中断。我还尝试了 while(条件(格式,其中条件设置为 false 而不是中断。这导致了一个错误,它说"点可能尚未初始化"。整个程序在上面,但这似乎是下面的问题区域:

for (int k = 0; k < size; k++)
{
while(true)
{
spot = (int)( Math.random() *52 );
if (repeat(prevSpots, spot) == false)
{
break;
}
}
newcards[k]  = cards[spot];
prevSpots[k] = spot;
}

大小是 52,所以数组有 52 个点!

你的问题是你每次都检查整个数组,而不仅仅是你填写的部分。

该数组最初是 52 个单元格,包含 0。

┌───┬───┬───┬───┬─────┬───┐
│ 0 │ 0 │ 0 │ 0 │ ... │ 0 │
└───┴───┴───┴───┴─────┴───┘

你选择一个数字,比如说6。它检查所有 52 个单元格 - 发现它们都不包含 6 个。这很好,所以它把 6 放在第一位。

┌───┬───┬───┬───┬─────┬───┐
│ 6 │ 0 │ 0 │ 0 │ ... │ 0 │
└───┴───┴───┴───┴─────┴───┘

你选择另一个数字,比如19。它检查所有 52 个单元格。它的值为 6 和 0。好的,19 没问题,它把它放在下一个单元格中。

┌───┬────┬───┬───┬─────┬───┐
│ 6 │ 19 │ 0 │ 0 │ ... │ 0 │
└───┴────┴───┴───┴─────┴───┘

等等。问题是你会选择除 0 之外的每个数字。每次它选择 0 时,它都会检查它,并且数组中已经有一个 0。填写完所有其他数字 (1-51( 后,除了 0 之外,您不能选择任何其他数字。但是你已经有 0,因为你检查了整个数组!

您必须检查"重复",直到 - 不包括 -k.

顺便说一下,这是一种非常糟糕的洗牌数组的方法。它的时间复杂度可能接近无限,具体取决于随机数生成器。最有效的随机算法是:

  • 用牌从 0 到 51 的自然顺序填充数组。
  • 对于从 51 到 0 降序排列的num
    • 选择一个介于 0 和num之间的随机数rand(含 0 和 (。
    • array[rand]array[num]之间交换卡

完成后,您的数组将被洗牌 - 因为在每个回合中,您都会选择一个尚未选择的随机单元格。因为如果它被选中,它已经被交换了另一个没有被选中的号码。

repeat()总是检查整个数组,数组开头包含 52 个零。这样零本身就永远不能放在数组中。

它应该得到k

public static boolean repeat (int[] array, int e, int k) 
{
boolean result = false;
//for (int i : array)
for(int i=0;i<k;i++) // <-- loop changed
{
if (array[i] == e) // <-- i became array[i]
{
result = true;
break;
}
}
return result;
}

结果仍然会很慢,因为随着循环(OneBigShuffle()的外部一个(的进行,随机生成器必须滚动越来越少的数字之一。

考虑参考关于洗牌的 https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle。


旁注:如果数组默认包含无效位置,那么原始的也可以工作:

int[] prevSpots = new int[size];
for(int i=0;i<size;i++)
{
prevSpots[i] = -1; // or any other value what is not in 0...51
}

最新更新