Two arrays, where items in array x can be in array y but not vice versa, test all permutations

后端 未结 1 1022
不思量自难忘°
不思量自难忘° 2020-11-30 14:28

A small application that I have written allows a user to add various items to two arrays. Some logic calculates a figure from the contents of each array.

Any items i

相关标签:
1条回答
  • 2020-11-30 15:27

    Use this for creating the power set of x:

    function power(x, y) {
        var r = [y || []], // an empty set/array as fallback
            l = 1;
        for (var i=0; i<x.length; l=1<<++i) // OK, l is just r[i].length, but this looks nicer :)
            for (var j=0; j<l; j++) {
                r.push(r[j].slice(0)); // copy
                r[j].push(x[i]);
            }
        return r;
    }
    

    Usage:

    > power([0,2], [5,6])
    [[5,6,0,2], [5,6,2], [5,6,0], [5,6]]
    

    I have been told do this using bitwise math to remember the possibilities or 'permutations' but I am struggling to get my head around this particular problem at this stage.

    It would be iterating to 2n (for an array of length n), using single bits to determine whether an item should be included in the subset. Example for an array [a,b]:

    i   binary   included in set
    -----------------------------
    0   00       {      }
    1   01       {    b }
    2   10       { a    }
    3   11       { a, b }
    

    We can use bitwise operators in JS for arrays with up to 31 items (which should be enough).

    function power(x, y) {
        var l = Math.pow(2, x.length),
            r = new Array(l);
        for (var i=0; i<l; i++) {
            var sub = y ? y.slice(0) : [];
            for (var j=0; j<x.length; j++)
                // if the jth bit from the right is set in i
                if (i & Math.pow(2,j)) // Math.pow(2,j) === 1<<j
                    sub.push(x[j]);
            r[i] = sub;
        }
        return r;
    }
    
    0 讨论(0)
提交回复
热议问题