现有一个不规范二维数组 [[1,2,3],[4,5],[6],[7,8,9,10],[11,12],[13,14],[15,16,17],[18,19,20]]
想得到该数组的所有组合方式,如[1,4,6,7,11,13,15,18],[1,4,6,7,11,13,15,19]......
如果用循环的话,项数太多就不适用了,请教各位高手有没有更好的算法?

解决方案 »

  1.   

    40分?以前有个类似的算法,150RMB,都没几个人能搞得上来的。
      

  2.   

    我简单说一下吧,获取每个数组元素的length属性,然后new一个random,然后random.nextInt(length)。用遍历得到数组对应下标(length-1)的每个结果,最为结果数组的元素就可以了吧。
      

  3.   

    LZ应该只要编写一个处理两个数组组合的函数,函数返回一个包含这两个数组组合的所有情况的数组。
    然后依次用它传第一项和第二项得到中间相吗,再和第三项一起传入(就是楼主的递归)
    ps js有段日子没写了,语法不记得了
      

  4.   

    function combo(m,n){ 
         var arr=[],sumArr=[],str,isBreak=false; 
         for(var i=0;i <m;i++){ 
             arr.push(0);     
         } 
         for(var i=0;i <n;i++){ 
             arr[i]=1;     
         } 
         str=arr.join(''); 
         while(1){ 
             var itemArr=[], 
                 reg=/(.*?)(10)/; 
             for(var j=0,len=str.length;j <len;j++){ 
                 str.charAt(j)!="0"&&itemArr.push(j); 
             } 
             sumArr.push(itemArr); 
             if(reg.test(str)){ 
                 str=str.replace(reg,function(l,s1,s2){ 
                     var num=s1.replace(/0/g,"").length, 
                         prefixstr=""; 
                     for(var i=0,len=s1.length;i <len;i++){ 
                         prefixstr+=(i <num?'1':'0');     
                     } 
                     return prefixstr+"01"; 
                 }); 
             }else{ 
                 break;     
             } 
         } 
         return sumArr; 
     } 
      
     function doubleCombo(arr,n){ 
         var arrLen=arr.length,finalArr=[]; 
         if(arrLen <n) { 
             alert("invalid input!"); 
             return; 
         } 
         var comboCol=combo(arrLen,n);//行序号组合数 
         for(var i=0,cl=comboCol.length;i <cl;i++){//得到组合的每一项 
             var colItem=comboCol[i],items=[[]]; 
             for(var j=0,il=colItem.length;j <il;j++){ 
                 var data=arr[colItem[j]]; 
                 if(typeof data=="number"){ 
                     for(var k=0,itemsLen=items.length;k <itemsLen;k++){ 
                         items[k].push(data);     
                     }     
                 } 
                 else{ 
                     var mitems=[]; 
                     for(var m=0;m <items.length;m++){         
                         for(var n=0;n <data.length;n++){ 
                             var mitem=items[m].concat([]); 
                             mitem.push(data[n]); 
                             mitems.push(mitem); 
                             //console.log(mitem); 
                             //console.log(mitems); 
                         }     
                     } 
                     items=mitems; 
                      
                 } 
             } 
             finalArr=finalArr.concat(items); 
         } 
         return finalArr; 
     } 
      
      
     //下面是调用和结果显示 
      
     var t=doubleCombo([1,2,3],[4,5],[6],[7,8,9,10],[11,12],[13,14],[15,16,17],[18,19,20],8) 
     for(var k=0,l=t.length;k <l;k++){ 
         var a=t[k]; 
         for(var j=0,l2=a.length;j <l2;j++) 
             document.write(a[j]+' '); 
         document.write(' <br/>'); 
     } 
      
      
    这个算法不是最适合你的,你的问题只是这个算法的一个子集,所以能用这个算法。
      

  5.   

    调用的时候写错了。为下面
     //下面是调用和结果显示 
      
     var t=doubleCombo([[1,2,3],[4,5],[6],[7,8,9,10],[11,12],[13,14],[15,16,17],[18,19,20]],8) 
     for(var k=0,l=t.length;k <l;k++){ 
          document.write(t[k]); 
         document.write(' <br/>'); 
     } 
      
      

  6.   

    谢谢JParser,试了下,是可行的!
      

  7.   

    嘿嘿,用这个问题发了一个博,里面有我的计算方法http://blog.csdn.net/danica7773/article/details/6801156
      

  8.   

    递归思想:
    function combo(arr) {
    if(arr.length === 1) {//数组只有一项,通常不会出现,一般递归到剩余最后两项为止
    return arr;
    } else if(arr.length === 2) {
    return 此处为递归到最内层,当数组里仅存2项时的返回值
    } else {//否则递归
    从arr.shift弹出一项(arr长度减1), 弹出项作为"当前项"
    用递归计算剩下的项,作为"剩余结果"
    return 根据"当前项"和"剩余结果"拼装最终值
    }
    }
    美观点的写法:// functional.jsfunction asArray(quasiArray, start) {  
        var result = [];  
        for (var i = (start || 0); i < quasiArray.length; i++)  
            result.push(quasiArray[i]);  
        return result;  
    }  function partial(func) {  
        var fixedArgs = asArray(arguments, 1);  
        return function() {  
            return func.apply(null, fixedArgs.concat(asArray(arguments)));  
        };  
    }  function forEach(array, action) {  
        for (var i = 0; i < array.length; i++)  
            action(array[i]);  
    }  function reduce(combine, base, array) {  
        forEach(array, function(element) {  
            base = combine(base, element);  
        });  
        return base;  
    }  function map(func, array) {  
        var result = [];  
        forEach(array, function(element) {  
            result.push(func(element));  
        });  
        return result;  
    } function flatten(arrays) {  
        var result = [];  
        forEach(arrays, function(array) {  
            forEach(array, function(element) {  
                result.push(element);  
            });  
        });  
        return result;  
    }  
    // test// arr = [[1,2,3],[4,5],[6],[7,8,9,10],[11,12],[13,14],[15,16,17],[18,19,20]];
    arr = [[1,2,3],[4,5],[6,7]];//a1 = [1,2,3]
    //a2 = [4,5]
    //ret= [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
    function matrix(a1, a2) {
    return flatten(map(function(x) {
    return map(function(y) {
    return [x, y];
    }, a2);
    }, a1));
    }// function make_pair(x, y) {
    //  return [x, y];
    // }
    // function num_arr(arr, x) {
    //  return map(partial(make_pair, x), arr);
    // }
    // function matrix(a1, a2) {//装X版的matrix
    //  return flatten(map(partial(num_arr, a2), a1));
    // }//a1 = [1,2]
    //a2 = [[3,4,5],[3,4,6]]
    //ret= [[1,3,4,5],[1,3,4,6],[2,3,4,5],[2,3,4,6]]
    function matrixes(a1, a2) {//装X版略
    return map(function(x) {
    return reduce(function(base, current) {
    var t = current.slice();//temp copy
    t.unshift(x);
    base.push(t);
    return base;
    }, [], a2);
    }, a1);
    }function combo(arr) {
    if(arr.length === 1) {
    return arr;
    } else if(arr.length === 2) {
    return matrix(arr[0], arr[1]);
    } else {
    var first = arr.shift(),
    rest = combo(arr);
    return flatten(matrixes(first, rest));
    }
    }
    r = combo(arr);
    console.table(r);以上代码中关于 map reduce flatten 等函数式编程方法,可以参考
    http://blog.csdn.net/aj3423/article/details/6210718在熟悉了函数式编程和递归思想之后,做这种题目不算太难的
      

  9.   

                function getArray(array1,array2){
                    var result = [];
                    for(var i =0,p;p=array1[i];i++){
                        var pTemp = [];
                        if(typeof(p) == "object"){
                            pTemp = p;
                        }else{
                            pTemp.push(p);
                        }
                        for(var j=0,q;q=array2[j];j++){
                            var qTemp = [];
                            if(typeof(q) == "object"){
                                qTemp = q;
                            }else{
                                qTemp.push(q);
                            }
                            result.push(pTemp.concat(qTemp));
                        }
                    }
                    return result;
                }
                
                var stack = [[1,2,3],[4,5],[6],[7,8,9,10],[11,12],[13,14],[15,16,17],[18,19,20]];
                var pop1 = stack.pop();
                while(stack.length>0){
                    var pop2 = stack.pop();
                    pop1 = getArray(pop1,pop2);
                }
                
                var strResult = [];
                for(var i = 0;i<pop1.length;i++){
                    strResult.push(pop1[i].join(" "));
                }
                alert(strResult.join("\n"));