可以给我一个人解释这GetCardinality方法是干什么的? [英] Can someone explain to me what this GetCardinality method is doing?

查看:190
本文介绍了可以给我一个人解释这GetCardinality方法是干什么的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找与Lucene.NET面搜索,我发现了光辉的榜样的这里这也解释了相当数量的,除了事实,即它完全忽视它检查位数组项目的基数作用。



谁能给我一个运行它在做什么了?主要的事情,我不明白是为什么创建bitsSetArray因为它是,它是干什么用的,以及如何,如果所有语句在工作循环。



这可能是一个很大的要求,但我明白这是如何工作之前,我甚至能想到在我自己的代码中使用它。



感谢

 公共静态INT GetCardinality(BitArray bitArray)
{
变种_bitsSetArray256 =新的字节[] {0,1,1,2, 1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3, 4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4, 4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4, 5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1, 2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4, 4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4, 5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5, 4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4, 5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7, 7,8};
VAR阵列=(UINT [])bitArray.GetType()getfield命令(m_array,BindingFlags.NonPublic可| BindingFlags.Instance).GetValue(bitArray)。
诠释计数= 0;

为(INT指数= 0;指数 - LT; array.Length;指数++)
数+ = _bitsSetArray256 [数组[索引]放大器;为0xFF] + _bitsSetArray256 [(数组[索引]>> 8)及为0xFF] + _bitsSetArray256 [(数组[索引]>> 16)及为0xFF] + _bitsSetArray256 [(数组[索引]>> 24)及为0xFF];

返回计数;
}


解决方案

_bitsSetArray256 数组初始化与价值观,使得 _bitsSetArray256 [N] 包含 ñ为 N 0..255



例如, _bitsSetArray256 [13] 等于3,因为13的二进制是 1101 其中包含3 1 秒。



这样做的原因是,它的速度远远预先计算这些值并存储它们,而不是每次(或按需)给他们锻炼。它不喜欢的 1 S IN的13二进制表示的数量是不断去改变的,毕竟:)



循环中,我们通过的 UINT 秒的数组循环。 A C# UINT 是一个32位二进制数,即由4个字节。我们的查找表告诉我们有多少位字节都设置了,所以我们必须处理四个字节。在计数+ = 行提取每四个字节的位操作,​​然后从查找数组获取其位计数。所有四个字节相加位计数给出了位计数的 UINT 作为一个整体。



因此​​,考虑一个 BitArray ,这个功能挖掘到 UINT [] m_array 成员,然后返回中位的设置总数的 UINT 取值其中二进制表示。


I've been looking into faceted search with Lucene.NET, I've found a brilliant example here which explains a fair amount, apart from the fact that it completely overlooks the function which checks the cardinality of items in a bit array.

Can anyone give me a run down of what it is doing? The main things I don't understand is why the bitsSetArray is created as it is, what it is used for and how all the if statements work in the for loop.

This may be a big ask but I have to understand how this works before I can even think of using it in my own code.

Thanks

public static int GetCardinality(BitArray bitArray)
	{
		var _bitsSetArray256 = new byte[] {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
		var array = (uint[])bitArray.GetType().GetField("m_array", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bitArray);
		int count = 0;

		for (int index = 0; index < array.Length; index ++)
			count += _bitsSetArray256[array[index] & 0xFF] + _bitsSetArray256[(array[index] >> 8) & 0xFF] + _bitsSetArray256[(array[index] >> 16) & 0xFF] + _bitsSetArray256[(array[index] >> 24) & 0xFF];

		return count;
	}

解决方案

The _bitsSetArray256 array is initialised with values such that _bitsSetArray256[n] contains the number of bits set in the binary representation of n, for n in 0..255.

For example, _bitsSetArray256[13] equals 3, because 13 in binary is 1101 which contains 3 1s.

The reason for doing this is that it's far faster to pre-compute these values and store them, rather than having to work them out each time (or on-demand). It's not like the number of 1s in the binary representation of 13 is ever going to change, after all :)

Within the for loop, we are looping through an array of uints. A C# uint is a 32-bit quantity, ie made up for 4 bytes. Our lookup table tells us how many bits are set in a byte, so we must process each of the four bytes. The bit manipulation in the count += line extracts each of the four bytes, then gets its bit count from the lookup array. Adding together the bit counts for all four bytes gives the bit count for the uint as a whole.

So given a BitArray, this function digs into the uint[] m_array member, then returns the total number of bits set in the binary representation of the uints therein.

这篇关于可以给我一个人解释这GetCardinality方法是干什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