查找数组中每个元素的出现次数,并更新与每个元素相关的信息

时间:2012-11-05 17:52:41

标签: c arrays sorting

我有一个大的二维数组,array[length][2]length= 500000

array[i][0]= hex numberarray[i][1]= 01中,代表与每个十六进制数相关的一些信息。像这样:

array[i][0]    array[i][1]

e05f56f8           1

e045ac44           1

e05f57fc           1

e05f57b4           1

e05ff8dc           0

e05ff8ec           0

e05ff900           1

我想得到一个新的数组,它存储:十六进制数,出现次数,相同十六进制数的数组[i] [1]之和。

我写这样的代码:

//First Sort the array according to array[][0]

int x,y,temp1,temp2;
  for (x=lines_num1-2;x>=0;x--)
    {
      for (y=0;y<=x;y++)
       {
        if(array[y][0]>array[y+1][0])
         {
            temp1=array[y][0];
            array[y][0]=array[y+1][0];
            array[y+1][0]=temp1;

            temp2=array[y][1];
            array[y][1]=array[y+1][1];
            array[y+1][1]=temp2;                
          }
       }
   }

// generate the new_array[][]
int new_array[length][3];
int n=0;
for (n=0; n<length; n++){
   new_array[n][0]=0;
   new_array[n][1]=0;
   new_array[n][2]=0;
}
int prev = array[0][0];
new_array[0][0]=array[0][0];
new_array[0][1]=1;
new_array[0][2]=array[0][2];
for (k=1;k<length;k++)
  {
     if (array[k][0] == prev)
       {
         new_array[n][1]=new_array[n][1]+1;
         new_array[n][2]=new_array[n][2]+array[k][0];
       }else{
         prev = array[k][0];
         new_array[n+1][0]=array[k][0];
         new_array[n+1][1]=new_array[n+1][1]+1;
         new_array[n+1][2]=new_array[n+1][2]+array[k][0];
         n++;
       }
   } 

但是代码似乎不像我预期的那样工作。首先,排序太慢了。而且似乎无法生成正确的new_array。关于如何处理这个的任何建议。

3 个答案:

答案 0 :(得分:0)

就个人而言,我会写一个哈希函数来直接用十六进制值索引结果数组。然后很简单:

struct {
    unsigned int nocc;
    unsigned int nsum;
} result[/* ... */];

/* calculate the results */
for (i = 0; i < LENGTH; ++i) {
    int *curr = &array[i];
    unsigned int index = hash(curr[0]);    

    result[index].nocc++;
    result[index].nsum += curr[1];
}

如果要对数组进行排序,请不要重新发明轮子:使用标准C库中的qsort

答案 1 :(得分:0)

排序很慢,因为您使用冒泡排序来对数据进行排序。冒泡排序具有二次平均复杂度,这意味着它必须执行超过1000亿次比较和交换以对数组进行排序。出于这个原因,never use bubble sort。相反,请学会使用qsort库函数并将其应用于您的问题。

此外,您的排序代码至少有一个错误:在为数组的第二列交换值时,您将获得具有错误列索引的值,[3]而不是[1]。< / p>

答案 2 :(得分:0)

对于您的场景,插入排序是正确的解决方案,在进行插入时,您可以创建#count和总和。排序完成后,您也将获得结果数组。

代码可能看起来像这样

int hex = 0, count = 0, sum = 0, iHole;
for (i=1; i < lines_num1 -1; i++)
{
     hex = array[i][0];
     count = array[i][1];
     sum = array[i][2];

     iHole = i
     // keep moving the hole to next smaller index until A[iHole - 1] is <= item
     while (iHole > 0 and array[iHole - 1][0] > hex)
       {
         // move hole to next smaller index
         A[iHole][0] = A[iHole - 1][0];
         A[iHole][1] = A[iHole - 1][1];
         A[iHole][2] = A[iHole - 1][2];
         iHole = iHole - 1
       }
     // put item in the hole
      if (array[iHole][0] == hex) 
      {
        array[iHole][1]++;
        array[iHole][2] += array[iHole][0];
       }
      else 
      {
        array[iHole][0]  = hex;
        array[iHole][1]  = 1;
        array[iHole][2]  = hex;
      }

   }

因此,制作第二个阵列的成本是分拣本身的成本。 O(n)最好的情况,O(n ^ 2)最坏的情况,你不必再去旅行来计算和计算。

请记住,这种排序是一种原位排序。如果您不想影响原始数组,那么iHole指向新数组也是如此。 iHole应该指向新数组的尾部而不是“i”