首先,这不是作业!
我的问题来自Robert Sedgewick的书中的 C ++第三版算法。
给出了一个大小为n乘2 ^ n(二维)的数组,我们应该用二进制数大小的n来填充它。例如,对于n = 5,结果将是:
00001
00010
00011
00100
00101
00110
00111
等等。我们应该将这个位序列放入数组中。
答案 0 :(得分:1)
我不太了解C / C ++,但是一种天真的,与语言无关的方法是简单地找到A [i,j]的公式,其中i \ in [0,2 ^ n - 1]和j \ [0,n-1]。
在单词中,A [i,j]包含i的第j个二进制数字,从最高位开始计数。
在公式中,A [i,j] =(i AND 2 ^(n-1-j))SHR(n-1-j)
其中AND是二进制按位和运算符,SHR是二进制“shift bits right”运算符。 a ^ b意味着(当然)“提升到b的力量”。
丑陋的概念验证德尔福代码:
var
i: Integer;
twoton: integer;
j: Integer;
begin
twoton := round(IntPower(2, n));
SetLength(A, twoton, n);
for i := 0 to twoton - 1 do
for j := 0 to n - 1 do
A[i, j] := (i and round(IntPower(2, n-1-j))) shr (n-1-j);
这很好用,但我确信有更快的方法......至少有一个可以在数组中存储2的幂并使用POWEROF2 [k]而不是round(IntPower(2,k)),但是 - 当然 - 这取决于你的语言。毕竟,IntPower是Delphi的功能。
如何运作
假设我们有数字23,或者,在二进制10111中。现在我们想要第三个二进制数字。然后我们想要数字10111和数字00100,如果搜索到的数字是1则获得00100,否则获得00000。请注意,00100,我们与之对的数字,只是十进制的2 ^ 3;因此所有的权力都是2。现在我们有数字00N00,其中N是被寻找的数字,在这个例子中是1:00100。我们现在将这个数字的3位向右移位(SHR操作),以获得00001 = 1,并且 - il! - 我们已经得到了我们的数字!
更智能的方法
我不知道C如何存储数组,但你可以简单地创建一个无符号整数的2 ^ N维向量 A(8位,16位或32位,最好是),即数字0,1,2,...,2 ^ N - 1,然后认为这实际上是二维矩阵。实际上,如果我们将UNSINGED_INTEGER [k]表示为UNSIGNED_INTEGER的第k位,那么A [i] [k]或多或少是你想要的矩阵......
答案 1 :(得分:1)
每个数字比二进制数系统中的最后一个数字多一个。
以二进制
递增(加1)请注意,<<
运算符将左操作数乘以2乘以右操作数的幂。数字1l
只是1
表示为long
,在64位系统上为64位。
template< size_t n > // template detects size of array. Strictly optional.
void ascending_binary_fill( bool (&arr)[ 1l << n ][ n ] ) {
std::fill( arr[0], arr[0] + n, 0 ); // first # is 0
for ( size_t pred = 0; pred < 1l << n; ++ pred ) {
int bit = n; // pred = index of preceding number; bit = bit index
while ( arr[ pred ][ -- bit ] ) { // trailing 1's in preceding #
arr[ pred+1 ][ bit ] = 0; // ... are trailing 0's in current #
}
arr[ pred+1 ][ bit ] = 1;
std::copy( arr[ pred ], arr[ pred ] + bit, arr[ pred+1 ] );
}
}
答案 2 :(得分:1)
非常简单!
这是伪代码的解决方案
assert(bits <= 32)
int array[pow(2, bits)]
for (uint i= 0; i < length(array); i++)
array[i]= i;
结果是一个数组,其中填充了您作为示例提供的模式
答案 3 :(得分:1)
public static uint[][] FillUpCode(uint qValue, uint kValue)
{
var size = (ulong)Math.Pow(qValue, kValue);
var array = new uint[size][];
var workArray = new uint[kValue];
long position = kValue - 1;
ulong n = 0;
while (position > 0)
{
while (workArray[position] < qValue)
{
var tempArray = new uint[kValue];
Array.Copy(workArray, tempArray, kValue);
array[n++] = tempArray;
workArray[position]++;
}
while (position > 0)
{
workArray[position] = 0;
if (workArray[position - 1] < (qValue - 1))
{
workArray[position - 1]++;
position = kValue - 1;
break;
}
position--;
}
}
return array;
}
qValue - 数字基数,kValue - 行长度:)当您需要以不同的数字生成数组时,代码可能很有用。
答案 4 :(得分:0)
所以基本上,你需要一个从零开始的数组,并且最多可以达到2 ^ n? Psuedo-C:
bool[][] Fill(int n) { max = Pow(2, n); array = new bool[max, n]; for i from 0 to max - 1 for j from 0 to n - 1 array[i][n - j - 1] = ((i >> j) & 1) == 1; return array; }
我能看到的唯一问题是它的上限是n = 32,但是这已经占用了大量的内存,所以这真的不是问题。
请注意,你也可以使它成为一维数字并用0到2 ^ n的数字填充它,并且实际上将使用(A [i]&gt;&gt; j来检索A [i] [j] th元素)&amp; 1。
答案 5 :(得分:0)
这是一个非常基本的问题,我将使用这个Java代码演示:
public class Bin { // prints:
static String zero(int L) { // 0000
return (L <= 0 ? "" : String.format("%0" + L + "d", 0)); // 0001
} // 0010
static String zeroPad(String s, int L) { // 0011
return zero(L - s.length()) + s; // 0100
} // 0101
public static void main(String[] args) { // 0110
final int N = 4; // 0111
for (int i = 0; i < (1 << N); i++) { // 1000
System.out.println(zeroPad(Integer.toBinaryString(i), N)); // 1001
} // 1010
} // 1011
} // 1100
// 1101
// 1110
// 1111
我将留待您了解如何实施toBinaryString
以及如何使用位填充int[][]
。
答案 6 :(得分:0)
// My solution is based on that of Potatoswatter.
// use cols value where rows = 2^cols
// start here after setting cols
rows = pow(2.0, double(cols));
// memory allocation
bool **array = new bool*[rows];
for (int i = 0; i < rows; i++) {
array[i] = new bool[cols];
}
std::fill( array[0], array[0] + cols, 0 ); // maybe not needed
for (int i = 1; i < rows; i++) { // first row is zero, start at second
// starting at right ...
int j = lits - 1;
// turn the last zero into a one
if (array[i][j] == false) {
array[i][j] = true;
}
else {
// turn all trailing ones into zeros (prior to first zero)
while (array[i][j] == true) {
array[i][j] = false;
j--;
}
array[i][j] = true;
}
// copy this row to next row
if (i < (rows - 1)) {
std::copy(array[i], array[i] + lits, array[i+1]);
}
}