【问题标题】:Create an array of values which appear in both given arrays java创建一个出现在两个给定数组java中的值数组
【发布时间】:2018-11-17 14:19:07
【问题描述】:

我需要创建一个数组,其值出现在两个给定数组中。

我正在考虑循环遍历每个数组并比较值,如果它们匹配,则增加一个“计数器”变量,该变量将是新数组的长度,循环遍历新数组并将值分配给数组元素。

我需要找出一个循环的解决方案,下面的代码是我目前所得到的

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

        int arr1[] = {2, 4, 5, 7, 9, 10};
        int arr2[] = {1, 2, 5, 6, 8};

        int counter = 0;
        int combined[] = new int[counter];

        for (int s = 0; s < arr1.length; s++) {
            for (int x = 0; x < arr2.length; x++) {
                for (int i = 0; i < combined.length; i++) {
                    if (arr1[s] == arr2[x]) {
                        counter++;
                        combined[i] = arr1[s];
                    }

                }
            }
            for (int i = 0; i < combined.length; i++) {
                System.out.print(combined[i] + " ");
            }
        }
    }
}

【问题讨论】:

  • 那么您面临的问题是什么?
  • I need to figure out a solution with a loop 你的意思是没有循环?
  • 你需要计数器做什么?
  • 我不能在没有数组大小的情况下在 Java 中声明一个数组,这就是我创建计数器变量的原因,以计算有多少匹配值将是数组的大小问题与这段代码是它不会在控制台中打印任何内容,最后一个循环应该打印出数组的变量
  • @Julia 我现在看到了。是的,您正在创建大小为 0 的数组。int combined[] = new int[counter]; 当您增加计数器时,此数组不会自行调整大小。而且我认为combined[i] = arr1[s]; 无论如何都会抛出异常。老实说,代码还有其他几个问题。

标签: java arrays algorithm loops for-loop


【解决方案1】:
public static int[] intersection(int[] arr1, int[] arr2) {
    Set<Integer> elements = IntStream.of(arr1).boxed().collect(Collectors.toSet());
    return IntStream.of(arr2).filter(elements::contains).toArray();
}

或者只使用int[]:

// create temporary array to not modify input data
int[] tmp = Arrays.copyOf(arr1, arr1.length);
Arrays.sort(tmp);

for(int v : arr2)
    if(Arrays.binarySearch(tmp, v) >= 0)
        System.out.print(v + " ");

