提问者:小点点

随机“摇一摇”一个数组,分配新的随机点


我想做的是拿我的数组硬币[]。基本上将每个硬币重新排列到不同的位置。这就是我到目前为止所拥有的。当我这样做时,什么都没有发生。这意味着所有的值保持不变。除了最后一个。那个改变了。

public void shake() 
{
    for (int i = 0; i < coins.length; i++)
    {
        int index = Coin.RANDOM.nextInt(coins.length);
        Coin temp = coins[index];
        coins[index] = coins[i];
        coins[i] = temp;

        System.out.print(coins[i] + ", ");
    }
}

我像这样实例化随机:

public static long SEED = System.currentTimeMillis();
public static Random RANDOM = new Random(SEED);

共3个答案

匿名用户

请注意这条线

System.out.print(coins[swap] + ", ");

显示已经移动(交换)的硬币。也许您正在考虑在iindex:硬币[i]处显示新硬币(无论如何这是不正确的,因为已经显示的硬币仍然可以在下一次迭代中交换)。也许最好为循环创建第二个来显示最终的硬币值。

但这不仅仅是这里的问题。要随机洗牌数组,您应该使用与您的方法略有不同的Ferer-Yates算法。您可以在SO上找到Java算法的实现。

如果你有一个列表

匿名用户

当您使用交换作为索引时,您将交换当前值,您可以编辑您的随机数生成器以在特定范围内生成随机数(例如0-coin. long),然后您可以将您的实现更改为如下所示

public void shake() 
{

    Coin temp;

    for (int i = 0; i < coins.length; i++)
    {
        //int swap = Coin.RANDOM.nextInt(coins.length);
        temp = coins[swap];
        coins[swap] = coins[i];
        coins[i] = temp;

        System.out.print(coins[i] + ", ");
    }
}

对于代码中的注释行,请选中此项以更新随机数生成器以生成两个值之间的数字。然后每次在i 1-coin. long之间生成交换(index)并继续此操作,直到完全耗尽数组。这确保您不会在索引处进行已显示的值的交换。但我并不完全相信这确实是一次随机洗牌,因为在循环开始时,您对交换索引有更多选择,而在循环稍后的某个时候,您会有更多选择,并且摇动不是完全随机的。此解决方案仅适用于您想严格实现自己的摇动方法而不使用@Tomek提到的Collection. shuffle的情况。

匿名用户

为什么不使用集合?为数组或ArrayList中的每个值分配随机索引非常简单。

Collections.shuffle(coins);//if coins is array
Collections.shuffle(Arrays.asList(coins));//if coins is an ArrayList