我有一个包含整数的方阵(不一定是不同的)。我需要以最快的方式找到其中不同元素的数量。我试图将整数存储在一维数组中,对其进行排序,然后找到不同元素的数量......但显然,它不够快。你能用C语言建议更好更快的程序吗?
答案 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)
我建议采用以下方法:
此问题的时间复杂度将是创建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;
}