查找数组中不同元素数量的最快方法

时间:2013-12-09 14:27:01

标签: c arrays

我有一个包含整数的方阵(不一定是不同的)。我需要以最快的方式找到其中不同元素的数量。我试图将整数存储在一维数组中,对其进行排序,然后找到不同元素的数量......但显然,它不够快。你能用C语言建议更好更快的程序吗?

5 个答案:

答案 0 :(得分:2)

最快的是非常依赖于您正在处理的数据,所涉及的结构的大小等。

你对整数可以采用的值有界限吗?如果是这样,那么保持一个由整数值索引的数组,初始化为零,跟踪该值在矩阵中的副本数量,可能是最快的,空间使用合理。

如果没有,那么可能使用哈希表来做类似的事情将是最快的。

但无论如何,为问题提供更精确的参数将非常有帮助。

答案 1 :(得分:1)

有界整数值0-99

矩阵尺寸300 x 300

int array[100];
int i;
int j;
int n_unique = 0;

for (i=0;i<300;i++) {
    if (n_unique == 100) break;
    for  (j=0;j<300;j++) {
        if (array[mat[i][j]] == 0) {
            array[mat[i][j]] = 1;
            n_unique++;
            if (n_unique == 100) break;
         }
    }
}

算法是O(n)

答案 2 :(得分:1)

我建议采用以下方法:

  1. 在矩阵中的值上创建一个散列图。
  2. 返回hashmap的大小作为结果。
  3. 此问题的时间复杂度将是创建hashmap所需的时间顺序。这不需要任何排序,并且比您使用的方法更有效。这种方法与输入数据的范围无关,这使得它更加通用。

    (我不擅长在C中实现内容)我将包含一个演示该方法的Java代码。

    class Distinct {
         public static void main(String ar[]) {
              int size;
              int matrix[][] = new int[size][size]; 
              // POPULATE THE MATRIX BY IMPLEMENTING CUSTOM METHOD
              populate(matrix); 
              // ALGORITHM:
              HashMap<Integer,Boolean> distinct = new HashMap<Integer,Boolean>();
              for(int i=0;i<size;i++) {
                  for(int j=0;j<size;j++) {
                      distinct.put(matrix[i][j],true);
                  }
              }
              System.out.println("Number of distinct elements:"+distinct.size());
         }
    }
    

    可以在此处找到有关在C中实现散列映射的指针:Implementing a HashMap

    我希望这有帮助!

答案 3 :(得分:0)

通常在任何算法的速度,内存和复杂性之间都存在折衷。正如其他人所说,您了解有关数据的信息越多,制作算法的速度就越快。假设您有1到100之间的数字(作为示例),您将能够使用此信息真正优化算法。

我花了很多时间来编写任何数据集通用的示例算法。这假设您的设置尺寸足够小或者您有足够的可用内存。基本上,短版本是分配具有与原始二维数组一样多的元素的数组。然后循环遍历原始数组并将唯一元素放入新数组中的框中。最后计算新数组中的元素数量:

#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
typedef int bool;
#define TRUE 1
#define FALSE 0

/* The actual algorithm function - finds the number of unique values */
int NumberUniqueValues(int **array, int width, int height)
{
  int i = 0, j = 0, k = 0, maxFilled = 0;
  bool wasFound = FALSE;
  int *newElements = malloc(sizeof(int) * width * height);

  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      wasFound = FALSE;
      for (k = 0; k < maxFilled; k++) {
        if (newElements[k] == array[i][j]) {
          wasFound = TRUE;
          break;
        }
      }

      if (!wasFound) newElements[maxFilled++] = array[i][j];
    }
  }

  /* Free space */
  free(newElements);
  return maxFilled;
}

int main ()
{
  /* variables */
  int i = 0, j = 0;
  int originalWidth = 10;
  int originalHeight = 10;

  /* initialize array */
  int **originalArray = (int **)malloc(originalHeight * sizeof(int*));
  for (i = 0; i < originalHeight; i++) {
    originalArray[i] = (int *)malloc(originalWidth * sizeof(int));
  }

  /* initialize random seed, then fill with random values */
  srand (time(NULL));
  for (i = 0; i < originalHeight; i++) {
    for (j = 0; j < originalWidth; j++) {
      originalArray[i][j] = rand() % 100;
    }
  }

  printf("Number unique values: %d\n", NumberUniqueValues(originalArray, originalWidth, originalHeight));

  /* Free space */
  for (i = 0; i < originalHeight; i++) free(originalArray[i]);
  free(originalArray);

  return 0;
}

同样,这可能不是您案例中最快的算法,因为我不知道所有细节,但它至少会起作用。祝你好运!

答案 4 :(得分:0)

首先,它取决于您对待阵列的方式。如果它是动态的,你可以使用2d数组作为1d数组,因为静态2d数组是1d数组,动态数组可以创建为1d数组。

const int M = 100;
const int N = 200;
int **a = NULL;
int i, j;

a = (int**) malloc(M * sizeof(int*) + N * M * sizeof(int));
a[0] = (int*)(a + M);
for (i = 1; i < M; i++) {
    a[i] = a[0] + i * N;
}
//code
free(a);

a[i][j] === a[0][i*num_of_columns + j]

所以,1d阵列有2种算法

typedef int T;
#define EQ(a, b) ((a)==(b))

void quadDiff(T *a, size_t *out_size) {
    size_t i, j;
    size_t size = *out_size;
    size_t pos = 0;
    int unique;

    for (i = 0; i < size; i++) {
        unique = 1;
            for (j = i; j > 0; j--) {
                if (EQ(a[i], a[j-1])) {
                    unique = 0;
                    break;
                }
            }
            if (unique) {
                a[pos++] = a[i];
        }
    }
    *out_size = pos;
}

void sortDiff(T *a, size_t item_size, size_t *out_size, int (*cmp)(const void *, const void *)) {
    size_t i;
    T prev = a[0];
    size_t pos = 0;
    qsort(a, *out_size, item_size, cmp);
    for (i = 0; i < *out_size; i++) {
        if (EQ(prev, a[i])) {
            continue;
        }
        prev = a[i];
        a[pos++] = a[i];
    }
    *out_size = pos;
}