低效的JavaScript算法,如何使以下代码更有效?

时间:2017-06-07 16:09:44

标签: javascript

问题陈述:鉴于两个阵列 a b 编写一个函数comp( a,b )( clojure中的compSame( a,b ),用于检查两个数组是否具有“相同”元素,具有相同的多重性。 “相同”在这里表示 b 中的元素是 a 平方中的元素,无论顺序如何。

我的解决方案:

function comp(array1, array2){

  var test;

  if( array1.length <= 0 || array2.length <= 0 || array1 == null || array2 == null || array2.length != array1.length || array1==undefined || array2==undefined){
    return false;
  }else{
    for(i=0; i<array2.length; i++){
      for(j=0; j<array1.length; j++){
        if(array2[i] === Math.pow(array1[j],2)){
          test = true;
          break;
        }else{
          test = false;
        }
      }
      if(test==false)
        return false;
    }

    if(test === true)
      return true;
    else
      return false;
  }
}

此外,对于代码的任何建设性批评都表示赞赏,因为我仍然只是一个渴望改进的wookie。

测试示例:

var a1 = [80, 2, 65, 68];
var a2 = [6401, 4, 4225, 4624];

对于最终结果,我想要的是true,如果为true则返回true,同样为false。该程序解决了所有测试用例,但它超时。

2 个答案:

答案 0 :(得分:1)

用语言说:

  1. 对第一个数组进行平方
  2. 排序第一个数组
  3. 排序第二个数组。
  4. 现在,如果任何元素与另一个数组中的相应元素不匹配,则无法匹配。
  5. 否则匹配
  6. 在代码中:

    function comp(array1, array2){
    
        var test;
    
        if( !array1 || !array2 ){
            return false;
        }
    
        if ( array1.length != array2.length ){
            return false;
        }
    
        // first squre the array
        array1_squared = array1.map( function( val ){ return Math.pow( val, 2 ); } );
    
        // then sort both arrays
        array1_squared.sort()
        array2.sort()
    
        // then compare
        for ( var i=0 ; i < array1_squared.length ; i+= 1 ){
            if ( array1_squared[i] != array2[i] ) {
                return false;
            }
        }
    
        return true;
    }
    

    更多细节,因为:

    从概念上讲,我认为这更容易理解。一个区别是我在循环外做平方。你正在你的循环中做你的方块,这意味着你正在平方长度^ 2次,而不是长度时间。这会造成一些浪费的CPU周期。此外,您最终会循环遍历数组,同时循环遍历数组,这将给出长度** 2循环执行。相比之下,排序相当快,然后它让我们只用一个循环得到实际的答案。

答案 1 :(得分:1)

这是我的代码

function comp(arr1, arr2)
{
    // make sure the arrays are set and are of equal length (if not they obivously don't match)
    if(arr1 == null || arr2 == null || arr1.length != arr2.length)
        return false;
    // sort arrays
    var intSorter = function(a,b){return a-b;};
    arr1.sort(intSorter);
    arr2.sort(intSorter);
    for(var i=0;i<arr1.length;i++)
    {
        var v = arr1[i];
        // if square of value in arr1 does not equal the value in arr2, arrays don't match
        if(v*v!=arr2[i])
            return false;
    }
    return true;
}
// test it!
console.info(comp([2,6,3,8,4,5], [25,64,16,36,4,9]));
console.info(comp([2,6,3,8,4,5], [25,64,17,36,4,9]));
console.info(comp([2,6,3,8,4,5], [25,64,16,36,4,9,9]));

打印true,false,false

我不首先计算所有方块作为次要优化,我使用“自定义”intSorter因为JavaScript将数字排序为字符串,所以4在36之后结束('3'在'4'之前)

关于您的代码,您不需要test变量,只要知道函数结果就使用return,并且不要将pow()用于小值,因为它使用循环,可能比你做v*v时更加谨慎。