提取设置为 HashSet 的位
本文关键字:uint 的位 HashSet 设置 提取 | 更新日期: 2023-09-27 18:32:44
在
c# 中是否有一种方便的方法(使用 linq 或类似方法)将 uint 的真实位提取到HashSet<uint>
中?
例:
private HashSet<uint> ExtractTrueBitsFromSum(uint sum)
{
}
calling it with 15 returns the set `{1,2,4,8}`
calling it with 23 returns the set `{1,2,4,16}`
calling it with 31 returns the set `{1,2,4,8,16}`
private HashSet<uint> ExtractTrueBitsFromSum(uint sum) {
HashSet<uint> result = new HashSet<uint>();
while(sum>0) {
uint newSum = sum&(sum-1); // newSum = sum with least significant True bit set to False.
result.Add(sum^newSum); // sum^newSum return least significant True bit of sum.
sum=newSum;
}
return result;
}
我只会使用明显的循环,而不打扰 Linq:
private HashSet<uint> ExtractTrueBitsFromSum(uint sum)
{
var set = new HashSet<uint>();
for (uint j = 1; j != 0; j <<= 1)
if ((sum & j) != 0)
set.Add(j);
return set;
}
我认为这不是
使用LINQ的任何理由。
private static HashSet<uint> ExtractTrueBitsFromSum(uint sum)
{
var result = new HashSet<uint>();
for (int i = 0; i < 32; i++)
{
if (((sum >> i) & 0x1) == 1)
result.Add((uint)((1 << i)));
}
return result;
}
这
似乎适用于int
s:
int n = 23;
string str = Convert.ToString(n, 2);
HashSet<int> result = new HashSet<int>(str.Select((c, index) =>
int.Parse(c.ToString()) > 0 ? (int)Math.Pow(2, index) : 0));
result.Remove(0);
编辑 - 以考虑位的颠倒顺序:
HashSet<int> result = new HashSet<int>(str.Reverse().Select((c, index) =>
int.Parse(c.ToString()) > 0 ? (int)Math.Pow(2, index) : 0));
result.Remove(0);
编辑 2:
HashSet<uint> result = new HashSet<uint>(str.Reverse().Select((c, index) =>
int.Parse(c.ToString()) > 0 ? (uint)Math.Pow(2, index) : 0));
result.Remove(0);
如果您更喜欢 LINQ:
private HashSet<uint> ExtractTrueBitsFromSum(uint sum)
{
var bits = Convert.ToString(sum, toBase: 2);
return new HashSet<uint>(
bits.Select((bit, index) => (uint)(bit - '0') << (bits.Length - index - 1))
.Where(pow => pow > 0));
}