试图在JS中找到一个数字的因子

时间:2014-03-02 16:13:54

标签: javascript

我刚刚开始学习JS,并理解找到一个因素的概念。但是,这段代码就是我到目前为止所拥有的。我有str变量,只输出第一个因素,即2.我试图将每个(int)添加到str作为因素列表。下面的代码片段有什么问题?

function calculate(num) {
    var str = "";
    var int = 2;
    if (num % int == 0) {
        str = str + int;
        int++;
    } else {
        int++;
    }
    alert(str);
}

calculate(232);

13 个答案:

答案 0 :(得分:11)

ES6版本:

const factors = number => Array
    .from(Array(number + 1), (_, i) => i)
    .filter(i => number % i === 0)

 console.log(factors(36));      //  [1, 2, 3, 4, 6, 9, 12, 18, 36]

https://jsfiddle.net/1bkpq17b/

数组(数字)会创建一个空数组[数字]位置

Array.from(arr,(_,i)=> i)根据位置[0,1,2,3,4,5,6,使用值填充空数组7,8,9]

.filter(i => ...)将填充的[0,1,2,3,4,5]数组过滤到满足数字%i =的条件的元素== 0只留下作为原始数字因子的数字。

请注意,如果您处理大数字(或小数字),您可以直到Math.floor(数字/ 2)才能提高效率。

正如@gengns在评论中建议的那样,生成数组的一种更简单的方法是使用spread运算符和keys方法:

const factors = number => [...Array(number + 1).keys()]
          .filter(i => number % i === 0)

console.log(factors(36));      //  [1, 2, 3, 4, 6, 9, 12, 18, 36]

答案 1 :(得分:10)

@ Moob的回答是正确的。你必须使用一个循环。但是,您可以通过确定每个数字是偶数还是奇数来加快过程。奇怪的数字不需要像普通人那样检查每个数字。可以针对每个其他数字检查奇数。此外,我们不需要检查过去给定数字的一半,因为上半部分都不会有效。排除0并从1开始:

function calculate(num) {

    var half = Math.floor(num / 2), // Ensures a whole number <= num.
        str = '1', // 1 will be a part of every solution.
        i, j;

    // Determine our increment value for the loop and starting point.
    num % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);

    for (i; i <= half; i += j) {
        num % i === 0 ? str += ',' + i : false;
    }

    str += ',' + num; // Always include the original number.
    alert(str);
}

calculate(232);

http://jsfiddle.net/r8wh715t/

虽然我理解你的特定情况(计算232)计算速度不是因素(&lt; - 没有双关语),但可能成为更大数字或多次计算的问题。我正在Project Euler problem #12工作,我需要这种类型的函数,计算速度至关重要。

答案 2 :(得分:8)

function calculate(num) {
    var str = "0";
    for (var i = 1; i <= num; i++) {
        if (num % i == 0) {
            str += ',' + i;
        }
    }
    alert(str);
}

calculate(232);

http://jsfiddle.net/67qmt/

答案 3 :(得分:8)

作为@ the-quodesmith的answer的更高效的补充,一旦你有了一个因素,你就会立刻知道它的配对产品是什么:

function getFactors(num) {
  const isEven = num % 2 === 0;
  let inc = isEven ? 1 : 2;
  let factors = [1, num];

  for (let curFactor = isEven ? 2 : 3; Math.pow(curFactor, 2) <= num; curFactor += inc) {
    if (num % curFactor !== 0) continue;
    factors.push(curFactor);
    let compliment = num / curFactor;
    if (compliment !== curFactor) factors.push(compliment);
  }

  return factors;
}

对于getFactors(300),这将只运行15次循环,而不是原始的+ -150。

答案 4 :(得分:1)

以下是时间复杂度为O(sqrt(N))的实现:

function(A) {
  var output = [];

  for (var i=1; i <= Math.sqrt(A); i++) {
    if (A % i === 0) {
      output.push(i);

      if (i !== Math.sqrt(A)) output.push(A/i);
    }
  }

  if (output.indexOf(A) === -1) output.push(A);

  return output;
}

答案 5 :(得分:1)

这是性能友好的版本,复杂度为O(sqrt(N))。 输出是不使用sort的排序数组。

var factors = (num) => {
let fac = [], i = 1, ind = 0;

while (i <= Math.floor(Math.sqrt(num))) {
  //inserting new elements in the middle using splice
  if (num%i === 0) {
    fac.splice(ind,0,i);
    if (i != num/i) {
      fac.splice(-ind,0,num/i);
    }
    ind++;
  }
  i++;
}

//swapping first and last elements
let temp = fac[fac.length - 1];
fac[fac.length - 1] = fac[0];
fac[0] = temp;

// nice sorted array of factors
return fac;
};
console.log(factors(100));

