Java 如何将两个数组之间的交集作为新数组获取?

Java 如何将两个数组之间的交集作为新数组获取?,java,c++,c,algorithm,Java,C++,C,Algorithm,在各种情况下,我多次遇到这个问题。它对所有编程语言都是通用的,尽管我熟悉C或Java 让我们考虑两个数组(或集合): 如何将两个数组之间的公共元素作为新数组获取? 在这种情况下,数组A和B的交集是char[]c={'c','d'} 我希望避免一个数组在另一个数组中重复迭代,这将 将执行时间增加(A的长度乘以B的长度),这对于大型阵列来说太多了 我们有没有办法在每个数组中进行一次传递以获得公共元素 foreach element e in array A insert e into has

在各种情况下,我多次遇到这个问题。它对所有编程语言都是通用的,尽管我熟悉C或Java

让我们考虑两个数组(或集合):

如何将两个数组之间的公共元素作为新数组获取? 在这种情况下,数组A和B的交集是
char[]c={'c','d'}

我希望避免一个数组在另一个数组中重复迭代,这将 将执行时间增加(A的长度乘以B的长度),这对于大型阵列来说太多了

我们有没有办法在每个数组中进行一次传递以获得公共元素

foreach element e in array A
    insert e into hash table H

foreach element e in array B
    if H contains e 
        print e
该算法在时间上是
O(N)
,在空间上是
O(N)

