我怎样才能提高效率呢? (在C中合并数组)

时间:2015-12-26 00:04:21

标签: c arrays performance

该程序应该合并两个数组并将它们放在一个输出数组中。我所拥有的是:

void Merge(int *arr1, int *arr2, int *output, int arr1size, int arr2size) { 
   int arr2count = 0, arr1count = 0;                                        
   while (arr1count < arr1size) {                                           
      if (arr2count >= arr2size) {   /* dump arr1 because arr2 is done */                                         
         *output++ = *arr1++;                                               
         arr1count++;                                                       
      }                                                                     
      else if (*arr1 < *arr2) {                                             
         *output++ = *arr1++;                                               
         arr1count++;                                                       
      }                                                                     
      else {                                                                
         *output++ = *arr2++;                                               
         arr2count++;                                                       
      }                                                                     
   }                                                                        
   while (arr2count++ < arr2size) {    /* dump arr2 */                                     
      *output++ = *arr2++;                                                  
   }                                                                        
}

如何才能提高效率?我的意思是,从字面上删除任何代码,以使其更有效。

出于争论的考虑,考虑三重while循环实现(如下所示)效率较低。

while (arr1count < arr1size && arr2count < arr2size) { .... }
while (arr1count < arr1size) { .... }
while (arr2count < arr2size) { .... }

此外,这必须使用指针表示法,而不是数组表示法(我希望...)

3 个答案:

答案 0 :(得分:3)

我尝试删除变量和增量。请注意,这些是次要改进,而算法仍需要O(m + n)时间。

编辑:结合了用户2048454

提到的循环中断

Edit2:删除了两个while循环并替换为memcpy。感谢FUZxxl

void Merge2(int *arr1, int *arr2, int *output, int *a1last, int *a2last) { 
   while (arr1 < a1last && arr2 < a2last) {
      if (*arr1 < *arr2) {                                             
         *output++ = *arr1++;                                                
      }                                                                     
      else {                                                                
         *output++ = *arr2++;                                               
      }                                                                     
   }                  
   /* Replaced while with memcpy () */
   memcpy(output,arr1,sizeof(int)*(a1last-arr1));
   memcpy(output,arr2,sizeof(int)*(a2last-arr2));                                                  
   }                                                                        
}

int main()
{
    int a[]={1,3,5,7};
    int b[]={2,4,6,8};
    int c[10];
    int i;
    Merge2(a,b,c,&a[4],&b[4]); //&a[4] points to the end address of the array. Do not access value at that address, it is "out of bounds"

    for(i=0; i<8; i++)
        printf("%d ",c[i]);

    printf("\n");

    return 0;
}

答案 1 :(得分:2)

这样的东西?

void Merge(int *arr1, int *arr2, int *output, int arr1size, int arr2size) {
  for (int i=0,i1=0,i2=0; i<arr1size+arr2size; i++) {
    if      (i1==arr1size) *output++ = *arr2++;
    else if (i2==arr2size) *output++ = *arr1++;
    else if (*arr1<*arr2)  *output++ = *arr1++, i1++;
    else                   *output++ = *arr2++, i2++;
  }
}

答案 2 :(得分:0)

从上面的代码判断,数组最初是排序的,输出也应该包含有序值。

由于您提到的限制,一个想法是不使用arr1count / arr2count,而是使用: arr1last / arr2last

其中:

&#34; arr1last = ARR1 + arr1size&#34;和&#34; arr2last = arr2 + arr2size&#34;

这样你就不必增加一个计数器,编译器会用更少的变量( - * count - * size ++ * last)来处理,只需对arr1&lt;进行比较即可。 arr1last。同样适用于arr2

也是你的第一个,如果是真的,将永远是真的,所以根据你的阵列的大小,可能值得在那时突破并继续你提到的三重循环实现,因为上面的2如果arr2size = 1,arr1size = 999并且arr2 [0]将成为&#39;输出中的第一个值,那么循环实现可能效率低下