【讨论】:

    【解决方案2】:

    第一个问题是您将 combined 数组初始化为 0,因此它不会包含任何内容,第二个问题是您有一个多个 for 循环,即 combined 数组上的一个循环。

    相反,您需要创建一个足够大的临时数组以覆盖所有可能的重复项,然后从临时数组复制到正确大小的数组。

    public static void main(String[] args) {
        int arr1[] = { 2, 4, 5, 7, 9, 10 };
        int arr2[] = { 1, 2, 5, 6, 8 };
    
        int min = Math.min(arr1.length, arr2.length); //We can never have more duplicates than the number of elements in the smallest array
        int counter = 0;
        int combined[] = new int[min];
    
        for (int s = 0; s < arr1.length; s++) {
            for (int x = 0; x < arr2.length; x++) {
                if (arr1[s] == arr2[x]) {
                    combined[counter] = arr1[s];
                    counter++;
                    break; //We have found a duplicate, exit inner for loop and check next digit in outer loop
                }
            }
        }
        int[] result = Arrays.copyOf(combined, counter); //This makes a copy of the array but only with the number of elements that are used
        for (int i = 0; i < result.length; i++) {
            System.out.print(result[i] + " ");
        }
    }
    

    如果您不想使用Arrays.copy,您可以自己进行复制,只需将该行替换为

    int[] result = new int[counter]
    for (int j = 0; j < counter; j++) {
        result[j] = combined[j];
    }
    

    【讨论】:

      【解决方案3】:

      如果您只想使用数组和迭代来解决这个问题, 你可以:

      1. 对输入数组进行排序:O(n log n)
      2. 遍历数组:O(n)

      代码:

      public static void main(String[] args) {
          ...
      
          // make sure input arrays are sorted
          Arrays.sort(arr1);
          Arrays.sort(arr2);
      
          List<Integer> common = new ArrayList<Integer>();
      
          int i = 0, j = 0;
          while (i < arr1.length && j < arr2.length) {
      
              int v1 = arr1[i];
              int v2 = arr2[j];
      
              if (v1 == v2) {
                  common.add(v1);
                  i++;
                  j++;
              } else if (v1 < v2) {
                  i++;
              } else {
                  j++;
              }
          }
      
          System.out.println(common);
      }
      

      在您前进的每次迭代中:

      • arr1 的索引 (i)
      • 或 arr2 的索引 (j)
      • 或两者兼有

      无 ArrayList 版本:

      public static void main(String[] args) {
          ...
      
          Arrays.sort(arr1);
          Arrays.sort(arr2);
      
          int found = 0;
          int[] common = new int[Math.min(arr1.length, arr2.length)];
      
          int i = 0, j = 0;
          while (i < arr1.length && j < arr2.length) {
      
              int v1 = arr1[i];
              int v2 = arr2[j];
      
              if (v1 == v2) {
                  common[found] = v1;
                  found++;
                  i++;
                  j++;
              } else if (v1 < v2) {
                  i++;
              } else {
                  j++;
              }
          }
      
          for (int k = 0; k < found; k++) {
              System.out.println("common: " + common[k]);
          }
      }
      

      【讨论】:

        【解决方案4】:

        给你:

        int[] intersection = IntStream.of(arr1)
                    .filter(v1 -> IntStream.of(arr2).anyMatch(v2 -> v2 == v1))
                    .toArray();
        

        【讨论】:

        • 谢谢,但是我还没有在课堂上学习过.filter()、.findAny()等方法,可惜我的老师不会接受这个方案。
        【解决方案5】:

        这样就可以了:

        public static void main(String[] args) {
        
            int arr1[] = { 2, 4, 5, 7, 9, 10 };
            int arr2[] = { 1, 2, 5, 4, 8 };
        
            int combined[] = new int[arr1.length];
        
            for (int x = 0; x < arr1.length; x++) {
                for (int i = 0; i < arr2.length; i++) {
                    if (arr1[x] == arr2[i]) {
                        combined[x] = arr1[x];
                    }
        
                }
            }
            for (int i = 0; i < combined.length; i++) {
                System.out.print(combined[i] + " ");
            }
        }
        
        1. 您不需要 3 个循环来查找两个数组之间的重复项。
        2. 在这里,外部循环遍历更大的数组 (arr1) 和内部循环 循环遍历较小的数组 (arr1)。
        3. combined 被定义为具有与较大数组相同的大小(以避免任何 ArrayOutOfBoundsException
        4. 嵌套循环完成后,combined 将只保存 使用arr1size 初始化重复条目以及一些零。 (作为练习,您可以更改循环以过滤掉仅指示重复项的非零元素!)

        【讨论】:

        • 它为[7,2, 4, 5, 7, 9, 10][ 1, 5, 4, 8,2 ] 提供了不正确的结果。此外,这些不会在组合数组之间留下间隙吗?
        • 感谢您指出。错过了包含内部循环的最后一个元素。现在解决了。关于0,它总是可以被删除/过滤掉,我也为此添加了一个注释。
        【解决方案6】:

        在 Java 8 中你可以尝试:

        public static void main(String[] args) {
                Integer[] arr1 = {2, 4, 5, 7, 9, 10};
                Integer[] arr2 = {1, 2, 5, 6, 8};
                List<Integer> integers = Stream.of(arr1)
                        .filter(Arrays.asList(arr2)::contains)
                        .collect(Collectors.toList());
                System.out.println(integers);
        }
        

        输出将是:

        [2, 5]
        

        【讨论】:

          猜你喜欢
          • 2016-10-05
          • 1970-01-01
          • 2022-11-17
          • 2019-01-26
          • 1970-01-01
          • 1970-01-01
          • 2019-03-11
          • 2014-02-09
          • 1970-01-01
          相关资源
          最近更新 更多