为了避免额外的空间,可以使用基于排序的方法

  • 对两个数组进行排序
  • 然后执行循环,直到它们具有公共元素或其中一个数组到达其末端

  • 渐进地,这需要排序的复杂性。i、 e.O(NlogN),其中N是较长输入数组的长度。

    最好的方法是根本不要从数组开始。数组对于元素的随机访问是最优的,但对于搜索(这就是寻找交集的全部内容)不是最优的。当您谈论交叉点时,必须将阵列视为集合。因此,请使用更合适的数据结构(在Java中,是一个
    )。这样任务就更高效了。

    您可以使用tree,但时间将是O(n(logn)),元素必须具有可比性

    我知道一些语言中有一些方法可以完全满足您的需要,您考虑过其中一些实现吗

    PHP-

    爪哇-


    因为在我看来这就像一个字符串算法,所以我暂时假设不可能对这个序列(因此是字符串)进行排序,然后您可以使用

    假设输入大小不变,则问题的复杂性为O(nxm),(两个输入的长度)

    publicstaticvoidmain(String[]args){
    char[]a={'a','b','c','d'};
    char[]b={'c','d','e','f'};
    系统输出println(相交(a,b));
    }
    私有静态集相交(char[]a,char[]b){
    Set aSet=newhashset();
    Set intersection=新HashSet();
    用于(字符c:a){
    附加条款(c);
    }
    用于(字符c:b){
    如果(aSet.包含(c)){
    添加(c);
    }
    }
    折返交叉口;
    }
    
    效率的下限是O(n)-您至少需要读取所有元素。 然后有几种方法:

    最简单的方法 在数组2中搜索数组1中的每个元素。时间复杂度O(n^2)

    排序方法 您只需要对数组1进行排序,然后使用二进制搜索从数组2中搜索元素。时间复杂度:排序O(nlogn),搜索O(n*logn)=O(nlogn),总O(nlogn)

    散列方法 从数组元素创建哈希表。从哈希表中的第二个表中搜索元素。时间复杂度取决于哈希函数。您可以在最佳情况下(所有元素将具有不同的哈希值)实现O(1),但在最坏情况下(所有元素将具有相同的哈希值)实现O(n)。总时间复杂度:O(n^x),其中x是哈希函数效率的一个因子(介于1和2之间)

    一些散列函数保证构建一个没有冲突的表。但建筑不再严格按照O(1)的时间来计算每个元素。在大多数情况下都是O(1),但如果表已满或遇到冲突,则需要重新刷新该表—需要O(n)时间。这种情况并不经常发生,比clean adds少得多。因此,摊销时间复杂度为O(1)。我们不关心某些加法需要O(n)时间,只要大多数加法需要O(1)时间

    但即便如此,在极端情况下,每次插入表都必须重新刷新,因此严格的时间复杂度将是O(n^2)

    GoogleGuava 对于这一点,已经有很多很好的答案,但是如果您想要使用一个库进行惰性编码的单行程序方法,我会选择(对于Java)及其方法

    (手头没有编译器,请耐心等待)

    char[]A={'A','b','c','d'};
    char[]B={'c','d','e','f'};
    集合交点=集合交点(
    Sets.newHashSet(Chars.asList(a)),
    Sets.newHashSet(Chars.asList(b))
    );
    
    显然,这是假设两个数组都不会有重复项,在这种情况下,使用集合数据结构将更有意义,并允许更有效地执行此类操作,特别是如果您不从一开始就从一个基元数组开始


    可能适合您的用例,也可能不适合您的用例,但对于一般情况来说,这是一种不需要动脑筋的方法。

    如果您关心重复项,请使用哈希映射对列表a进行索引,键是元素,值是该元素已被看到的次数

    迭代第一个元素,如果映射中不存在该元素,则将其放入其中,值为1;如果映射中已存在该元素,则将其添加到该值

    接下来,迭代B,如果该值存在,则减去1。如果不是,则在表中该元素的值中输入-1

    最后,遍历映射并对任何具有值的元素进行迭代!=0,打印为差异

    private static <T> List<T> intersectArrays(List<T> a, List<T> b) {
        Map<T, Long> intersectionCountMap = new HashMap<T, Long>((((Math.max(a.size(), b.size()))*4)/3)+1);
        List<T> returnList = new LinkedList<T>();
        for(T element : a) {
            Long count = intersectionCountMap.get(element);
            if (count != null) {
                intersectionCountMap.put(element, count+1);
            } else {
                intersectionCountMap.put(element, 1L);
            }
        }
        for (T element : b) {
            Long count = intersectionCountMap.get(element);
            if (count != null) {
                intersectionCountMap.put(element, count-1);
            } else {
                intersectionCountMap.put(element, -1L);
            }            
        }
        for(T key : intersectionCountMap.keySet()) {
            Long count = intersectionCountMap.get(key);
            if (count != null && count != 0) {
                for(long i = 0; i < count; i++) {
                    returnList.add(key);
                }
            }
        }
        return returnList;
    }
    
    私有静态列表数组(列表a、列表b){
    Map intersectionCountMap=newhashmap(((Math.max(a.size(),b.size())*4)/3)+1);
    List returnList=新建LinkedList();
    对于(T元素:a){
    Long count=intersectionCountMap.get(元素);
    如果(计数!=null){
    intersectionCountMap.put(元素,计数+1);
    }否则{
    交叉计数映射。放置(元素,1L);
    }
    }
    对于(T元素:b){
    长计数=整数
    
    $array1 = array("a" => "green", "red", "blue");
    $array2 = array("b" => "green", "yellow", "red");
    $result = array_intersect($array1, $array2);
    print_r($result);
    
    >> green
       red
    
    Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
    Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));
    
    listOne.retainAll( listTwo );
    System.out.println( listOne );
    
    >> dingo, hafil, iga
    
        public static void main(String[] args) {
            char[] a = {'a', 'b', 'c', 'd'};
            char[] b = {'c', 'd', 'e', 'f'};
            System.out.println(intersect(a, b));
        }
    
        private static Set<Character> intersect(char[] a, char[] b) {
            Set<Character> aSet = new HashSet<Character>();
            Set<Character> intersection = new HashSet<Character>();
            for (char c : a) {
                aSet.add(c);
            }
            for (char c : b) {
                if (aSet.contains(c)) {
                    intersection.add(c);
                }
            }
            return intersection;
        }
    
    char[] A = {'a', 'b', 'c', 'd'};
    char[] B = {'c', 'd', 'e', 'f'};
    
    Set<Character> intersection = Sets.intersection(
        Sets.newHashSet<Character>(Chars.asList(a)),
        Sets.newHashSet<Character>(Chars.asList(b))
    );
    
    private static <T> List<T> intersectArrays(List<T> a, List<T> b) {
        Map<T, Long> intersectionCountMap = new HashMap<T, Long>((((Math.max(a.size(), b.size()))*4)/3)+1);
        List<T> returnList = new LinkedList<T>();
        for(T element : a) {
            Long count = intersectionCountMap.get(element);
            if (count != null) {
                intersectionCountMap.put(element, count+1);
            } else {
                intersectionCountMap.put(element, 1L);
            }
        }
        for (T element : b) {
            Long count = intersectionCountMap.get(element);
            if (count != null) {
                intersectionCountMap.put(element, count-1);
            } else {
                intersectionCountMap.put(element, -1L);
            }            
        }
        for(T key : intersectionCountMap.keySet()) {
            Long count = intersectionCountMap.get(key);
            if (count != null && count != 0) {
                for(long i = 0; i < count; i++) {
                    returnList.add(key);
                }
            }
        }
        return returnList;
    }
    
    char[] A = {'a', 'b', 'c', 'd'};
    char[] B = {'c', 'd', 'e', 'f'};
    int[] charset = new int[256]
    
    for(int i=0; i<A.length; i++) {
      charset[A[i]]++;
    }
    
    int s[256] // for considering all ascii values, serves as a hash function
    
    for(int i=0;i<256;i++)
    s[i]=0;
    
    char a[]={'a','b','c','d'};
    char b[]={'c','d','e','f'};
    
    for(int i=0;i<sizeof(a);i++)
    {
       s[a[i]]++;
     }
    
     for(int i=0;i<sizeof(b);i++)//checker function
     {
         if(s[b[i]]>0)
           cout<<b[i]; 
      }
    
    
      complexity O(m+n);
      m- length of array a
      n- length of array b
    
    a = ['a', 'b', 'c', 'd']
    b = ['c', 'd', 'e', 'f']
    c = a & b
    
    HashSet<int> set1 = new HashSet<int>(new int[]{8, 12, 13, 15});
    
    HashSet<int> set2 = new HashSet<int>(new int[] { 15, 16, 7, 8, 9 });
    
    set1.IntersectWith(set2);
    
    foreach (int i in set1)
    
       Console.Write(i+ " ");
    
    public static void printArr(int[] arr){
        for (int a:arr){
            System.out.print(a + ", ");
        }
        System.out.println();
    }
    
    public static int[] intersectionOf(int[] arr1, int[] arr2){
        Arrays.sort(arr1);
        Arrays.sort(arr2);
    
        printArr(arr1);
        printArr(arr2);
    
        int i=0, j=0, k=0;
        int[] arr = new int[Math.min(arr1.length, arr2.length)];
    
        while( i < arr1.length && j < arr2.length){
            if(arr1[i] < arr2[j]){
                i++;
            } else if(arr1[i] > arr2[j]){
                j++;
            } else {
                arr[k++] = arr1[i++];
                j++;
            }
        }
        return Arrays.copyOf(arr, k);
    }
    
    public static void main(String[] args) {
        int[] arr1 = {1, 2, 6};
        int[] arr2 = {10, 2, 5, 1};
        printArr(intersectionOf(arr1,arr2));
    }
    
    arr1: 1, 2, 6, 
    arr2: 1, 2, 5, 10, 
    arr: 1, 2, 
    
    public class IntersectionOfUnsortedArrays {
        public static void main(String[] args) {
            int[] arr1 = { 12, 4, 17 };
            int[] arr2 = { 1, 12, 7, 17 };
            System.out.println("Intersection Using Simple Comparision");
            printArray(simpleIntersection(arr1, arr2));
            System.out.println("Intersection Using Sort and Binary Search");
            printArray(sortingBasedIntersection(arr1, arr2));
        }
    
        /*
         * Simple intersection based on the comparison without any sorting.
         * Complexity O(n^2)
         */
        public static int[] simpleIntersection(int[] a, int[] b) {
            int minlen = a.length > b.length ? b.length : a.length;
            int c[] = new int[minlen];
            int k=0;
            for(int i=0;i<a.length;i++){
                for(int j=0;j<b.length;j++){
                    if(a[i]==b[j]){
                        c[k++]=a[i];
                    }
                }
            }
            int arr[] = new int[k];
            // copy the final array to remove unwanted 0's from the array c
            System.arraycopy(c, 0, arr, 0, k);
            return arr;
        }
    
        /*
         * Sorting and Searching based intersection.
         * Complexity Sorting O(n^2) + Searching O(log n)
         */
    
        public static int[] sortingBasedIntersection(int[] a, int[] b){
            insertionSort(a);
            int minlen = a.length > b.length ? b.length : a.length;
            int c[] = new int[minlen];
            int k=0;
            for(int i=0;i<b.length;i++){
                int result = binarySearch(a,0,a.length,b[i]);
                if(result > -1){
                    c[k++] = a[result];
                }
            }
            int arr[] = new int[k];
            // copy the final array to remove unwanted 0's from the array c
            System.arraycopy(c, 0, arr, 0, k);
            return arr;
        }
    
        public static void insertionSort(int array[]) {
            for (int i = 1; i < array.length; i++) {
                int j = i;
                int b = array[i];
                while ((j > 0) && (array[j - 1] > b)) {
                    array[j] = array[j - 1];
                    j--;
                }
                array[j] = b;
            }
        }
    
        static int binarySearch(int arr[], int low, int high, int num) {
            if (high < low)
                return -1;
            int mid = (low + high) / 2;
            if (num == arr[mid])
                return mid;
            if (num > arr[mid])
                return binarySearch(arr, (mid + 1), high, num);
            else
                return binarySearch(arr, low, (mid - 1), num);
        }
    
        public static void printArray(int[] array) {
            for (int value : array) {
                System.out.print(" "+value);
            }
            System.out.println("\n");
        }
    }
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    public class Dup {
      public static void main(String[] args) {
        List<Integer> listA = Arrays.asList(3, 1, 4, 1, 9, 5, 9);
        List<Integer> listB = Arrays.asList(2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3);
        findCommons(listA, listB);
      }
    
      static void findCommons(List<Integer> listA, List<Integer> listB) {
        Map<Integer, Long> mapA = 
            listA.stream().collect(
                Collectors.groupingBy(Integer::intValue, Collectors.counting()));
    
        List<Integer> commons = new ArrayList<>();
        listB.stream()
            .filter(e -> mapA.get(e) != null)
            .filter(e -> mapA.get(e) > 0)
            .forEach(e -> {
                mapA.put(e, mapA.get(e) - 1);
                commons.add(e);
            });
    
        System.out.println(commons);
      }
    }
    
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        // display common element in two diffrent array
        int sizea,sizeb,i=0,j=0,k=0;
        int count=0;
        System.out.println("enter the size array A:"+'\n');
        sizea=sc.nextInt();
        System.out.println("enter the size array B"+'\n');
        sizeb=sc.nextInt();
        int a[]=new int[sizea];
        int b[]=new int[sizeb];
        int c[]=new int[sizea];
    
    
        System.out.println("enter the element in array A:"+'\n');
        for (i = 0; i < sizea; i++) {
    
            a[i]=sc.nextInt();
        }
        System.out.println("enter the element in array B:"+'\n');
        for (i = 0; i < sizeb; i++) {
    
            b[i]=sc.nextInt();
        }
        System.out.println("the element in array A:"+'\n');
        for (i = 0; i < sizea; i++) {
    
            System.out.print(a[i]+" ");
    
        }
        System.out.println('\n');
        System.out.println("the element in array B:"+'\n');
        for (i = 0; i < sizeb; i++) 
        {
    
            System.out.print(b[i]+" ");
        }
    
        for (i = 0; i <sizea; i++) 
        {
            for (j = 0; j < sizeb; j++) 
            {
               if(a[i]==b[j])
               {
                   count++;
                   c[k]=a[i];
                   k=k+1;
               }
            }
        }
        System.out.println('\n');
        System.out.println("element common in array is");
    
        if(count==0)
        {
            System.out.println("sorry no common elements");
        }
        else
        {
            for (i = 0; i <count; i++) 
            {
    
            System.out.print(c[i]+" ");
            }
        }
    
    }
    
        simply search each element of first array with each element of second array and stored matched result in third array
    class Union
    {
      public static void main(String[] args) {
      char a[] ={'f','g','d','v','a'};
      char b[] ={'a','b','c','d','e'};
      char temp[] = new char[5];
      int p=0;
      for(int i=0;i<a.length;i++)
      {
        for(int j=0;j<b.length;j++)
        {
          if(a[i]==b[j])     //searches if both array has common element
          {
    
            temp[p] = a[i];   //if match found store it in a new array
            p++;
          }
    
        }
    
      }
      for(int k=0;k<temp.length;k++)
      {
          System.out.println(temp[k]);
      }
    
      }
    }