我有一个表示为二进制数的配置值,允许在同一个值中有多个选项。
E.g。 5的值为“101”或4和1。
有没有人知道“输入”值“5”并获得{1,4}列表的最佳/最快方式?
答案 0 :(得分:3)
如果你想得到2的幂,其值包括:
int value = 5;
var addendums = Enumerable.Range(0, sizeof(int) * 8 - 1)
.Select(i => (1 << i) & value)
.Where(x => x != 0)
.ToList();
结果:
[ 1, 4 ]
请注意,如果您希望按降序添加附录,则可以在过滤序列后应用Reverse()
。
TL; DR 第一步生成整数值,这些值对应于整数值0, 1, 2, ..., 31
中的位位置。最大索引是Int32值中的位数 - 1(因为我们需要该位的索引)。
下一步选择1的位按AND运算结果移位到相应的索引(与2的幂相同)的值本身(此处仅显示前4位):
i 1<<i value (1<<i) & value
Binary Binary Binary Decimal
0 0001 0101 0001 1
1 0010 0101 0000 0
2 0100 0101 0100 4
3 1000 0101 0000 0
...
在此步骤之后您需要做的就是过滤掉零。
答案 1 :(得分:1)
稍微转移一点&
以后......
int n = 5+32;
var lst = new List<int>();
int i = 1;
while (n > 0)
{
if ((n & i) == i)
{
lst.Add(i);
n &= ~i;
}
i <<= 1; // equivalent to i *= 2
}
使用xor(^
)更加深奥:
if (n != 0)
{
while (true)
{
if ((n & i) != 0)
{
lst.Add(i);
n ^= i;
if (n == 0)
{
break;
}
}
i <<= 1; // equivalent to i *= 2
}
}
答案 2 :(得分:0)
天真的方法:
int originalInput = 42;
int input = originalInput;
// Generate binary numbers
var binaryNumbers = Enumerable.Range(0, 31).Select(n => (int)Math.Pow(2, n)).ToArray();
// Largest first
Array.Reverse(binaryNumbers);
var result = new List<int>();
foreach (var bin in binaryNumbers)
{
if (input >= bin)
{
result.Add(bin);
input -= bin;
}
}
Console.WriteLine($"{originalInput} decomposed: " + string.Join(" ", result));
生成一系列2的幂次数,范围从2 ^ 31(1073741824)到2 ^ 0(1),然后检查输入是否等于或大于这些数字,如果是,则添加编号到结果列表并从输入中减去。
现在已经全部写完了,看看谢尔盖的答案如何大大减少了一些Linq和比特换档魔法所需的代码。
混合解决方案,灵感来自两个答案:
var input = 42;
var output = Enumerable.Range(0, 31)
.Select(n => (int)Math.Pow(2, n))
.Where(p => (p & input) > 0);
Console.WriteLine($"{input} decomposed: " + string.Join(" ", output));
答案 3 :(得分:0)
我做了这个小样本。在这里,您从整数中获取其值为2的幂的总和。 Thosw权力应该是您的输入选项
class Program
{
static void Main(string[] args)
{
var input = 5;
var options = new List<uint>();
for (uint currentPow = 1; currentPow != 0; currentPow <<= 1)
if ((currentPow & input) != 0)
options.Add(currentPow);
foreach (var option in options)
Console.WriteLine(option);
Console.ReadLine();
}
}
输出为:1 4
编辑&gt;&GT;&GT;事实上,这与@Sergey Berezovskiy答案相同,但没有LINQ
希望有所帮助
答案 4 :(得分:0)
可能更传统且易于理解的解决方案。您将数字转换为字符串二进制表示,然后分析每个字符以提取每个位的相应十进制表示形式。
int number = 5;
string binaryRep = Convert.ToString(number, 2);
List<int> myList = new List<int>();
int pow = 0;
for(int i = binaryRep.Count() - 1; i >= 0; i--)
{
if(binaryRep[i] == '1')
{
myList.Add((int)Math.Pow(2, pow));
}
pow++;
}
答案 5 :(得分:0)
短而快:
$(".back, .laptop, .close").click(function(){
答案 6 :(得分:0)
显示二进制表示使用
int value = 7;
var binary = Convert.ToString(value, 2);
要查看二进制数字:
private int[] ToBinaryNumbers(int value)
{
var binary = Convert.ToString(value, 2).Reverse();
int ix = 0;
return binary.Select(x => { var res = x == '1' ? (int?)Math.Pow(2, ix) : (int?)null; ix++; return res; }).Where(x => x.HasValue).Select(x => x.Value).ToArray();
}
这将给你1,2,4,7或1,8 for 9