【问题标题】:java - 2D array find random null valuejava - 二维数组找到随机空值
【发布时间】:2015-02-14 15:49:51
【问题描述】:

我有一个二维数组,其中一些索引为空,一些索引具有值。 我想选择一个包含 null 的随机索引。

例子

5,0,0,5,0
4,0,0,4,7
9,0,4,8,9
0,8,4,0,1

我想从这些零索引中选择随机索引

谢谢回复

【问题讨论】:

    标签: java arrays loops find


    【解决方案1】:

    或者你可以试试这个:将'0'的索引作为键/值放在地图上,然后:

       Random   random = new Random();
       Map x= new HashMap();
        x.put(0,1); 
    

    ....

    List keys      = new ArrayList<Integer>(x.keySet());
    Integer randomX = keys.get( random.nextInt(keys.size()) );
    Integer value  = x.get(randomX );
    

    【讨论】:

      【解决方案2】:
      //Init array
      int array[][] = { { 5, 0, 0, 5, 0 }, { 4, 0, 0, 4, 7 },
                        { 9, 0, 4, 8, 9 }, { 0, 8, 4, 0, 1 } };
      
      //Init vector for indices of elements with 0 value
      ArrayList<int[]> indices = new ArrayList<int[]>();
      
      //Find indices of element with 0 value
      for (int i = 0; i < array.length; i++)
      {
          for (int j = 0; j < array[i].length; j++)
          {
              if (array[i][j] == 0)
              {
                  indices.add(new int[] { i, j });
              }
          }
      }
      
      //Just print the possible candidates
      for (int[] index : indices)
      {
         System.out.println("Index = (" + index[0] + ", " + index[1] + ")");
      }
      System.out.println();
      
      //Select a random index and print the result
      Random rand = new Random();
      int ri = rand.nextInt(indices.size());
      int[] index = indices.get(ri);
      
      System.out.println("Selected index = (" + index[0] + ", " + index[1] + ")");
      

      该解决方案是基于很容易在一维数组中选择一个随机值。因此,作为第一步,所有属于值为 0 的元素的索引都被收集到一个 ArrayList 对象中,然后在这个 ArrayList 对象中选择一个随机元素会导致搜索到的索引。

      【讨论】:

      • Netbeans 说:此检查报告 java.util.Vector 或 java.util.Hashtable 的任何使用。虽然仍然受支持,但这些类已被 JDK1.2 集合类淘汰,并且可能不应该在新的开发中使用。为什么使用矢量?谢谢大家的回复!
      • 好问题。答案写在这里:stackoverflow.com/questions/1386275/…我已经把Vector对象改成了ArrayList。
      【解决方案3】:

      您可以使用简单的技巧 - 只需将零值映射到数组。 或者更好的解决方案是只计算零值的数量,所以,你应该遍历你的二维数组并比较值 - 如果你想找到零,那么它应该是:

      int count = 0;
      for(int i=0;i< array.length;i++)
        for(int j=0;j< array[i].length;j++)
          if(array[i][j] == 0)
            count++;
      

      之后,您可以从间隔 1 计数中获取随机数,然后迭代您的二维数组并选择具有随机位置的零数。

      int randomPosition = (int )(Math.random() * (count-1));
      int now=0;
      if(randomPosition > -1)
        for(int i=0;i< array.length;i++)
          for(int j=0;j< array[i].length;j++)
            if(array[i][j]==0){
               now++;
               if(now == randomPosition){
               rowPosition = i;
               columnPosition = j;
              }
            }
      

      这并不是真正正确的方法,如果可以的话,您不应该在设计中使用空值 - 或零作为空值,最好考虑另一种将值保存在二维数组中的解决方案。你真的需要空值或零值吗?为什么你需要返回随机空位置?

      【讨论】:

      • 我正在为 gomoku 做随机算法,所以我需要从 empties 中选择随机位置来回复
      • @MarekForst 好吧,我不知道这个游戏,但是如果你真的需要它,你可以使用我写的,这不是有效的,但可以解决你的问题:)
      【解决方案4】:

      根据您的问题,我了解到您想在 Java 的二维数组中选择一个随机元素(包含 0)。首先,您应该明白,由于大多数数字都是基于值的,0 != null。这将有助于使您的问题更清楚。

      现在,您首先必须遍历数组以确定哪些元素为 0,并记录每个 0 元素的放置位置。然后,您生成一个随机数来确定应该选择哪个 0 元素:

      //determines amt of 0s in array
      ArrayList<ArrayList<int>> keys = new ArrayList<>();
      for (int i = 0; i < array.length; i++) {
          ArrayList<int> inner = new ArrayList<int>();
          for (int j = 0; j < array[i].length; j++) {
              if (i == 0) { inner.add(j); }
          }
          keys.add(inner);
      }
      
      Random r = new Random();
      //TODO: generate random number, determine which element to pick
      

      希望这会有所帮助。

      【讨论】:

        【解决方案5】:

        这个解决方案可能有点长,但很有效。我试图用 java 流来解决这个问题:

        首先您需要将 2D 数组转换为简单的 IntStream。最简单的方法可能是:

        Arrays.stream(arr).flatMapToInt(intArr -> Arrays.stream(intArr));
        

        我们的流现在看起来像这样:

        {5,0,0,0,5,0,4,0,0,4,7,9...}
        

        接下来,您需要获取具有键值(在本例中为索引值)等值的流。这对流来说非常困难,可能有更简单的解决方案,但我创建了一个具有自动递增索引的 KeyValue 类:

        class KeyValue {
            int index;
            int value;
            static int nextIndex;
        
            public KeyValue(int v) {
                this.index = nextIndex;
                nextIndex++;
                this.value = v;
            }
            public static void restart() {
                nextIndex = 0;
            }
        }
        

        现在很容易将我们的流转换为索引值项。调用:

        .mapToObj(KeyValue::new)
        

        现在我们的流看起来像这样:

        {KeyValue[i=0 v=5], KeyValue[i=1 v=0], KeyValue[i=2 v=0], KeyValue[i=3 v=0]...}
        

        现在过滤零并将流收集到一个数组:

        .filter(kv -> kv.value == 0).toArray(KeyValue[]::new);
        

        创建数组的整个代码是:

        KeyValue[] zeros = Arrays
                        .stream(arr)
                        .flatMapToInt(intArr -> Arrays.stream(intArr))
                        .mapToObj(KeyValue::new)
                        .filter(k -> k.value == 0)
                        .toArray(KeyValue[]::new);
        

        现在很容易从数组中获取随机值:

        int ourResult = zeros[random.nextInt(zeros.length)].index;
        

        整个代码如下所示:

        int[][] arr = new int[][]
                    {
                            {5, 0, 0, 5, 0},
                            {4, 0, 0, 4, 7},
                            {9, 0, 4, 8, 9},
                            {0, 8, 4, 0, 1}
                    };
            Random random = new Random();
            KeyValue.restart();
            KeyValue[] zeros = Arrays
                    .stream(arr)
                    .flatMapToInt(intArr -> Arrays.stream(intArr))
                    .mapToObj(KeyValue::new)
                    .filter(k -> k.value == 0)
                    .toArray(KeyValue[]::new);
            int ourResult = zeros[random.nextInt(zeros.length)].index;
        

        编码愉快:)

        【讨论】:

          【解决方案6】:

          我一直在寻找这个答案,并在处理过程中想出了这个:

          // object to hold some info
          class Point {
              // public fields fine for Point object
              public int i, j, count;
              // constructor
              public Point (int i, int j) {
                  this.i = i;
                  this.j = j;
                  this.count = 0;
              }
          
              public String toString() {
                  return i + " , " + j;
              }
          }
          int[][] grid;
          
          // processing needs to init grid in setup
          void setup() {
              // init grid
              grid = new int[][] {
              {5,1,2},
              {3,4,4},
              {4,0,1}
              };
          println(getRandomZero(new Point(0,0)));
          }
          
          // recursion try for 300 random samples
          Point getRandomZero(Point e) {
              // base case
              Point p = e;
              if (grid[p.i][p.j] != 0 && p.i < grid.length && p.j < grid[p.i].length) {
                  p.i = randomInt(0,grid.length);
                  p.j = randomInt(0,grid[p.i].length);
                  p.count++;
          // if can't find it in 300 tries return null (probably not any empties)
                  if (p.count > 300) return null;
                  p = getRandomZero(p);
              }
              return p;
          }
          // use Random obj = new Random() for Java
          int randomInt(int low, int high) {
              float random = random(1);
              return (int) ((high-low)*random)+low;
          }
          

          我明天会专门针对 Java 进行编辑。

          【讨论】:

            猜你喜欢
            • 2017-04-17
            • 1970-01-01
            • 2021-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-07
            相关资源
            最近更新 更多