我试图获得包含正好3个且小于1000000000的二进制数的计数(只是一个数字,而不是列表),即:10011,100000011等等。
下面的代码适用于整数,但我如何才能使用二进制文件?
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 1000000000; i++)
{
string test = i.ToString();
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
答案 0 :(得分:3)
为了您的继续教育,这里有另一种解决问题的方法。我们希望知道有多少二进制字符串在位和on
位上有off
。
在那里有一些容易解决的问题。如果N(on, off)
和on
都为零,则off
等于1,因为唯一的解决方案是空字符串。如果其中任何一个为零,则答案为1,因为全部为零或全部为1的字符串是唯一的。
让我们在表格中开始列表。
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1
f 2| 1
3| 1
4| 1
5| 1
6| 1
现在该怎么做(1,1)?那么,具有一个开和一个关的位的二进制字符串的数量等于以一开始的这种字符串的数量加上以零开始的这种字符串的数量。所以我们有:
N(1, 1) = N(1, 0) + N(0, 1) = 2
N(2,1)怎么样?同样的交易:
N(2, 1) = N(1, 1) + N(2, 0) = 3
我们可以看到类似的N(x,1)= N(1,x)= x + 1.填写数组:
on
0 1 2 3 4 5
+---------------------
o 0| 1 1 1 1 1 1
f 1| 1 2 3 4 5 6
f 2| 1 3
3| 1 4
4| 1 5
5| 1 6
6| 1 7
一般用于开启,关闭不为零:
N(on, off) = N(on - 1, off) + N(on, off - 1)
这意味着我们可以通过重复应用此规则来填充整个数组。 你能写一个这样做的程序吗?
一旦你这样做,你只需在[6, 3]
你之前在这个数组中看过这个模式吗?它有一个名字。提示:你可能还没有把它看成是一个正方形。
答案 1 :(得分:2)
更改代码的最简单方法是:
static void Main(string[] args)
{
int con = 0;
for (int i = 0; i < 512; i++)
{
string test = Convert.ToString(i, 2);
int count = test.Split('1').Length - 1;
if (count == 3)
{
con++;
}
}
Console.WriteLine(con);
}
这可以作为一个纯粹的数学方程来完成:
9! / (6!*3!) = 84
答案 2 :(得分:2)
为了您的娱乐和教育,请考虑以下事项:
static IEnumerable<string> Combinations(int on, int off)
{
if (on == 0 && off == 0)
yield return "";
if (on > 0)
foreach(var s in Combinations(on - 1, off))
yield return "1" + s;
if (off > 0)
foreach(var s in Combinations(on, off - 1))
yield return "0" + s;
}
研究这个实现:它产生一系列二进制字符串,其中on
位开启,off
位关闭。你看到它是如何做到的吗?
在这件事上明确地调用.Count()
可以解决你的问题,虽然这样的解决方案的效率远远低于简单地进行数学计算。
我为你的研究提出这个问题,因为在调查排列和组合时,像这样的递归枚举器是一个强大的工具。
答案 3 :(得分:1)
不使用字符串表示的解决方案:
static int CountBits(int i)
{
var current = i;
var bits = 0;
while (current != 0)
{
if ((current & 1) == 1)
{
bits += 1;
}
current >>= 1;
}
return bits;
}
使用此辅助方法,计数很简单:
var count = Enumerable.Range(0, 0b1000000000)
.Count(i => CountBits(i) == 3);
答案是84。
答案 4 :(得分:0)
长码(脾气暴躁的风格)
var con = 0;
for (var i = 0; i < 10000; i++)
{
var test = i.ToString();
if (test.Count(x => x == '1') == 3)
{
con++;
}
}
Console.WriteLine(con);
更短(更成熟)
var con = Enumerable.Range(0, 10000)
.Select(x => $"{x:00000}")
.Count(x =>
x.Count(c => c == '1') == 3
);
Console.WriteLine(con);
PS:他们似乎都有相同的表现。