将两个排序的数组合并为一个

时间:2017-03-15 17:53:33

标签: javascript arrays algorithm sorting puzzle

您好我被问到以下问题。

给定两个数组,即array1和array2。它们都按排序顺序包含数字。

Array1还包含-1等; array2中的数字与array1中的多个-1一样多。

示例如下,

array1 = [-1,-1,-1,-1,56,78,90,1200];
array2 = [1,4,5,1000]

我需要编写一个程序,将上面的数组合并为一个,它将按排序顺序包含两个数组中的数字,除了-1。

这是我的代码如下,

 puzzle04([3,6,-1,11,15,-1,23,34,-1,42],[1,12,28]);
 puzzle04([3,6,-1,11,15,-1,23,34,-1,42],[7,19,38]);
 puzzle04([3,6,11,15,32,34,42,-1,-1,-1,-1],[1,10,17,56]);
 puzzle04([-1,-1,-1,-1,3,6,11,15,32,34,42],[1,10,17,56]);
 puzzle04([-1,-1,-1,-1,3,6,11,15,32,34,42],[56,78,90,100]);
 puzzle04([12,34,65,-1,71,85,90,-1,101,120,-1,200],[24,37,94]);
 puzzle04([3,6,-1,11,15,-1,32,34,-1,42,-1],[1,10,17,56]);
 puzzle04([-1,-1,-1,56,78,90,112],[1,4,5]);
 puzzle04([-1,-1,-1,-1,56,78,90,112],[1,4,5,1000]);
 puzzle04([-1,-1,-1,-1,56,78,90,1200],[1,4,5,1000]); 

 function puzzle04(array1,array2){

    var outputArray = [],
        array1Counter = 0, // counter for array1
        array2Counter = 0, // counter for array2
        isArray2NumPlaced = false, // has number from array2 found its position in output array ?       
        areAllArray2NumsFilled = false; // is number pushed in output array

    // iterating through array2 loop    
    for(array2Counter = 0; array2Counter < array2.length; array2Counter++){

        // iterating through array1 loop
        for(; (isArray2NumPlaced === false); array1Counter++){

            // -1 encountered in array1
            if(array1[array1Counter] === -1){ 
                continue;

            // if array1 number is less than array2 number
            // then push array1 number in ouput array   
            }else if(array1[array1Counter] < array2[array2Counter]){

                outputArray.push(array1[array1Counter]);                

            }else{ // array2 number is less then array1 number

                // add array2 number in output array until
                // all array2 numbers are not added in output array.
                if(areAllArray2NumsFilled === false){
                    outputArray.push(array2[array2Counter]);    
                }               


                // is array2 number pushed in output array ?
                isArray2NumPlaced = true;

            }// end of if-else

            // if all the array2 numbers are added in output array
            // but still array1 numbers are left to be added
            if(isArray2NumPlaced === true 
            && array2Counter === (array2.length - 1) 
            && array1Counter <= (array1.length - 1)){

                outputArray.push(array1[array1Counter]);    

                // set the below flag to false so that,
                // array1 loop can iterate
                isArray2NumPlaced = false;

                // all the numbers of array2 are entered in output array
                areAllArray2NumsFilled = true;

            }// end of if

        }// array1 for-loops ends



        array1Counter--;
        isArray2NumPlaced = false;

    }// array2 for-loops ends


    console.log("final ",outputArray);  
}

以上代码的输出如下,

final  [ 1, 3, 6, 11, 12, 15, 23, 28, 34, 42 ]
final  [ 3, 6, 7, 11, 15, 19, 23, 34, 38, 42 ]
final  [ 1, 3, 6, 10, 11, 15, 17, 32, 34, 42, 56 ]
final  [ 1, 3, 6, 10, 11, 15, 17, 32, 34, 42, 56 ]
final  [ 3, 6, 11, 15, 32, 34, 42, 56, 78, 90, 100 ]
final  [ 12, 24, 34, 37, 65, 71, 85, 90, 94, 101, 120, 200 ]
final  [ 1, 3, 6, 10, 11, 15, 17, 32, 34, 42, 56 ]
final  [ 1, 4, 5, 56, 78, 90, 112 ]
final  [ 1, 4, 5, 56, 78, 90, 112, 1000 ]
final  [ 1, 4, 5, 56, 78, 90, 1000, 1200 ]

当我向审稿人展示我的代码时,他说我使用了太多的布尔变量,代码可以更加简单。

我尽力即兴发挥,但没有任何线索。

