首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有条件地生成10个随机对

有条件地生成10个随机对
EN

Stack Overflow用户
提问于 2017-05-31 18:18:20
回答 7查看 470关注 0票数 1

我有下面的for循环,它应该生成两个随机整数并调用grid.place(x,y)。如果grid.place(x,y)返回false,我想知道如何生成不同的对。如果提供的x和y以前没有提供,place方法将返回true。谢谢。

代码语言:javascript
复制
for (int i = 0; i < 10; i++) {
    mx = randomGenerator.nextInt(10);
    my = randomGenerator.nextInt(10);
    grid.place(mx,my); 
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2017-05-31 18:25:11

这是do-while循环的最佳情况:

代码语言:javascript
复制
for (int i = 0; i < 10; i++) {
    do{
       mx = randomGenerator.nextInt(10);
       my = randomGenerator.nextInt(10);
    }while(!grid.place(mx,my));

}

另一个解决方案是使用Collections.shuffle()方法。就像这样:

代码语言:javascript
复制
List<Integer> xPos = IntStream.rangeClosed(0,10).boxed().collect(Collectors.toList());
List<Integer> yPos = IntStream.rangeClosed(0,10).boxed().collect(Collectors.toList());

Collections.shuffle(xPos);
Collections.shuffle(yPos);


for(int i=0;i<10;i++)
    grid.place(xPos.get(i), yPos.get(i));

这将为您提供所有的和弦,并且不会比do-while循环更复杂地重复。

票数 2
EN

Stack Overflow用户

发布于 2017-05-31 18:24:21

为了避免重复,您可以使用一个列表,例如:

代码语言:javascript
复制
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    list.add(i);//fill your list
}

Random randomGenerator = new Random();
int mx = randomGenerator.nextInt(10);//generate the first value
int x = mx;//to not lost this value we store it in another variable
list.remove(mx);//remove the first value from your list, to avoid duplicate
int my = randomGenerator.nextInt(9);//generate the second value
int y = my;
grid.place(x, y);//now, you are sure that you have two different values 
票数 1
EN

Stack Overflow用户

发布于 2017-05-31 18:49:38

下面是一种更像OO的方法:

最有可能的是,“网格”不是无限的。这意味着您可以创建网格中所有可能位置的列表:

代码语言:javascript
复制
class Position{
  private final int x;
  private final int y;
  public Position(int x, int y){
    this.x=x;
    this.y=y;
  }
  public getX(){return x;}
  public getY(){return y;}
}

List<Position> availablePositions = new ArrayList<>();
for(int i =0; i<MAX_X;i++)
  for(int j =0; j<MAX_Y;j++)
    availablePositions.add(new Position(i,j));

然后您可以从该列表中检索一个随机索引:

代码语言:javascript
复制
   for (int i =0;i<10;i++){
     Position randomPosition = 
          availablePositions.remove(
                new Random().nextInt(availablePositions.size()));
     grid.place(
        randomPosition.getX(),
        randomPosition.getY());
   }

这样,您将永远不会得到一个重复,但所采取的立场是失去程序当前的执行。

或者,您只需对列表进行洗牌,并获取前10个元素:

代码语言:javascript
复制
 Collections.shuffle(availablePositions);
 for (int i =0;i<10;i++)
    grid.place(
        availablePositions.get(i).getX(),
        availablePositions.get(i).getY());

这也确保了循环中不同的位置,但您可以将列表中的所有位置保留在列表中供以后使用.

这个解决方案最大的问题是它有确定的时间,而代价是O(MAX_X * MAX_Y)内存。其他解决方案有O(1)时间(对于i的小值),虽然不是确定性的,还有O(1)内存。-戈博纳多

在现代计算机上,内存不是限制资源(甚至在手机上也不是.)。在用Java进行编程时,除非您已经证明存在问题,否则不应该优化内存和/或性能。如果您真的有内存问题,那么Java很可能是任务的错误工具。

但是:

当我们在解决方案中接受更多的OO时,我们将不需要单独的

Position对象占用内存。我们可以让Cell具有我们可以更改的状态,而不是网格中不可变的String对象。将自定义类作为网格中的元素使用,除了启用这种选择机制之外,还有更多的优点,因此我们应该看看它。

Cell.java

代码语言:javascript
复制
class Cell{
  private String content = " "; // empty
  public void placeHere(String newContent){
     content = newContent;
  }
}

Grid.java

代码语言:javascript
复制
 // ...     Cell[][] gameField = new Cell[MAX\_X][MAX\_Y];     for(int i =0; i  

然后,我们可以在一个单独的列表中收集现有的单元格:

List allCells =新的ArrayList<>();for(Cell[]行: gameField) allCells.addAll(Arrays.asList(行));

并选择随机单元来更改状态:

代码语言:javascript
复制
Collections.shuffle(allCells);
for(int i =0; i<10; i++)
   allCells.get(i).placeHere("*");

实际上,我们甚至不需要知道变化的细胞坐标。这就是OOP的意义所在:用代码中尽可能少的技术知识来解决任务。

等等,还有更多:

如何使用纯String数组重置游戏?对,迭代整个数组。但我得到的最佳性能优化提示是:

做某事最快的方法就是不去做。

那么,我们如何避免对完整数组的迭代呢?

使用我的方法,我们可以在一个单独的列表中收集修改后的单元格:

代码语言:javascript
复制
List<Cell> modifiedCells = new ArrList<>();
Collections.shuffle(allCells);
for(int i =0; i<10; i++){
   Cell currentCell = allCells.get(i);
   currentCell.placeHere("*");
   modifiedCells.add(currentCell);
}

然后,您必须重置该额外列表中的10单元对象,而不是数组中的MAX_X*MAX_Y字符串。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44292048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档