随机化然后将数组减少到一个值

Randomize and then Reduce Array down to one value

我不是程序员,但我得到了一个可以手动或算法完成的任务。手动执行此操作既费时又容易出错。不幸的是,我不知道从哪里开始。

给定数组[1, 2, 3, 4]

如何通过以下方式减少它:

[2, 3, 4] 1 出局

[1, 3, 4] 2 出局

[1, 2, 4] 3 出局

[1, 2, 3] 4 出局

[3, 4] 1、2出

[2, 4] 1、3出

[2, 3] 1, 4出局

[1, 4] 2、3出

[1, 3] 2, 4出局

[1, 2]3、4出

[4] 1, 2, 3 出局

[3] 1, 2, 4 出局

[2] 1, 3, 4 出局

[1] 2, 3, 4 出局

数组越大,变化越多。顺序不是随机的,但有一种我无法用语言描述的规律。

谢谢

这是一种方法:

function picks(arr) {
    // Indexes of the values that should be "out". -1 means nothing goes out.
    let out = Array(arr.length).fill(-1);
    let result = [];
    while (out[1] <= 0) {
        let i = arr.length;
        while (i-- && ++out[i] > i) {}
        for (let j = i+1; j < arr.length; j++) out[j] = out[j-1] + 1;
        let category = [[], []];
        for (let i = 0, j = 0; i < arr.length; i++) {
            while (out[j] < i) j++;
            category[+(out[j] === i)].push(arr[i]);
        }
        result.push(category);
    }
    return result;
}

// Demo run
let arr = [1, 2, 3, 4];
for (let [a, b] of picks(arr)) console.log(JSON.stringify(a), JSON.stringify(b)); 

要做到这一点,使用二进制数非常有帮助。您正在使用大小为 4 的数组,因此您首先需要将 2 提高到 4,即 16。现在您创建一个循环,将以二进制形式存储从 1 到 16 的每个数字。

var arr[16];
  for (i = 0; i < 16; i++) {
  arr[i]=binary(i);
}

计算二进制的函数如下:

string binario(int n){
    if(n>=2) {
        binario(n/2); 
        arr[n].concat(""+n%2);
    }
    else {
        arr[n].concat(""+n);
    }
}

有了这个,是时候使用之前的数组打印每个案例了 var arr_original[16];

for (let i = 0; i < 16; i++) {
    for (let j = 0; j < 4; j++) {
        if (j+1==1) {
            if (arr[i][j]) {
                arr_original[i][j] = "1";
            }else{
                arr_original[i][j] = "0";
            }
        }
        if (j+1 == 2) {
            if (arr[i][j]) {
                arr_original[i][j] = "1";
            } else {
                arr_original[i][j] = "0";
            }
        }
        if (j+1 == 3) {
            if (arr[i][j]) {
                arr_original[i][j] = "1";
            } else {
                arr_original[i][j] = "0";
            }
        }
        if (j+1 == 4) {
            if (arr[i][j]) {
                arr_original[i][j] = "1";
            } else {
                arr_original[i][j] = "0";
            }
        }
    }
}

此代码将为您提供数组的每个排列。我对 javascript 了解不多,我认为存在一些语法错误,但该算法是有效的。 希望你能成功!

这个的递归解决方案

const result = [];

function combinations(arr, size){
    for(let i=(arr[arr.length > 0 ? arr.length-1:0 ] || 0) + 1; i<=size; i++)
    {
        let comb = arr.concat(i);
        result.push(comb);
        combinations(comb, size);
    }
}
combinations([],5);

console.log(JSON.stringify(result));

学期数将为

(如果我们包括原始数组)

nC1 + nC2 + nC3 ...... + nC n = 2n-1

使用 binaris 在 @Juventino 上扩展:

function binary(dec, bits) {
  var b=[];
  var d=dec;
  while(d>0) {
    var r=d%2;
    b.unshift(r);
    d=Math.floor(d/2);
  }
  while(b.length<bits) b.unshift(0);
  return b;
}
array=[1,2,3,4]
for(var i=15; i>=0; i--) {
  var bi=binary(i, 4);
  var bxi=binary(15-i,4);
  //console.log(bi, bxi);
  var inArr=[];
  for(var ia=0; ia<bi.length; ia++) {
    if(bi[ia]==1) inArr.push(array[ia]);
  }
  var outArr=[];
  for(var oa=0; oa<bxi.length; oa++) {
    if(bxi[oa]==1) outArr.push(array[oa]);
  }
  console.log(inArr, outArr);
}

输出:

> (4) [1, 2, 3, 4] []
> (3) [1, 2, 3] [4]
> (3) [1, 2, 4] [3]
> (2) [1, 2] (2) [3, 4]
> (3) [1, 3, 4] [2]
> (2) [1, 3] (2) [2, 4]
> (2) [1, 4] (2) [2, 3]
> [1] (3) [2, 3, 4]
> (3) [2, 3, 4] [1]
> (2) [2, 3] (2) [1, 4]
> (2) [2, 4] (2) [1, 3]
> [2] (3) [1, 3, 4]
> (2) [3, 4] (2) [1, 2]
> [3] (3) [1, 2, 4]
> [4] (3) [1, 2, 3]
> [] (4) [1, 2, 3, 4]