【发布时间】:2022-01-06 08:29:49
【问题描述】:
我想生成一个包含m 位的二进制数列表,其中n 位设置为1,所有其他位设置为0。例如,假设m 为4。我想生成一个列表具有 4 位的二进制数。 16个数字中,有6个2位为1,其他全为0。
0000
0001
0010
0011 <--
0100
0101 <--
0110 <--
0111
1000
1001 <--
1010 <--
1011
1100 <--
1101
1110
1111
我想为任何m 位生成一个列表,其中n 位设置为1,至少对于n = 2 的情况。但我不确定要遵循什么过程。我当然可以暴力破解它并生成所有m 位的数字,然后单独检查每个数字,但是对于可能需要一段时间的大量位。我觉得必须有一个更巧妙的数学技巧来找出答案。
如果有任何关于从哪里开始的指示,我将不胜感激。我不介意答案是伪代码还是任何语言,只要它们是明确的。
XY 问题
我正在尝试解决国际象棋问题,其中棋盘上有两个棋子。首先,我试图在棋盘上生成两个棋子的所有有效组合,我计划通过将棋盘视为 64 位二进制数 (0000 0000 0000 0000 .. 0011) 来实现,其中一个位是一块。为此,我需要找到一种优雅的方式来生成二进制数列表。
编辑:我尝试在 Python 中实现朴素算法只是为了演示。在我的 VS Code 上执行 m = 64 需要很长时间,所以绝对不是最好的解决方案:
n = 2
m = 64
combos = []
for i in range(2 ** m):
bin_s = str(format(i, f'0{m}b'))
if bin_s.count('1') == n:
combos.append(bin_s)
for c in combos:
print(c)
print(f"There are {len(combos)} combinations")
【问题讨论】:
-
这有帮助吗?每个具有 n 个 1 的 m 位数要么以 0(后跟带有 n 个 1 的 m-1 位数)或 1(后跟带有 n-1 个 1 的 m-1 位数)开头。
-
所以对于一个有 2 个 1 的 64 位数字,它要么以 0 开头,然后是 2 个 1 的 63 位数字,或者以 1 后跟 1 1 的 63 位数字开头。诚然,我不确定这如何帮助我提出算法
-
它是(大部分)一种算法——一种递归算法。剩下的主要部分是确定答案显而易见的 m 和 n 的情况(例如,如果只有 1 个或更少的数字)。
-
老实说,我不太擅长从线索中找出答案。您是否建议将二进制中的每个数字从 1 迭代到 2^m(例如 1 到 2^64)并对每个数字应用一些递归算法来确定它是否符合具有两个 1 位的标准?或者使用一些递归算法来生成列表?
-
你在哪里看到我写的任何东西中的“迭代”这个词?我所描述的是一种生成列表的递归算法,这正是您所要求的。
标签: list algorithm binary pseudocode