如果允许我们在开始时用全零填充表格,那么应该可以准确地执行2^n - 1 填充来设置我们想要的 1 位。不过,这可能并不比编写手动循环快,它完全没有配置文件。
编辑:
std::vector<std::vector<int> > output(n, std::vector<int>(1 << n)); 行声明了一个向量的向量。外部向量的长度为 n,内部向量为 2^n(n 个输入的真值结果的数量),但我使用左移进行幂计算,因此编译器可以插入一个常量而不是调用,例如, pow。在n=3 的情况下,我们最终得到一个 3x8 向量。我以这种方式组织它(而不是通常的 8x3 以行作为第一个索引),因为我们将在输出数据中利用基于列的模式。以这种方式使用 vector 构造函数还可以确保向量的向量的每个元素都初始化为 0。因此我们只需要担心将我们想要的值设置为 1,剩下的就不用管了。
第二组嵌套的for 循环只是用来在完成后打印出结果数据,没什么特别的。
第一组 for 循环实现了真正的算法。我们在此处的输出数据中利用了基于列的模式。对于给定的真值表,最左边的列将有两个部分:前半部分全为 0,后半部分全为 1。由于我们预先填充了零,因此将应用从一半开始的半列高度的单次填充我们需要的所有1。第二列将有 1/4th 0、1/4th 1、1/4th 0、1/4th 1 行。因此,两个填充将应用我们需要的所有 1。我们重复这个直到我们到达最右边的列,在这种情况下,每隔一行都是 0 或 1。
我们开始说“我需要一次填充一半的行”(unsigned num_to_fill = 1U << (n - 1);)。然后我们遍历每一列。第一列从要填充的位置开始,用 1 填充那么多行。然后我们增加行并将填充大小减少一半(现在我们一次填充 1/4 的行,但是我们跳过空白行并再次填充)用于下一列。
例如:
#include <iostream>
#include <vector>
int main()
{
const unsigned n = 3;
std::vector<std::vector<int> > output(n, std::vector<int>(1 << n));
unsigned num_to_fill = 1U << (n - 1);
for(unsigned col = 0; col < n; ++col, num_to_fill >>= 1U)
{
for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
{
std::fill_n(&output[col][row], num_to_fill, 1);
}
}
// These loops just print out the results, nothing more.
for(unsigned x = 0; x < (1 << n); ++x)
{
for(unsigned y = 0; y < n; ++y)
{
std::cout << output[y][x] << " ";
}
std::cout << std::endl;
}
return 0;
}