java - 如何改组 ArrayList,但改组特定索引后保持不变?
问题描述
在我的ArrayList
中,每个数字都根据它们在 中的位置分配给它们的颜色ArrayList
。奇数索引中的数字为红色,偶数索引中的数字为蓝色,10 的倍数索引中的数字为黑色。我需要对列表进行洗牌,以便在洗牌后,红色数字仍在奇数索引中,蓝色数字仍在偶数索引中,黑色数字仍在十个索引的倍数中。我知道如何洗牌整个列表,但不知道这样的具体事情。我该怎么做呢?
这是上下文的代码:
/* Term 2 Assignment 5 - Game Wheel */
/* GameWheel class*/
import java.util.*;
import java.lang.*;
public class GameWheel
{
// List of slices making up the wheel
private List<Slice> slices;
// Position of currently selected slice on wheel
private int currentPos;
/* Creates a wheel with 40 preset slices which are then randomized (keeping
* the color pattern the same).
*/
public GameWheel()
{
slices = new ArrayList<Slice>();
currentPos = 0;
initGameWheel();
scramble();
}
/* Spins the wheel by so that a different slice is selected. Return that
* slice (Note: the 20 slices following the current slice are more likely to
* be returned than the other 20).
*/
public Slice spinWheel()
{
//spin power between range of 1-100 (inclusive)
int power = (int)(Math.random()*100 + 1);
int newPos = (currentPos + power) % slices.size();
currentPos = newPos;
return slices.get(currentPos);
}
/* Helper method for the constructor. Randomizes the positions of the slices
* that are in the wheel, but without changing the pattern of the colors
* (i.e. the red slices will still be at odd indices, the black slices at
* multiples of 10, and the blue slices at all other even indices).
*/
private void scramble()
{
}
// Helper method which initializes the slices in the wheel
private void initGameWheel()
{
slices.add(new Slice("black", 8000));
for (int i=1; i < 40; i++)
{
if (i%2 == 1)
slices.add(new Slice("red", i*10));
else if (i%10 == 0)
slices.add(new Slice("black", i*200));
else
slices.add(new Slice("blue", i*100));
}
}
// Returns the list of slices for this GameWheel
public List<Slice> getSlices() {
return slices;
}
}
以下是切片的创建方式:
/* Slice class*/
public class Slice
{
private String color;
private int prizeAmount;
// Creates a slice with color c, and cash prize p
public Slice(String c, int p) {
color = c;
prizeAmount = p;
}
// Returns the cash prize in dollars for this slice
public int getPrizeAmount() {
return prizeAmount;
}
// Returns the color of this slice as a string
public String getColor() {
return color;
}
/* Returns a string representation of the slice in the following format:
* Color: red, prize amount: $50.
*/
public String toString() {
return "Color: " + color + ", Prize Amount: $" + prizeAmount;
}
}
任何帮助表示赞赏
解决方案
没有“简单”的方式(例如,通过现有的方法,例如Collections.shuffle
);你必须自己编程这个功能,但你当然可以使用一些现有的东西来帮助你。
一种有点迂回的方法是“解构和重构”:编写一个方法,将单个列表分解为 3 个单独的列表(每种颜色 1 个),然后将它们打乱,然后将三个单独的列表“重构”回一个大列表,使用明显的算法(如果索引能被 10 整除,则从黑名单中抓取下一个,否则如果能被 2 整除,则从蓝名单中抓取,否则,从红名单中抓取)。
另一种方法是自己实现洗牌算法。对于上下文,您正在寻找Fisher-Yates shuffle algorithm,它的实现Collections.shuffle
也使用了该算法。要知道的关键事项:
要获得 0 到 N 之间的随机数,请调用(创建单个实例,一次,并继续重复使用它)的实例
.nextInt(n)
。Random
不要使用 common(int) (Math.random() * n)
,这是微妙的错误(鸽子原则)和非惯用的 java。Fisher yates 主要涉及从开始(索引 0)到倒数第二个元素(具有索引的那个)遍历列表
list.size() -2
。对于每个元素,将其与一个统一的随机选择的元素交换,该元素本身或它上面的任何元素。
换句话说,要 shuffle 1,2,3,4,5
,我们从第 0 个元素(第 1 个)开始,并从其自身中选择任何均匀随机的元素并与之交换。这是5个元素的选择,所以我们打电话rnd.nextInt(5)
来弄清楚。该随机数可能是 0,在这种情况下,“你将 1 与它自己交换”,这意味着它保持原位(嘿,洗牌意味着随机;有时一张牌在洗牌后会出现在牌堆中的同一个位置!)。然后对于下一个元素(索引 1 处的 2),您从其自身(即索引 1)中选择任何索引直到最后,因此我们调用rnd.nextInt(4)
,依此类推。
对于这个练习,棘手的一点是要弄清楚有多少有效的“在你之上”可以交换存在(这将是你传递给的参数rnd.nextInt(X)
),以及如何翻译你的 nextInt 调用给你的数字您现在需要交换的索引。
请注意,此算法完全可以正常工作;不需要任何额外的列表或数组。您只需要一个临时变量来启用交换。
这听起来像家庭作业,所以我不会为你预先咀嚼答案。希望这足以让您自己编写它。祝你好运!
推荐阅读
- javascript - React Scheduler 自定义预约表格
- excel - 从 Tableau Server 到 Excel 的数据连接
- javascript - 如何通过 JS 触发特定的 Chrome 扩展功能
- git - GitHub/Git:无法使用特定分支创建拉取请求(无按钮)
- .htaccess - 为什么我的 .htaccess 文件没有重定向到 https?怎么修?
- python - PySpark:小写键丢失数据
- python - ImportError:无法从“brownie”导入名称“SimpleCollectible”
- amazon - 最终策略大小大于限制
- php - 从动态更改的表单字段中创建数组
- sql - 出现错误时如何插入我的代码并使其正常工作?