输出: [1,2,4,5,10,20,25,50,100]

答案 6 :(得分:0)

@NonNull
public static Intent createForceBrowserIntent(Context context, @NonNull Uri uri)
{
    Intent intent = new Intent(context, ForceOpenInBrowserActivity.class);
    intent.setAction(Intent.ACTION_VIEW);
    intent.putExtra(ForceOpenInBrowserActivity.URI, uri);
    return intent;
}

答案 7 :(得分:0)

我来寻找一种算法用于factoring quadratic equations,这意味着我需要考虑正数和负数以及因子。以下函数执行此操作并返回因子对列表。 Fiddle

function getFactors(n) {
  if (n === 0) {return "∞";} // Deal with 0
  if (n % 1 !== 0) {return "The input must be an integer.";} // Deal with non-integers

  // Check only up to the square root of the absolute value of n
  // All factors above that will pair with factors below that
  var absval_of_n = Math.abs(n),
      sqrt_of_n = Math.sqrt(absval_of_n),
      numbers_to_check = [];
  for (var i=1; i <= sqrt_of_n; i++) {
    numbers_to_check.push(i);
  }

  // Create an array of factor pairs
  var factors = [];
  for (var i=0; i <= numbers_to_check.length; i++) {
    if (absval_of_n % i === 0) {
      // Include both positive and negative factors
      if (n>0) {
        factors.push([i, absval_of_n/i]);
        factors.push([-i, -absval_of_n/i]);
      } else {
        factors.push([-i, absval_of_n/i]);
        factors.push([i, -absval_of_n/i]);
      }
    }
  }

  // Test for the console
  console.log("FACTORS OF "+n+":\n"+
              "There are "+factors.length+" factor pairs.");
  for (var i=0; i<factors.length; i++) {
    console.log(factors[i]);
  }

  return factors;
}

getFactors(-26);

答案 8 :(得分:0)

function calculate(num){
    var str = "0"   // initializes a place holder for var str
      for(i=2;i<num;i++){     
        var num2 = num%i;
        if(num2 ==0){       
            str = str +i; // this line joins the factors to the var str
        }
    }
    str1 = str.substr(1) //This removes the initial --var str = "0" at line 2
    console.log(str1) 
}
calculate(232);

//Output 2482958116

答案 9 :(得分:0)

这是使用最佳实践,适当的代码样式/可读性并以有序数组返回结果的优化解决方案。

function getFactors(num) {
    const maxFactorNum = Math.floor(Math.sqrt(num));
    const factorArr = [];
    let count = 0;  //count of factors found < maxFactorNum.

    for (let i = 1; i <= maxFactorNum; i++) {
        //inserting new elements in the middle using splice
        if (num % i === 0) {
            factorArr.splice(count, 0, i);
            let otherFactor = num / i; //the other factor
            if (i != otherFactor) {
                //insert these factors in the front of the array
                factorArr.splice(-count, 0, otherFactor);
            }
            count++;
        }
    }

    //swapping first and last elements
    let lastIndex = factorArr.length - 1;
    let temp = factorArr[lastIndex];
    factorArr[lastIndex] = factorArr[0];
    factorArr[0] = temp;

    return factorArr;
}

console.log(getFactors(100));
console.log(getFactors(240));
console.log(getFactors(600851475143)); //large number used in Project Euler.

我的答案基于@Harman的答案

答案 10 :(得分:0)

这使我的Codility达到了85%(上限失败,超过10亿)。

将输入减少一半并不适合大量使用,因为一半仍然是一个很大的循环。因此,我使用一个对象来跟踪数字及其一半的值,这意味着当我们从两端同时工作时,可以将循环减少到四分之一。 N = 24变为:(1&24),(2&12),(3&8),(4&6)

function solution(N) {

    const factors = {};

     let num = 1;  
     let finished = false;
     while(!finished)
     {
         if(factors[num] !== undefined)
         {
             finished = true;
         }
         else if(Number.isInteger(N/num))
         {

          factors[num] = 0;
          factors[N/num]= 0;
         }
        num++
     }

    return Object.keys(factors).length;
}

答案 11 :(得分:0)

function primeFactors(n) {
  let arrPrime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79];
  let divisor = 2,
    divided = n,
    arr = [],
    count = 0, out = "";
  while (divisor < n) {
    if (divided % divisor == 0) {
      arr.push(divisor)
      divided /= divisor;
      console.log(divisor);
    }
    else {
      divisor++;
    }
  }
  console.log(count);
  // let news = arr.filter(num => num != ",")
  // console.log(news);
  // arr.slice(indexOf(map(",")), 1)
  return arr;
}

let out = primeFactors(86240);
console.log(out);

答案 12 :(得分:-1)

targetType