您能否建议我解决上述问题的更好方法

注意:不能使用任何现成的排序方法或预先编写的api来解决上述练习。

8 个答案:

答案 0 :(得分:3)

您所要做的就是逐步浏览两个数组,取两个值中较小的一个,然后将其添加到输出列表中。一旦添加了所有一个数组,另一个数组的其余部分都会变大,并且可以一次性添加。

function merge(x, y) {
    var i = 0;
    var j = 0;
    var result = [];

    while (i < x.length && j < y.length) {
        // Skip negative numbers
        if (x[i] === -1) {
            x += 1;
            continue;
        }
        if (y[j] === -1) {
            y += 1;
            continue;
        }

        // Take the smaller of the two values, and add it to the output.
        // Note: the index (i or j) is only incremented when we use the corresponding value
        if (x[i] <= y[j]) {
            result.push(x[i]);
            i += 1;
        } else {
            result.push(y[j]);
            j += 1;
        }
    }

    // At this point, we have reached the end of one of the two arrays. The remainder of
    // the other array is all larger than what is currently in the output array

    while (i < x.length) {
        result.push(x[i]);
        i += 1;
    }

    while (j < y.length) {
        result.push(y[j]);
        j += 1;
    }

    return result;
}

答案 1 :(得分:1)

function merge(array1, array2)
{
    int i = 0, j = 0;
    array3; //answer
    while ( i<array1.size() and j<array2.size() ){

        if (array1[i] == -1 ) //ignore -1
        {   ++i; continue; }
        if (array2[j] == -1 ) //ignore -1
        {   ++j; continue; }

        if ( array1[i] < array2[j] ) { //choose the minor
            array3.push( array1[i] );
            ++i;
        }
        else {
            array3.push( array2[j] );
            ++j;    
        }
    }

    //if some array has elements still
    while (i < array1.size() )
        array3.push(array1[i]);
    while (j < array2.size() )
        array3.push(array1[j]);

    return array3
}

答案 2 :(得分:1)

要将2个已排序的阵列拼接在一起,您可以按如下所示进行拼接。要添加省略特定值的功能,可以在合并数组之前使用 var arglist = new Dictionary<string, object>() { { "1",1 } , {"2",2 }, {"3",new object() } }; string testval = CustomerInfo(arglist); 来消除这些元素。

&#13 ;
&#13;
.filter()
&#13;
&#13;

答案 3 :(得分:1)

function merge(array1, array2){
        var array = [];
        var i = 0;
        var j = 0;
        while(i < array1.length || j < array2.length){
            if(array1[i] === -1){
                i++;
                continue;
            }
            if(array1[i] && (!array2[j] || array1[i] <= array2[j])){
                array.push(array1[i]);
                i++;
            } else if(array2[j] && (!array1[i] || array2[j] <= array1[i])){
                array.push(array2[j]);
                j++;
            }
        }
        return array;
    }

答案 4 :(得分:1)

试试这个

function puzzle04(arr1, arr2) 
{    
    var result = [];
    var final = [];
    var arr_concat = arr1.concat(arr2).filter(function (value) {
       return value != -1;
    });

    arr_concat.forEach(function(x) { 
        if(!result[x]) { 
            result[x] = []; 
            result[x].push('super sort'); 
        }
        else { 
            result[x].push('super sort'); 
        } 
    });

    result.forEach(function(k, v) { 
        k.forEach(function(x) {
            final.push(v); 
        }); 
    });

    console.log(final);
}

答案 5 :(得分:1)

您所描述的是mergeSort

function puzzle04(array1, array2) {
  return mergeSortWithoutMinusOnes(array1.concat(array2))
}

function mergeSortWithoutMinusOnes(items){

  if (items.length < 2) {
    return items;
  }

  var middle = Math.floor(items.length / 2),
      left    = items.slice(0, middle),
      right   = items.slice(middle);

  return mergeWithoutMinusOnes(mergeSortWithoutMinusOnes(left), mergeSortWithoutMinusOnes(right));
}

function mergeWithoutMinusOnes(left, right){
  var result  = [],
      il      = 0,
      ir      = 0;

  while (il < left.length && ir < right.length){
    if (left[il] < right[ir]){
      if (left[il] === -1) {
        il++;
      } else {
        result.push(left[il++]);
      }
    } else {
      if (right[ir] === -1) {
        ir++
      } else {
        result.push(right[ir++]);
      } 
    }
  }

  return result.concat(left.slice(il)).concat(right.slice(ir));
}

