一个算法的优化
一个算法的优化
朋友需要一个算法,有一个多行,两列的二维数组,两列分别保存主副设备号,要求判断
任意两行的第一列和第二列同时相同,返回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;
}