C: Print only not common elements in 2 arrays

◇◆丶佛笑我妖孽 提交于 2019-12-23 06:00:59

问题


I have some C code I want to modify really simple.

Let's say I have two arrays like this

   int v1[5] = {1, 3, 7, 13, 10};
   int v2[2] = {1, 10};

And I would like to print the not common elements (difference) like:

3, 7, 13

Here is my attempt which is not enough yet:

#include <stdio.h>

int main()
{
    int v1[5] = { 1, 3, 7, 13, 10 };
    int v2[2] = { 1, 10 };

    for (int i = 0; i < sizeof(v1) / (sizeof * v1); i++) {
        for (int j = 0; j < sizeof(v2) / (sizeof * v2); j++) {
            if (v1[i] != v2[j]) {
                printf("%d ", v1[i]);
                break;
            } else {
                break;
            }
        }
    }

    return 0;
}

The two arrays will be always really short (max 6 elements). Thery are not ordered and I should not modify them. The elements in each of them are unique, that is each number can only appear 1 time in each array. v2 will only contains a subset of element from v1. What would be the most efficient way to achieve this?


回答1:


You could start by taking any array and iterating it element by element and finding if that element is in second array too by a nested for loop and putting an if condition in the inner for loop and storing the common element in another array and then comparing both of the array one by one with that array and putting uncommon element in another array.

Like:

int a[min(l1,l2)], b[l], x = 0, k = 0, flag = 1;
for(int i=0; i<l1; i++){
for(int j=0; j<l2; j++){
    if(v1[i]==v2[j]){
        a[k] = v1[i];
        k++;
    }
}
}
for(int i=0; i<l1; i++){
flag = 1;
for(int j=0; j<k; j++){
    if(v1[i] == a[j]){
      flag = 0;
      break;
    }
}
if(flag==1){
    b[x] = v1[i];
    x++;
}
}

for(int i=0; i<l2; i++){
flag = 1;
for(int j=0; j<k; j++){
    if(v2[i] == a[j]){
      flag = 0;
      break;
    }
}
if(flag==1){
    b[x] = v2[i];
    x++;
}
}

Afterwards you can print the array.




回答2:


An approach that is greedy in term of memory, but quick in terms of CPU cycles (linear time) is a histogram, as list comparisons in the trivial sense typically use quadratic execution complexity :(.

Code Listing


#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

int main(void) {

    /* Allocate. */
    int numElements1 = 0;
    int numElements2 = 0;

    const int maxHistVal = UINT8_MAX + 1;
    const int maxElements = 10;
    const int minElements = 1;
    uint8_t *arr1 = NULL, *arr2 = NULL;
    uint8_t *histogram = NULL;

    /* Init random seed. */
    srand(time(NULL));

    /* Determine number of elements for each array. */
    numElements1 = (rand() % (maxElements - minElements)) + minElements;
    numElements2 = (rand() % (maxElements - minElements)) + minElements;

    /* Generate two random arrays with non-duplicated values. */
    if (NULL == (arr1 = calloc(numElements1, sizeof(uint8_t)))) {
        return ENOMEM;
    } else if (NULL == (arr2 = calloc(numElements2, sizeof(uint8_t)))) {
        free(arr1);
        return ENOMEM;
    } else if (NULL == (histogram = calloc(maxHistVal, sizeof(uint8_t)))) {
        free(arr2);
        free(arr1);
        return ENOMEM;
    } else {
        /* Have our sample arrays and histogram. Populate them and print them
         * out.
         */
        printf("ARR1: ");
        uint8_t j = 0;
        for (int i = 0, j = 0; i < numElements1; i++) {
            /* Populate array. */
            j += (rand() % 2) + 1;
            arr1[i] = j;
            printf("%-3d ", arr1[i]);
            /* Update histogram. */
            histogram[arr1[i]]++;
        }
        printf("\n");
        printf("ARR2: ");
        for (int i = 0, j = 0; i < numElements2; i++) {
            /* Populate array. */
            j += (rand() % 2) + 1;
            arr2[i] = j;
            printf("%-3d ", arr2[i]);
            /* Update histogram. */
            histogram[arr2[i]]++;
        }
        printf("\n");
        /* Print out only values that appear exactly once in the histogram. */
        printf("HISTOGRAM: UNIQUE VALUES: ");
        for (int i = 0, j = 0; i < maxHistVal; i++) {
            /* Print histogram. */
            if (1 == histogram[i]) {
                printf("%-3d ", i);
            }
        }
        printf("\n");
        /* For fun, identify the duplicates. */
        printf("HISTOGRAM: DUPLICATE VALUES: ");
        for (int i = 0, j = 0; i < maxHistVal; i++) {
            /* Print histogram. */
            if (1 < histogram[i]) {
                printf("%-3d ", i);
            }
        }
    }

    /* Cleanup..*/
    free(histogram);
    free(arr2);
    free(arr1);

    return 0;
}

Sample Run


ARR1: 2   3   4   6   8   9   10  
ARR2: 1   2   3   4   
HISTOGRAM: UNIQUE VALUES: 1   6   8   9   10  
HISTOGRAM: DUPLICATE VALUES: 2   3   4  



回答3:


What would be the most efficient way to achieve this?

Should the range of values in a[], b[] be limited to 0 to 63, code could use an unsigned long long mask.

This iterates once through each array l1 + l2 operations, rather than a double for() loop with l1 * l2 operations.

#include <assert.h>
#include <stdio.h>

int main(void) {
  const int v1[5] = { 1, 3, 7, 13, 10 };
  const int v2[2] = { 1, 10 };

  unsigned long long mask = 0;
  for (size_t i = 0; i < sizeof(v2) / (sizeof *v2); i++) {
    assert(v2[i] >= 0 && v2[i] < 64);
    mask |= 1ull << v2[i];
  }
  mask = ~mask;
  for (size_t i = 0; i < sizeof(v1) / (sizeof *v1); i++) {
    assert(v1[i] >= 0 && v2[i] < 64);
    if ((1ull << v1[i]) & mask) {
      printf(" %d", v1[i]);
    }
  }
  puts("");
  return 0;
}

Output

 3 7 13



回答4:


#include<stdio.h>

#define MAX_OLD   4
#define MAX_NEW   2
int main()
{
   int old[] = {3, 4, 5, 6};
   int new[] = {4, 5};
   int temp[] = {0, 0, 0, 0, 0, 0, 0, 0};
   int j = 0,z=0,i=0;
   for(i = 0; i < MAX_NEW; i++)
   {
      for(; j < MAX_OLD; j++)
      {
         if(old[j] <= new[i])
         {
            if(old[j]!=new[i])
               temp[z++] = old[j];
         }
         else
         {
            break;
         }
      }
   }
   while(j<MAX_OLD)
      temp[z++]=old[j++];
   printf("Temp[0] : %d  %d %d %d %d %d %d %d\n",temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7]);
   return 0;
}


来源:https://stackoverflow.com/questions/41065651/c-print-only-not-common-elements-in-2-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!