一个算法的优化

一个算法的优化

  • 空间
 

朋友需要一个算法,有一个多行,两列的二维数组,两列分别保存主副设备号,要求判断

任意两行的第一列和第二列同时相同,返回false

任意两行的第一列相同,第二列有一个为0,返回false。

全部不相同返回true。

 

最原始方法:时间复杂度为 O (n平方)。


假设传入参数为 line  总行数。

bool fun( int a[][2], intint line )
{
 if line > 16
  return false;

 for(i=0; i<line-1; i++)
 {
   for(j=i+1; j<line; j++)
  {   
   if(!(a[i][0] & a[j][0]))    //第一列相同
    if(!(a[i][1] & a[j][1])) || !a[i][1] || !a[j][1])
     return false;
  }
 }

 return true;

}

 

优化后算法:时间复杂度为O(n).

int fun( const unsigned int a[16][2], int line)
{
 int i=0;
 unsigned int *value = malloc( 65535 * 3 * _SIZE ); // memory size limits to 65535*32767, so map 2-dimension array to  1-dimension
 unsigned int *sign = malloc( 65535 * _SIZE );
 unsigned int major = 0, deputy = 0;

 //reset buf
 memset(value, 0, 65535 * 3 * _SIZE); 
 memset(sign, 0, 65535 * _SIZE);

 for(; i<line; i++)
 {
  major = a[i][0];
  deputy = a[i][1];
  sign[major] = 1;        //if this line has major-id, set 1

  if(value[major+deputy*2] )      //value[x] = 1, so this item was maped twice,  exists two same groups at least.
   return 0;
  else
   value[major+deputy*2] = 1;

  if( !deputy  && sign[major] )     //deputy-id =0, and exists same major-id.
   return 0;
   
 }
 return 1;
}

思路是,主副设备号映射到一个2维数组上,只要有任意两次映射到同一个元素上,说明,有一组主副设备号都相同。

另一种情况是,行的第一个元素为0时候,说明副设备号相同,此时判断,此行是否有其他主设备号

。。用了两种映射。。 第一种是把主副设备号号当行列下标映射到一个二维数组上。但是发现,这个数组超级大。超过2G限制。只好又把这个二维数组映射到到一维数组上。

构造算法时候,用到的草图,最后发现key用不到了,line换成了sign

 

测试后发现,存在不合理的判断。对副设备好为0的判断不正确。

 

修改后的算法:

int fun( const unsigned int a[16][2], int line)
{
 int i=0;
 unsigned int *value = malloc( 65535 * 3 * _SIZE ); // memory size limits to 65535*32767, so map 2-dimension array to  1-dimension
 unsigned int *value2 = malloc( 65535 * _SIZE );  // only map major-id when deputy-id is 0
 unsigned int *value3 = malloc( 65535 * _SIZE );  // only map major-id when deputy-id is not 0
 unsigned int *sign = malloc( 65535 * _SIZE );
 unsigned int major = 0, deputy = 0;

 //reset buf
 memset(value, 0, 65535 * 3 * _SIZE); 
 memset(value2, 0, 65535 * _SIZE);
 memset(value3, 0, 65535 * _SIZE);
 memset(sign, 0, 65535 * _SIZE);

 for(; i<line; i++)
 {
  major = a[i][0];
  deputy = a[i][1];
  
  if(deputy)          // only when deputy-id is not 0
  {
   value3[major] = 1;       // map major-id

   if(value[major+deputy*2] || value2[major]) // value[x] = 1, so this item was maped twice,  exists two same groups at least. or exists same major-id which of deputy-id is 0
    return 0;
   else
    value[major+deputy*2] = 1;
  }   
  else if( value3[major] )      // deputy-id is 0,and exists same major-id
   return 0;
  else           // deputy-id is 0, and doesnt exists same major-id, set 1
   value2[major] = 1; 
 }
 return 1;
}

posted @ 2017-04-06 10:48  dfdqzp  阅读(165)  评论(0编辑  收藏  举报