生成所有可能的真/假组合

4

我想创建一个包含三个变量的数组,这些变量可以是true或false(即8种可能的组合)。

我正在尝试创建此图像左上角的立方体:

enter image description here

因此,输出应该类似于:

points = [
  // first square
  {
    id: '000',
    truths: [false, false, false]
    position: [0, 0]
  },
  {
    id: '100',
    truths: [true, false, false]
    position: [5, 0]
  },
  {
    id: '010',
    truths: [false, true, false]
    position: [0, 5]
  },
  {
    id: '110',
    truths: [true, true, false]
    position: [5, 5]
  },
  // second square
  {
    id: '001',
    truths: [false, false, true]
    position: [2.5, 2.5]
  },
  {
    id: '101',
    truths: [true, false, true]
    position: [7.5, 2.5]
  },
  {
    id: '011',
    truths: [false, true, true]
    position: [2.5, 7.5]
  },
  {
    id: '111',
    truths: [true, true, true]
    position: [7.5, 7.5]
  },
];

lines = [
  { from: '000', to: '100' },
  { from: '000', to: '010' },
  { from: '000', to: '001' },

  { from: '100', to: '101' },
  { from: '100', to: '110' },

  { from: '001', to: '101' },
  { from: '001', to: '011' },

  { from: '101', to: '001' },
  { from: '101', to: '111' },

  ...
]

我不知道如何遍历所有可能的真值并创建这些点。

一种方法是使用for循环。

for (var i=0; i<Math.pow(2, 3); i++) {
  ...
}

但这并不能帮助我分配可能的真值。

1
有2^n个可能的值。如果你不想使用嵌套的for循环(你真的不应该这样做),那么提取整数0...2^n的位。truths中的n个值将是整数的位。 - plasmacel
我就是不明白,如果你的顺序是0、4、2、3、1、5、7、8,二进制方法怎么会有帮助呢?为什么不直接使用数字呢? - Redu
@Redu 我不明白你在说什么。顺序并不重要。从0到8的所有整数都将表示3位,对应于OP类比中的“truths”数组。2^n个整数=2^n个“truths”数组。在二进制中,数字可以被视为位“数组”:0=[0,0,0],1=[0,0,1],2=[0,1,0],3=[0,1,1],4=[1,0,0],5=[1,0,1],6=[1,1,0],7=[1,1,1]。 - plasmacel
5个回答

10

计算机中的所有内容都已经是二进制形式。您不需要使用任何炫酷的Math.pow等函数。

for (let i = 0; i < 1 << 3; i++) {
  console.log([!!(i & (1<<2)), !!(i & (1<<1)), !!(i & 1)]);
}

虽然这看起来简单明了,但我实际上不喜欢使用!!或魔术数字。不过在编写代码片段时,我总是会陷入这些技巧中。因此,我将尝试提供稍微更清晰的版本:

const AMOUNT_OF_VARIABLES = 3;

for (let i = 0; i < (1 << AMOUNT_OF_VARIABLES); i++) {
  let boolArr = [];
  
  //Increasing or decreasing depending on which direction
  //you want your array to represent the binary number
  for (let j = AMOUNT_OF_VARIABLES - 1; j >= 0; j--) {
    boolArr.push(Boolean(i & (1 << j)));
  }
  
  console.log(boolArr);
}


嗨,只是出于好奇问一下...这个 0 (for let i = 0;) 是否等于二进制的 0?它和 1 >>> 1 是一样的吗? - Alejandro Iván
0 真的是零。只需要这样看,JavaScript 二进制运算符在 32 位整数上“仿佛”工作,我们只使用了三个比特位:000、001、010、011、100、101、111。只需省略前面的 29 个零,我们不关心它们。 - ASDFGerte
好的,谢谢您的澄清!我习惯于类C的编程语言(在那里我通常使用\0),所以有时会感到困惑。 - Alejandro Iván
1
@AlejandroIván 但请注意,1 >>> 1 === 0 - ASDFGerte

2

很简单,只需将0到2**n-1之间的所有整数转换为二进制:

var n = 3,
    m = 1 << n;
for (var i = 0; i < m; i++) {
    var s = i.toString(2); // convert to binary
    s = new Array(n + 1 - s.length).join('0') + s; // pad with zeroes
    console.log(s);
}

上面的代码是通用的;您可以将n更改为所需的位数。

2

pow(2, n) 种可能的值。

在二进制数系统中,数字可以简单地被看作是位的“数组”:0=[0,0,0],1=[0,0,1],2=[0,1,0],3=[0,1,1],4=[1,0,0],5=[1,0,1],6=[1,1,0],7=[1,1,1]

按照这个思路,最简单的方法是提取整数[0, pow(2, n) - 1]的位。以下是代码,它是上述思想的直接实现:

function test()
{
   var n = 3;
   var k = (1 << n); // bit trick for pow(2, n)

   var truths = [];

   for (var i = 0; i < k; ++i)
   {
      truths[i] = [];

      for (var j = 0; j < n; ++j)
      {
         var value = (i >> j) & 1; // extract the j-th bit of i
         truths[i][j] = value;
      }

      console.log(truths[i]);
   }
}

1

const boolCombo = size => {
  const buf = Array(1 << size)
  for (let i = buf.length; i--;) {
    buf[ i ] = Array(size)
    for (let j = size; j--;)
      buf[ i ][ j ] = +!!(i & 1 << j)
  }
  return buf
}

console.log(boolCombo(3))


-1

#包括 <stdio.h>

#包括 <math.h>

int main()

{

int n, c, k, arr[100], m, i;

scanf("%d", &n);

m = pow(2, n);

for (i = 0; i < m; i++)

arr[i] = i;

for (i = 0; i < m; i++)

{

for (c = n-1; c >= 0; c--)

{

k = arr[i] >> c;

if (k & 1)

printf("正确");

else

printf("错误");

}

printf("\n");

}

返回 0;

}


欢迎来到StackOverflow。请查看如何回答问题 - CyberEternal
请添加更多细节以扩展您的答案,例如工作代码或文档引用。 - Community
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - Yunnosch
https://stackoverflow.com/editing-help - Yunnosch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接