编辑:我已经使用jsperf在这里对不同的方法进行了比较,Phrogz的方法明显是最快的,是第3个的两倍。
如果我理解正确,您正在询问如何计算每列数字是不同基数的情况。您可以通过递归实现此操作。
function options(opArr, fullArray){
var i = 0, j = opArr.length;
if(j < fullArray.length){
while(i < fullArray[j]){
newArr = opArr.slice(0);
newArr[j] = i;
i++;
options(newArr, fullArray);
}
}else{
}
}
options([], [3, 9, 3, 3]);
注意:这个(例子)将导致制作
3 * 9 * 3 * 3 = 243
个数组。这样做可能会消耗大量内存。
另一种方法是从整数转换为数组,这可能会节省内存使用,因为您可以忘记所有先前计算的数组。
function countUp(arrayOfBases, callback, self){
var arr = arrayOfBases.reverse(), x = 1, i = arr.length,
me = (self===undefined?this:self),
makeArr = function(arr, x, fn, me){
var a = arr.slice(0), n = [], i = x, j = 0, k = 0;
while(a.length > 0){
k = a[0];
if(k !== 0) j = i % k, i = (i - j) / k;
else j = 0;
n.unshift(j);
a.shift();
}
fn.call(me,n);
};
while (i-->0) if(arr[i] !== 0) x = x * arr[i];
i = 0;
while(i < x){
makeArr(arr, i, callback, me);
i++;
}
}
countUp([3,9,3,3], function(a){console.log(a);});
另一种方法类似于之前的方法,保留上次生成的数组,这样在循环中计算量会减少,但初始化时需要更多计算。
function countUp2(arrayOfBases, callback, self){
var arr = arrayOfBases.reverse(), x = 1, i = arr.length, last = [],
me = (self===undefined?this:self),
addOne = function(arr, n, fn, me){
var j = n.length, i = j - 1;
n[i]++;
while(j = i, i-- > 0 && n[j] >= arr[j]){
if(arr[j] === 0) n[i] += n[j], n[j] = 0;
else n[i]++, n[j] -= arr[j];
}
return fn.call(me,n.slice(0)), n;
};
while (i-->0){
if(arr[i] !== 0) x = x * arr[i];
last[i] = 0;
}
i = 0;
last[last.length-1] = -1;
while(i < x){
last = addOne(arr, last, callback, me);
i++;
}
}
countUp2([3,9,3,3], function(a){console.log(a);});
所有这些方法都会输出。
[0,0,0,0]
[0,0,0,1]
...
[0,8,1,2]
[0,8,2,0]
...
[2,8,2,1]
[2,8,2,2]
您可以随意处理这些数据,按照您的选择进行操作。