来自:https://github.com/nzakas/computer-science-in-javascript/blob/master/algorithms/sorting/merge-sort-recursive/merge-sort-recursive.js,修改为忽略减去。

答案 6 :(得分:1)

考虑您的特殊-1排除条件;您可以选择将多个已排序的数组合并为一个,如下所示;

&#13;
&#13;
function merger(a,b,_,__,r = []){
  return !a.length ? !b.length ? r
                               : r.concat(b.filter(n => n > -1))
                   : !b.length ? r.concat(a.filter(n => n > -1))
                               : a[0] > -1 ? b[0] > -1 ? a[0] > b[0] ? (r.push(b[0]), merger(a,b.slice(1),_,__,r))
                                                                     : (r.push(a[0]), merger(a.slice(1),b,_,__,r))
                                                       : merger(a,b.slice(1),_,__,r)
                                           : merger(a.slice(1),b,_,__,r);
}

var arrs =  [[3,6,-1,11,15,-1,23,34,-1,42],[1,12,28],[3,6,-1,11,15,-1,23,34,-1,42],[7,19,38],[3,6,11,15,32,34,42,-1,-1,-1,-1],[1,10,17,56],[-1,-1,-1,-1,3,6,11,15,32,34,42],[1,10,17,56],[-1,-1,-1,-1,3,6,11,15,32,34,42],[56,78,90,100],[12,34,65,-1,71,85,90,-1,101,120,-1,200],[24,37,94],[3,6,-1,11,15,-1,32,34,-1,42,-1],[1,10,17,56],[-1,-1,-1,56,78,90,112],[1,4,5],[-1,-1,-1,-1,56,78,90,112],[1,4,5,1000],[-1,-1,-1,-1,56,78,90,1200],[1,4,5,1000]],
     res = arrs.reduce(merger);
console.log(JSON.stringify(res));
&#13;
&#13;
&#13;

答案 7 :(得分:0)

您可以在一个循环中迭代arrayOne,然后arrayTwo

这个想法是将目标索引与实际索引分开。第一个循环忽略-1并保留目标索引。

如果实际值大于arrayTwo的第一个值,则会交换这两个值,并通过迭代并使用更大的值进行交换来在arrayTwo中进行排序。

然后,将实际项目分配给目标索引。

两个指数都会增加。

最后,所有arrayTwo项都会添加到arrayOne

function puzzle04(arrayOne, arrayTwo) {
    var i = 0, j, l = 0;
    while (i < arrayOne.length) {
        if (arrayOne[i] === -1) {
            i++;
            continue;
        }
        if (arrayTwo[0] < arrayOne[i]) {
            [arrayOne[i], arrayTwo[0]] = [arrayTwo[0], arrayOne[i]];
            j = 0;
            while (arrayTwo[j] > arrayTwo[j + 1]) {
                [arrayTwo[j], arrayTwo[j + 1]] = [arrayTwo[j + 1], arrayTwo[j]];
                j++;
            }
        }
        arrayOne[l++] = arrayOne[i++];
    }
    j = 0;
    while (l < arrayOne.length) {
        arrayOne[l++] = arrayTwo[j++];
    }
    return arrayOne;
}

console.log(puzzle04([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [1, 12, 28]));
console.log(puzzle04([3, 6, -1, 11, 15, -1, 23, 34, -1, 42], [7, 19, 38]));
console.log(puzzle04([3, 6, 11, 15, 32, 34, 42, -1, -1, -1, -1], [1, 10, 17, 56]));
console.log(puzzle04([-1, -1, -1, -1, 3, 6, 11, 15, 32, 34, 42], [1, 10, 17, 56]));
console.log(puzzle04([-1, -1, -1, -1, 3, 6, 11, 15, 32, 34, 42], [56, 78, 90, 100]));
console.log(puzzle04([12, 34, 65, -1, 71, 85, 90, -1, 101, 120, -1, 200], [24, 37, 94]));
console.log(puzzle04([3, 6, -1, 11, 15, -1, 32, 34, -1, 42, -1], [1, 10, 17, 56]));
console.log(puzzle04([-1, -1, -1, 56, 78, 90, 112], [1, 4, 5]));
console.log(puzzle04([-1, -1, -1, -1, 56, 78, 90, 112], [1, 4, 5, 1000]));
console.log(puzzle04([-1, -1, -1, -1, 56, 78, 90, 1200], [1, 4, 5, 1000]));
.as-console-wrapper { max-height: 100% !important; top: 0; }