【问题标题】:Java - Compare 2 int Arrays and judge them based on their values [closed]Java - 比较 2 个 int 数组并根据它们的值判断它们 [关闭]
【发布时间】:2012-11-07 19:27:27
【问题描述】:

我有一组 2 个包含相同数量数字的 int 数组

例如

int[] array1 = {1,3,5,5,2}
int[] array2 = {5,3,4,4,4}

我需要根据 2 个标准来比较它们

  1. 有多少元素在同一索引上具有相同的值
  2. 有多少元素在不同的索引上有相同的值

并返回一个表示值的整数数组

我有几个例子让你更好地理解:

   int[] array0 = {1,3,5,5,2};
   int[] array1 = {5,3,4,4,4};
   int[] array2 = {5,3,4,4,5};
   int[] array3 = {2,3,2,2,4};
   int[] array4 = {5,5,2,1,3};
   int[] array5 = {3,1,5,5,2};
   int[] array6 = {1,3,5,5,2};

   compare(array0,array1); //this would return 1,1
   compare(array0,array2); //this would return 1,2
   compare(array0,array3); //this would return 1,1
   compare(array0,array4); //this would return 0,5
   compare(array0,array5); //this would return 3,2
   compare(array0,array6); //this would return 5,0

对于第一个数字很简单,我只需要检查 array1 的索引 i 上的元素是否与 array2 中的相同。

我在生成第二个数字时遇到问题,因为应该从其中一个数组中取最小的数字。 如果我只看 array1 的元素是否在 array2 中的某个地方,它在某些情况下会产生错误的结果。

如果你看

int[] array1 = {1,3,5,5,2}

int[] array3 = {2,3,2,2,4};

并检查array1是否与array3在索引上的内容相同,它会返回3个数字相等但在不同的位置这是错误的,因为它应该从最小的数字开始判断,结果应该是1。

如果我切换它来比较 array3 在某个索引上是否与 array1 具有相同的内容,它适用于这种情况,但不适用于其他情况。

关于如何解决这个问题的任何想法,我很无能为力?

【问题讨论】:

  • 为什么不使用 Java 中比数组更强大的机制 - 集合框架

标签: java arrays compare


【解决方案1】:
  • 克隆两个输入整数数组。

  • 检查元素在同一索引上是否具有相同的值。

  • 如果是这样,将 1 添加到同一索引计数器,并将输入整数数组中的值更改为 -1(或小于最小有效值的数字)。

  • 使用嵌套的 for 循环检查元素是否具有相同的值。换句话说,检查第一个整数数组的第一个元素和第二个整数数组的所有元素。跳过两个数组中具有相同索引的元素,并跳过小于最小有效值的元素。

  • 如果是这样,将 1 添加到不同的索引计数器,并将输入整数数组中的值更改为 -1(或小于最小有效值的数字)。

