C# 提取设置为哈希集的位<;uint>;?
在c#(使用linq或类似工具)中,是否有一种方便的方法将uint的真位提取到C# 提取设置为哈希集的位<;uint>;?,c#,linq,C#,Linq,在c#(使用linq或类似工具)中,是否有一种方便的方法将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
哈希集
例如:
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 ExtractTrueBitsFromSum(uint sum)
{
}
用15调用它将返回集合`{1,2,4,8}`
用23调用它会返回集合`{1,2,4,16}`
用31调用它将返回集合`{1,2,4,8,16}`
这似乎适用于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);
int n=23;
string str=Convert.ToString(n,2);
HashSet结果=新的HashSet(str.Select((c,index)=>
int.Parse(c.ToString())>0?(int)Math.Pow(2,index):0);
结果:删除(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);
HashSet结果=新的HashSet(str.Reverse().Select((c,index)=>
int.Parse(c.ToString())>0?(int)Math.Pow(2,index):0);
结果:删除(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);
HashSet结果=新的HashSet(str.Reverse().Select((c,index)=>
int.Parse(c.ToString())>0?(uint)Math.Pow(2,索引):0);
结果:删除(0);
私有哈希集ExtractTrueBitsFromSum(uint sum){
HashSet result=新的HashSet();
而(总和>0){
uint newSum=sum&(sum-1);//newSum=sum,最低有效真位设置为False。
result.Add(sum^newSum);//sum^newSum返回sum的最低有效真位。
sum=newSum;
}
返回结果;
}
我只会使用明显的循环,而不必担心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;
}
private HashSet ExtractTrueBitsFromSum(uint sum)
{
var set=新的HashSet();
对于(uint j=1;j!=0;jI thnik,没有任何理由使用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;
}
私有静态哈希集ExtractTrueBitsFromSum(uint sum)
{
var result=new HashSet();
对于(int i=0;i<32;i++)
{
如果((总和>>i)&0x1)==1)
结果。如果您喜欢LINQ,请添加((uint)((1):
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));
}
private HashSet ExtractTrueBitsFromSum(uint sum)
{
变量位=转换为字符串(和,toBase:2);
返回新哈希集(
位。选择((位,索引)=>(uint)(位-'0')功率>0));
}
方便吗?不太方便-在纸上算出二进制数学,然后将步骤转换为代码。可能有“聪明”的方法可以做到这一点,但我会先得到一些有效的方法,然后集中精力使其“更好”(无论这对你意味着什么).无论如何,为什么要使用HashSet
?这里的最终目标是什么?知道整数中设置了哪些位能为您带来什么好处?@DStanley为什么不应该使用HashSet…不可能有重复的值。问题不是HashSet vs List。他问的问题是,一旦拥有HashSet,您将如何处理这些信息,t这里可能有一个更好的方法来达到你的最终目标。他正在检查你是否有一个带有Flags
属性a选项的is-a enum?它听起来更适合你想要做的事情。你可以放下i
,使用j!=0
作为循环条件。@PetSerAl-True,只要我在它周围加上未选中的。(或者可能不需要-我会检查)好的,我测试了它,您不需要取消选中
。索引从最高有效位开始,但您的查询使用它就像它从最低有效位开始一样。此外,oveflow将在该查询中出现uint.MaxValue
,(int)Math.Pow(2,31)
equals-2147483648
@LeonidVasilyev-刚刚编辑过,因为我提到它只对int
s有效,因为没有Convert.ToString
接受uint
和base
是真的,但是有一个版本接受long
和base。你可以将它与uint
一起使用,因为它将被隐式转换为long
Convert.ToString(uint.MaxValue,2)
效果很好。不客气。实际上,即使是Convert.ToString((int)sum,2)
效果也很好,因为无论oveflow如何sum
和(int)sum
两个补码都是一样的。
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));
}