【发布时间】:2016-06-29 08:35:05
【问题描述】:
我有两个位数组,每个长度为 200.000。我需要以相同的顺序在每个列表中找到多少个 1。让我画出来:
1 0
**1 1**
0 0
0 1
0 0
**1 1**
1 0
0 1
.. ..
所以结果应该是 2。
我在 -two 中进行了这个比较,嵌套了大约 2000 万次 :)。
我现在使用带有 & 运算符的位数组而不是使用 popCount 方法来查找结果。
那么你对这类问题有什么建议。你会在哪里存储这些向量,你会如何以我想要的方式比较它们?我需要速度。
更新: 我已经用 760 个长度的阵列完成了这项工作,我的方法用了不到 5 秒的时间。 cmets中建议的每种方法都花费了> 1分钟(我停止了程序) 所以我想是我必须回答它。我简化了我的代码。
for(i<761)
var vector1 = matris[getvectorthing];
for(j=i+1<761)
{
var vector2 = matris[getvectorthing];
var similarityResult = vector1Temp.And(vector2);
var similarityValuePay = popCount(similarityResult);
//similarityValuePay is result that i want
}
}
private static int popCount(BitArray simRes)
{
Int32[] ints = new Int32[(simRes.Count >> 5) + 1];
simRes.CopyTo(ints, 0);
Int32 count = 0;
// fix for not truncated bits in last integer that may have been set to true with SetAll()
ints[ints.Length - 1] &= ~(-1 << (simRes.Count % 32));
var tempInt = ints.Where(k => k != 0).ToArray();
for (Int32 i = 0; i < tempInt.Length; i++)
{
Int32 c = tempInt[i];
// magic (http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel)
unchecked
{
c = c - ((c >> 1) & 0x55555555);
c = (c & 0x33333333) + ((c >> 2) & 0x33333333);
c = ((c + (c >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
count += c;
}
return count;
}
我问它是因为可能有很多切割方法或简单的调整来提高性能。例如:
var tempInt = ints.Where(k => k != 0).ToArray();
这个 ToArray() 似乎是我需要修复的部分。等等
【问题讨论】:
-
写一些代码给我们看看。
-
" -two nested for- " - 你为什么需要它?