【讨论】:

    【解决方案2】:

    这应该可以解决问题:

    public void compare(int[] arrayA, int[] arrayB) {
        int sameIndex = 0;
        int diffIndex = 0;
        //Made two new empty arrays to save the status of each element in the corresponding array, whether it has been checked our not, if not, it'd be null.
        String[] arrayAstatus = new String[arrayA.length];
        String[] arrayBstatus = new String[arrayB.length];
        for (int i = 0; i < arrayA.length; i++) {            
            if (arrayA[i] == arrayB[i] || arrayAstatus[i] != null) {
                sameIndex++;
                continue;
            }
            for (int a = 0; a < arrayB.length; a++) {
                if (a == i || arrayBstatus[a] != null) {
                    continue;
                }
                if (arrayA[i] == arrayB[a]) {
                    arrayAstatus[i] = "checked";
                    arrayBstatus[a] = "checked";
                    diffIndex++;
                    break;
                }
            }
        }
        System.out.println(sameIndex + ", " + diffIndex);
    }
    

    【讨论】:

      【解决方案3】:

      也许对于第二种情况,您可以尝试从数组中删除数字并在发现它们匹配时跳出循环。您可以将临时数组设置为原始数组的值。然后对照array3 中的所有值检查array1[0] 的值。找到匹配项后,从两个数组中删除数字并检查 array1[1]array3 中的所有值。

      因此,当您检查 array1[4]array3[0] 时,您将得到匹配。然后您将删除这两个数字并跳出循环。 array1 中没有要检查的数字,因此结果将为 1。

      我认为这将解决计算相同值两次的问题。

      【讨论】:

        【解决方案4】:

        首先,这听起来是个非常糟糕的主意。不要返回一个数组,其中每个索引都意味着不同的和神秘的东西。制作两个方法:compareSameIndex(array, array) 和 compareDifferentIndex(array, array)。

        对于这些的实际实现,您可以检查第一个数组中的每个索引以查看它们是否出现在第二个数组中的任何位置,然后调用它只是 compare()。然后 compareDifferentIndex() 变成 compare()-compareSameIndex()。例如:

        public int compare (int[] array0, int[] array1) {
          int matches = 0;
          List<Integer> list1 = Arrays.asList(array1);
        
          for (int curInt : array0) {
            if (list1.contains(curInt)) {
              matches++;
            }
          }
          return matches;
        }
        
        public int compareSameIndex(int[] array0, int[] array1) {
          int matches = 0;
          for (int i=0; i < array0.length; i++) {
            if (array0[i] == array1[i]) {
              matches++
            }
          }
          return matches;
        }
        
        public int compareDifferentIndex(int[] array0, int[] array1) {
          return compare(array0, array1) - compareSameIndex(array0, array1);
        }
        

        对于相同数字出现两次时会发生什么,要求似乎有点模糊,但您可以将该逻辑构建到 compare() 中以适应。你也可以针对非常大的数组优化这个,你不会两次检查相同的数字,但这将是我会采取的一般方法。

        【讨论】:

          【解决方案5】:

          您可以拥有一个包含已访问数字的集合。你会这样:(不测试这段代码是否运行,只是给你一个想法)

          public int[] compare(int[] first, int[] second) {
               Set<Integer> numbersFoundInFirstArray = new LinkedHashSet<Integer>();
               Set<Integer> numbersFoundInSecondArray = new LinkedHashSet<Integer>();
               int inSameIndex = 0;
               int inDifferentIndex = 0;
          
               for (int i; i < first.length; i++) {
                   if (first[i] == second[i]) {
                       inSameIndex++;
                   }
                   if (numbersFoundInFirstArray.contains(second[i])) {
                       inDifferentIndex++;
                   }
                   if (numbersFoundInSecondArray.contains(first[i])) {
                       inDifferentIndex++;
                   }
                   numbersFoundInFirstArray.add(first[i]);
                   numbersFoundInSecondArray.add(second[i]);
               }
               return new int[] {inSameIndex, inDifferentIndex};
          }
          

          如果我没记错的话,集合中的包含比较有 O(1)。 Set 的属性是您将只有一个特定类型的元素。因此,如果您将 1 加两次,它将只有一个引用 1。这样,您将只测试当前数字是否已在另一个数组中找到:)

          【讨论】:

            【解决方案6】:

            检查参数只是一个好习惯。 可能有一些小的优化可以在这里完成,但是哈希可以让你存储你已经访问过的位置,这样就不会多次计算它们。

             private int[] compare(int[] arr1, int[] arr2){
                int same_index = 0;
                Hashtable differences = new Hashtable();
                int diff_count = 0;
                if (arr1.length != arr2.length){
                    throw new IllegalArgumentException("Array Size is not identical.");
                } else {
                   for(int count = 0; count < arr1.length; count++){
                      if (arr1[count] == arr2[count]{
                          same_index++;
                          differences.put(count, null);
                      } else {
                          for (int count2 = 0; count2 < arr1.length; count2++){
                              if(!differences.containsKey(count2) && arr1[count] == arr2[count2]){
                                  differences.put(count2, null);
                                  diff_count++;
                              }
            
                          }                  
                      }
                   }
                }
                int[] returnArray = new int[2];
                returnArray[0] = same_count;
                returnArray[1] = diff_count;
                return (returnArray);
             }
            

            【讨论】:

              【解决方案7】:

              您需要将所有数组转置为树状结构,该结构基本上将索引所有数组中的所有唯一值并存储指向它们在数组中的位置和哪个数组的指针。该树的基本蓝图结构是:

              uniqElemVal->arrayIndx->arrayID = true
              

              其中 uniqElemVal 将是 1,3,5,2 代表 1,3,5,5,2,2,3,4 代表 2,3,2,2,4 等,所有工会化

              arrayIndx 将是第一个数组 0 中的 1,对于 5 将是 2 和 3 等等。

              数组 ID 是任意的,可以让您键入每个数组,例如第一个为 1,第二个为 2,以此类推。

              所以在这种情况下:

              #1st array
              1->0->1
              3->1->1
              5->2->1
              5->3->1
              2->4->1
              
              #2nd array
              2->0->2    
              3->1->2 
              3->2->2
              2->3->2
              2->4->2
              4->5->2
              

              然后,当您遍历这棵树时,只要您有一个具有超过 1 个叶子的 2 级节点,这意味着该特定元素值在多个数组的特定位置存在匹配。

              我个人会将这棵树定义为

              HashMap<Integer, HashMap<Integer, ArrayList<Integer>>>
              

              因此,只要您有一个包含 >1 个元素的叶数组列表,就意味着您有一个匹配项

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-03-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-07-03
                • 1970-01-01
                相关资源
                最近更新 更多