繁体   English   中英

C# 是否具有将二进制数转换为位幂数组的内置方法(例如 0b1101 -> {0, 2, 3} )?

[英]Does C# have a builtinway of converting binary number to array of bit powers ( e.g. 0b1101 -> {0, 2, 3} )?

(编辑 - 前言:我正在通过给定大小的所有子集实现可迭代。为了获得下一个组合,我正在使用 Gosper 的 hack 快速获得字典顺序下一个组合的 0/1 向量。现在我需要快速 map 的向量组合到我的集合中的元素数组。幸运的是,这些元素与单个位的幂非常相同,我想知道 C# 是否没有快速快捷方式。)

如果我得到数字 0 - (N-1) 的第 K 个子集(按字典顺序),则 K 的二进制表示中的位告诉我应该选择哪些元素。 检查设置了哪些位并基于这些位创建子集(数组)的最优雅的方法是什么?

就像是:

var BitPowers = new List<int>();
for(int i = 0; i<N; ++i)
{
  if((K & (1<<i)) != 0)
  { 
   BitPowers.Add(i);
  }
}
return BitPowers.ToArray();

可能就足够了,但这是最好的方法吗? 我猜位操作很快,但由于可能的集合数量是指数级的,尽可能优化这个 function 将是理想的。

据我所知,没有 .NET 内置 API 可以做这样的事情。

Linq魔术

您可以在一个作业中编写此紧凑代码,但对速度的优化较少:

int value = 0b10110010;

var BitPowers = Convert.ToString(value, 2)
                       .Reverse()
                       .Select((bit, index) => new { index, bit })
                       .Where(v => v.bit == '1').Select(v => v.index);

foreach ( int index in BitPowers )
  Console.WriteLine(index);

它将 integer 转换为字符串的二进制表示,从左到右反转以具有良好的索引,然后选择一对(位,索引),然后过滤已定义的那些,然后选择要创建的索引可枚举的列表。

Output

1
4
5
7

优雅与速度之间的妥协

您可以使用 BitArray 实例简化循环。

也许这是您要求的最接近的“内置”方式:

var bits = new BitArray(BitConverter.GetBytes(value));
for ( int index = 0; index < bits.Length; index++ )
  if ( bits[index] )
    BitPowers.Add(index);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM