2015-07-01 2 views
1

Я работаю над назначением javascript, и у меня есть некоторые проблемы с пониманием кода. Я работаю с этим кодом, и он работает, но я хочу сломать его дальше, чтобы действительно понять, что происходит. Я прокомментировал те части, которые я действительно понимаю, но оставил вопросы по некоторым из более сложных частей для меня.Найти самый низкий общий кратный диапазон чисел

//Finding the Least Common Denominator with a Recursive Euclidean Algorithm 
 
//GCD = Biggest Number that is divides into both evenly 
 
function gcd(a, b) { 
 
    return b ? gcd(b, a % b) : Math.abs(a); //Ternary Operator to run if b is valid 
 
    //Is this ternary operator only checking if the variable b exists? 
 
} 
 

 
//Least Common Multiple = Smallest number that is divisible by both numbers 
 
//Euclidean Algorithm 
 
function scm(a, b) { 
 
    return (a * b)/gcd(a, b); 
 
} 
 

 
//Iterate through each part of the array to find the LCM overall 
 
function smallestCommons(arr) { 
 
    arr = arr.sort(); 
 
    result = 1; 
 
    for (var i = arr[0]; i <= arr[1]; i++) { 
 
    //I am not quite sure what is happening in this for loop.   
 
    result = scm(result, scm(result, i)); 
 
    } 
 
    return result; 
 
} 
 

 
document.write('<pre>' + smallestCommons([1, 5]) + '</pre>');

+0

Тройной оператор проверяет, если переменная 'b' является [ "truthy"] (https://developer.mozilla.org/en-US/docs/Glossary/Truthy) или [ "falsy"] (https://developer.mozilla.org/en-US/docs/Glossary/Falsy). Прочтите [ternary operator] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) документы и, пожалуйста, исследуйте свои вопросы, прежде чем спрашивать здесь. – Blazemonger

+0

Первый - это просто ярлык для if/else. И его использование рекурсии (вызов самой функции) для поиска GCD. – Wazaaaap

+0

Действительно ли 60 - это LCM [1,5]? ;-) –

ответ

1

Является ли это троичный оператор проверяет только если переменная Ь существует?

Нет, это проверка, если это truthy value: значение, которое переводится верно, когда оценивается в логическом контексте. Все значения являются правдивыми, если они не определены как ложные (то есть, за исключением false, 0, "", null, undefined и NaN).

Если b не указано, его значение будет undefined, что является ложным значением. В представленном коде фактически проверяется, является ли значение 0 из-за рекурсии с использованием модуля: gcb(b, a % b).

Я не совсем уверен, что происходит в этом для цикла.

Во-первых, это могло бы помочь разбить его так:

var res; 
// `arr[0]` is the first value which is assigned to `i` 
// The loop will iterate until `i` is equal to 
// the second value `arr[1]` 
for (var i = arr[0]; i <= arr[1]; i++) { 
    res = scm(result, i); 
    result = scm(result, res); 
} 

И затем вручную шаг через него с входом [1, 5]:

  1. С: result === 1; i === 1; arr[1] === 5;

    res = scm(1, 1) // res === 1

    result = scm(1, 1) // result === 1

  2. С: result === 1; i === 2; arr[1] === 5;

    res = scm(1, 2) // res === 2

    result = scm(1, 2) // result === 2

  3. С: result === 2; i === 3; arr[1] === 5;

    res = scm(2, 3) // res === 6

    result = scm(2, 6) // result === 6

  4. С: result === 6; i === 4; arr[1] === 5;

    res = scm(6, 4) // res === 12

    result = scm(6, 12) // result === 12

  5. С: result === 12; i === 5; arr[1] === 5;ПОСЛЕДНЕГО LOOP

    res = scm(12, 5) // res === 60

    result = scm(12, 60) // result === 60

Несколько наблюдений должны быть сделаны:

  • ли 60 действительно LCM из [1, 5]?
  • Зачем делать два вызова scm, если и внутренний вызов scm, и внешний вызов scm возвращают одинаковое значение?

Я бы предположил, что код не работает должным образом. :)

+1

Это не отвечает на все вопросы, заданные @Eric Park, поэтому он недействителен для ответа. – Wazaaaap

+0

@wazaap Это было из непреднамеренного представления. –

2

Is this ternary operator only checking if the variable b exists?

Обозначения только для проверки того, что она является truthy значение, так как Blazemonger прокомментировал. Однако он специально предназначен для остановки рекурсии, когда выполняется базовое условие (то есть b = 0).

I am not quite sure what is happening in this for loop.

Цикл оценивает LCM всех чисел от arr[0] к arr[1], принимая один номер за один раз.Это делается для того, чтобы избежать превышения целочисленного предела в случае больших чисел.

Оценка основана на том, что для трех целых чисел a, b и c, LCM(a, b, c) = LCM(LCM(a, b), c) и LCM(1, x) = x. Поэтому на каждом шаге цикл оценивает LCM обрабатываемой части и текущего элемента (то есть i).

1

Первая функция - это рекурсивная функция (функция, в которой вы вызываете ту же функцию). Он будет вызывать себя до тех пор, пока не будет вызван со значением b, равным 0. Для этого существует тернарный оператор. Пока это не 0, тест оценивается как ИСТИНА, следовательно, делает первую инструкцию, рекурсию с манипуляцией, которую вы видите. Всякий раз, когда% b будет 0, то есть a делится на b, это будет фактически последний рекурсивный вызов, тернарный тест будет оцениваться как FALSE и возвращающее значение a.

Вторая функция просто использует этот первый, чтобы использовать математическую формулу для поиска наименьшего общего кратного.

Третья функция использует вторую, чтобы найти scm серии чисел, начальный диапазон, и цикл делает именно это, переменную i, итерирующую от нижней границы до более высокой границы диапазона.

2

Я написал свой ответ в качестве комментариев ниже. Изменены некоторые имена и исправлены неправильный алгоритм.

/* 
When b is not zero, null, undefined, NaN (not a number), or false, then compute greatestCommonDivisor(b, a % b). Otherwise return the absoute value of a. 
This will make sense if you step through it with an example. Let's try to find the greatest common divisor of 6 and 9, which we know is 3. 

1. a=6, b=9 
2. a=9, b=6 
3. a=6, b=3 
4. a=3, b=0 
5. B is falsy! 
return absoulte value of a, which is 3. 
*/ 
function greatestCommonDivisor(a, b) { 
    return b ? greatestCommonDivisor(b, a % b) : Math.abs(a); 
} 

function leastCommonMultipleOfTwo(a, b) { 
    return (a * b)/greatestCommonDivisor(a, b); 
} 

/* 
No wonder you were confused. The algorithm they gave you was wrong. I fixed it below. Let's look at that with an example. 

Let's say we're trying to find the least common multiple of [5, 2, 9]. Logically we know it's 90. (The wrong algorithm gave 60). 

The algorithm below takes the array elements one at a time, and finds the LCM of it and whatever LCM we've calculated so far. 
Initially we start with calculatedLCM = 1 to get the algorithm started. 

1. we look at arr[0], which is 5 
calculatedLCM = leastCommonMultipleOfTwo(1,5) 
calculatedLCM = 5 

2. we look at arr[1], which is 2 
calculatedLCM = leastCommonMultipleOfTwo(5,2) 
calculatedLCM = 10 

3. we look at arr[2], which is 9 
calculatedLCM = leastCommonMultipleOfTwo(10,9) 
calculatedLCM = 90 

*/ 

function leastCommonMultiple(arr) { 
    calculatedLCM = 1; 
    for (var i = 0; i < arr.length; i++) { 
     calculatedLCM = leastCommonMultipleOfTwo(calculatedLCM, arr[i]); 
    } 
    return calculatedLCM; 
} 

console.log(leastCommonMultiple([5, 2, 9])); 
Смежные вопросы