【问题标题】:Finding if a multidimensional array is within an array Java查找多维数组是否在数组Java中
【发布时间】:2022-01-15 22:07:59
【问题描述】:

我有一个数组 - 类似于:

import java.util.Arrays;

public class test {
    public static void main(String[] args)
    {

        String[][] A = { { "a", "b", "c" }, { "d", "e", "f" }, { "g", "h", "-" } };
        String[][] B = { { "-", "e", "b" }, { "a", "h", "c" }, { "d", "g", "f" } };
        String[][] C = { { "a", "b", "c" }, { "d", "e", "f" }, { "g", "h", "-" } };
        String[][][] myArray = { A, B};

        for (String[][] s : myArray) {
            System.out.println(Arrays.deepToString(s));
            if (Arrays.deepToString(s).equals(Arrays.deepToString(C))) {
                System.out.println("true");
            }
        }
    }
}

我需要检查一个值是否在数组中,但是,这是我发现的唯一可行的方法,而且效率很低。

由于大多数内置方法似乎不起作用,有没有更好的方法来做到这一点?

我也尝试使用 Set 并且遇到了同样的问题。

【问题讨论】:

    标签: java arrays


    【解决方案1】:

    这很简单:永远不要转换为字符串。试试deepEquals,它应该可以满足您的需求,当然您首先必须深入了解您的myArray 并遍历元素。

    public static boolean contains(String[][][] set, String[][] obj) {
        for (String[][] elt : set) {
            if (Arrays.deepEquals(elt, obj)) {
                return true;
            }
        }
        return false;
    }
    

    这会在大约 4.5% 的时间内为您的测试集执行包含功能。


    当涉及到对象数组(包括其他数组)时,Java 具有类型擦除功能。因此,在使用 Arrays.equals(String[], String[]) 的地方自己创建 deepEquals(String[][], String[][]) 可能会稍微快一些,因为您不必在运行时检查对象是否是 String 的数组,也不必检查是否有任何数组嵌套更深。

    public static boolean fasterContains(String[][][] set, String[][] obj) {
        for (String[][] elt : set) {
            if (deepEquals(elt, obj)) {
                return true;
            }
        }
        return false;
    }
    
    private static boolean deepEquals(String[][] a, String[][] b) {
        int n = a.length;
        if (b.length != n) {
            return false;
          }
          
         for (int i = 0; i < n; i++) {
            if (!Arrays.equals(a[i], b[i])) {
                return false;
            }
        }
        return true;
    }
    

    这会在大约 3.5% 的时间内为您的测试集执行包含功能,同时仅比上述测试稍微复杂一些。


    作为一般提示:计算机在字符串方面效率不高(尽管较新的 Java 版本确实在一定程度上解决了这个问题)。无论如何,永远不要转换为字符串以进行任何比较、计算、连接或诸如此类的事情。除非真的没有其他办法,否则总是比较字节、整数或对象(即原始数据)。


    如果您只有一个字符列表,那么有两个观察结果:

    • char[][] 也应该可以工作;
    • 当然也可以只是String[],其中字符串由各种字符组成(您可以使用String#charAt(index) 检索并使用String#equals(other) 进行比较。

    使用后者,您可以将搜索时间减少到 2% 左右。

    【讨论】:

      【解决方案2】:

      另一种方法是将数组存储/散列为 StringBuilder 并将其与多维数组中形成的 StringBuilder 进行比较。

      与 String 相比,StringBuilder 对 String 操作的速度更快。代码如下:

      import java.util.Arrays;
      
      public class test {
          public static void main(String[] args)
          {
      
              String[][] A = { { "a", "b", "c" }, { "d", "e", "f" }, { "g", "h", "-" } };
              String[][] B = { { "-", "e", "b" }, { "a", "h", "c" }, { "d", "g", "f" } };
              String[][] C = { { "a", "b", "c" }, { "d", "e", "f" }, { "g", "h", "-" } };
              String[][][] myArray = { A, B};
              StringBuilder str = new StringBuilder();
              StringBuilder str1 = new StringBuilder();
              for(String[] ss : C){
                  for(String s : ss){
                      for(char p : s.toCharArray()){
                                  str1.append(p);
                              }
                  }
              }
              String cc = str1.toString();
              for(String[][] s : myArray){
                  for(String[] ss : s){
                      for(String sss : ss){
                          for(char p : sss.toCharArray()){
                              str.append(p);
                          }
                          if(str.toString().equals(cc)){
                              System.out.println("true");
                          }
                      }
                  }
              }
              
          }
      }
      

      【讨论】:

      • 好的,但它仍然只运行 60% 的时间。这当然是一个加速,但没有任何接近 20-50 的加速,你可以通过简单地不转换为字符串来实现。最后,它仍然是一个字符串化的解决方案,具有很多不必要的复杂性。尽管如此,还是投了赞成票,因为速度越快。
      猜你喜欢
      • 2020-05-02
      • 2014-05-28
      • 2014-10-14
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多