Algorithm 查找所有n位二进制数,其中r个相邻数字为1
让我举例说明。如果n=4,r=2,则表示所有4位二进制数,使得两个相邻的数字可以是1。所以答案是00110111001101,我将从简化问题开始。一旦你对最简单的情况有了一个解决方案,概括它,然后尝试优化它 首先设计一个算法,找出给定的数字是否有“r”相邻的1。一旦你有了它,蛮力的方法就是用“n”数字遍历所有的数字,用你刚刚开发的算法检查每一个数字 现在,您可以寻求对其进行优化。例如:如果您知道“r”是偶数还是奇数,您可以减少要查看的数字集。KNR给出的计数1算法是设定位数的顺序。因此,您排除了一半复杂度低于实际逐位比较的情况。也许还有更好的方法来减少这种情况 我无法找出一个模式或算法 提示:11可以从位置0、1或2开始。在任何一侧,数字都必须为零,因此只有“空闲”数字位于剩余位置,并且可以在所有可能的值之间循环 例如,如果有n=10个数字,并且您正在查找r=3个相邻的数字,则模式为Algorithm 查找所有n位二进制数,其中r个相邻数字为1,algorithm,math,binary,Algorithm,Math,Binary,让我举例说明。如果n=4,r=2,则表示所有4位二进制数,使得两个相邻的数字可以是1。所以答案是00110111001101,我将从简化问题开始。一旦你对最简单的情况有了一个解决方案,概括它,然后尝试优化它 首先设计一个算法,找出给定的数字是否有“r”相邻的1。一旦你有了它,蛮力的方法就是用“n”数字遍历所有的数字,用你刚刚开发的算法检查每一个数字 现在,您可以寻求对其进行优化。例如:如果您知道“r”是偶数还是奇数,您可以减少要查看的数字集。KNR给出的计数1算法是设定位数的顺序。因此,您排除了
x01110y
其中,x和y可以循环使用剩余五个自由数字的所有可能后缀和前缀。注意,在侧面,前导零和尾随零被删除,在x0111和1110y中留下六个自由数字
下面是一个使用Python的示例:
from itertools import product
def gen(n, r):
'Generate all n-length sequences with r fixed adjacent ones'
result = set()
fixed = tuple([1] * r + [0])
for suffix in product([0,1], repeat=n-r-1):
result.add(fixed + suffix)
fixed = tuple([0] + [1] * r + [0])
rem = n - r - 2
for leadsize in range(1, rem):
for digits in product([0,1], repeat=rem):
result.add(digits[:leadsize] + fixed + digits[leadsize:])
fixed = tuple([0] + [1] * r)
for prefix in product([0,1], repeat=n-r-1):
result.add(prefix + fixed)
return sorted(result)
有趣的问题,非常简单的递归解决方案。德尔菲
procedure GenerateNLengthWithROnesTogether(s: string;
N, R, Len, OnesInRow: Integer; HasPatternAlready: Boolean);
begin
if Len = N then
Output(s)
else
begin
HasPatternAlready := HasPatternAlready or (OnesInRow >= R);
if HasPatternAlready or (N - Len > R) //there is chance to make pattern}
then
GenerateNLengthWithROnesTogether('0' + s, N, R, Len + 1, 0, HasPatternAlready);
if (not HasPatternAlready) or (OnesInRow < R - 1) //only one pattern allowed
then
GenerateNLengthWithROnesTogether('1' + s, N, R, Len + 1, OnesInRow + 1, HasPatternAlready);
end;
end;
begin
GenerateNLengthWithROnesTogether('', 5, 2, 0, 0, False);
end;
program output:
N=5,R=2
11000 01100 11010 00110
10110 11001 01101 00011
10011 01011
N=7, R=3
1110000 0111000 1110100 0011100
1011100 1110010 0111010 1110110
0001110 1001110 0101110 1101110
1110001 0111001 1110101 0011101
1011101 1110011 0111011 0000111
1000111 0100111 1100111 0010111
1010111 0110111
procedure GenerateNLengthWithROnesTogether(s:string;
N、 R,Len,OnesInRow:Integer;haspatternready:Boolean);
开始
如果Len=N,则
输出(s)
其他的
开始
haspatterneready:=haspatterneready或(OnesInRow>=R);
如果haspatterneed或(N-Len>R)//有机会生成模式}
然后
generatenLengthThronestogether('0'+s,N,R,Len+1,0,haspatterned);
if(nothaspatterneready)或(OnesInRow
正如我在上面的评论中所说,我仍然不清楚输出集的全部限制。但是,可以对下面的算法进行改进,以涵盖您的最终情况
在我描述算法之前,有一个观察:让我们重复
1
次m
次,D是我们可以用来生成有效输出的所有可能后缀的集合。因此,位字符串S0D0
(S后跟0位,然后是位字符串D后跟0位)是算法的有效输出。另外,所有字符串ror(S0D0,k)
,0那么您到底遇到了什么问题?@HunterMcMillen:可能是问题:)@leppie我看不出有问题,是吗?这基本上是一种游程限制(RLL)编码形式。我相信这通常是通过在普通二进制中进行计数,然后将结果转换为所选的RLL来完成的。@HunterMcMillen我的问题是什么可以成为这方面的算法?我无法找出模式或算法。我可以将二进制数作为字符串搜索,但这不是最优的。我想知道这是否有一个数学模式。此外,除了将二进制数作为字符串搜索外,我无法找出最简单情况下的算法。我需要考虑更多。如果只是找到这些数字的数量,那就很容易了。假设r是2,n是4。然后11个会在4个地方的某个地方聚集在一起。因此,其余两个位置可以具有不同的数字/值排列。因此有四个这样的价值观。如果n等于20,那么就有20-2,18个这样的位置,因此有2^18个这样的数字。不过,通过剩余可能性的循环是困难的部分。如果置换1块中仅向左的填充,并与仅向右的填充合并,则仍会丢失一些填充。在块的两侧填充,我认为不创建重复项是很困难的,尽管我认为这是一种方法。重复项不是问题。我要试试这个逻辑。谢谢这几乎奏效了。但对于n=6和r,给出了无效的输出111011=2@ritratt为什么111011是无效输出?它有一组两个相邻的。您是否打算添加一个输出最多应具有两个连续整数的约束?是的,它最多应具有两个连续整数。我解决了上面的错误,现在工作正常!
def ror(str, n):
return str[-n:]+str[:-n]
def family(s, d, r):
root = s + '0' + d + '0'
yield root # root is always a solution
for i in range(1, len(d)+3):
sol=ror(root, i)
if sol[:r]==s and sol[r]=='0' and sol[-1]=='0':
break
yield sol
if d[-r:]!=s: # Make sure output is valid
yield s + '0' + d + '1'
if d[:r]!=s: # Make sure output is valid (todo: duplicate check)
yield '1' + d + '0' + s
def generate(n, r):
s="1"*r
if r==0: # no 1's allowed
yield '0'*n
elif n==r: # only one combination
yield s
elif n==r+1: # two cases. Cannot use family() for this
yield s+'0'
yield '0'+s
else:
# generate all sub-problem outputs
for rr in range(r+1):
if n-r-2>=rr:
for d in generate(n-r-2, rr):
for sol in family(s, d, r):
yield sol
for s in generate(6,3):
print(s)