| 2 | BASIC CONCEPTS | ALGORITHMS | 1.1 |
Algorithm E. (Euclid's Algorithm). Given two positive integers m and n, find
their greatest common divisor, i.e., the largest positive integer which evenly
divides both m and n.
| E1. | [Find remainder.] Divide m by n and let r be the remainder. (We will have 0 ≤ r < n.) |
| E2. | [Is it zero?] If r = 0, the algorithm terminates; n is the answer. |
| E3. | [Interchange.] Set m ← n, n ← r, and go back to step E1. ❚ |
Simulation E. (Euclid's Algorithm).
The GCD of m and n is ...
| m | ||
| n | ||
| r |
Count: ?
Program En. (Euclid's Algorithm).
function gcd(m, n) { assertTrue(isPositiveInt(m) && isPositiveInt(n)); let r = undefined; while (true) { r = m % n; if (r === 0) { return n; } m = n; n = r; } } function isPositiveInt(n) { return isInt(n) && n > 0; } function isInt(n) { return n === parseInt(n); } function assertTrue(condition) { if (!condition) { throw Error('assertion failed'); } }
function gcd(m, n) { assertTrue(isPositiveInt(m) && isPositiveInt(n)); let r = mod(m, n); if (r === 0) { return n; } else { return gcd(n, r); } } function mod(m, n) { let r = m; while (r >= n) { r = r - n; } return r; } function isPositiveInt(n) { return isInt(n) && n > 0; } function isInt(n) { return n === parseInt(n); } function assertTrue(condition) { if (!condition) { throw Error('assertion failed'); } }
function gcd(m, n) { assertTrue(isPositiveInt(m) && isPositiveInt(n)); let r = mod(m, n); if (r === 0) return n; return gcd(n, r); } function mod(m, n) { let r = m; while (r >= n) r = r - n; return r; } function isPositiveInt(n) { return isInt(n) && n > 0; } function isInt(n) { return n === parseInt(n); } function assertTrue(condition) { if (!condition) { throw Error('assertion failed'); } }
function gcd(m, n) { assertTrue(isPositiveInt(m) && isPositiveInt(n)); let r = mod(m, n); return (r === 0) ? n : gcd(n, r); } function mod(m, n) { let r; for (r = m; r >= n; r = r - n) { } return r; } function isPositiveInt(n) { return isInt(n) && n > 0; } function isInt(n) { return n === parseInt(n); } function assertTrue(condition) { if (!condition) { throw Error('assertion failed'); } }
function gcd(m, n) { assertTrue(isPositiveInt(m) && isPositiveInt(n)); let r = mod(m, n); return (r === 0) ? n : gcd(n, r); } function mod(m, n) { for (var r = m; r >= n; r -= n); return r; } function isPositiveInt(n) { return isInt(n) && n > 0; } function isInt(n) { return n === parseInt(n); } function assertTrue(condition) { if (!condition) { throw Error('assertion failed'); } }
EXERCISES
- When translating the ECMAScript programs above into the Java programming language, why is it not necessary to include a translation of the function
isInt? - Create a Java class called
Utilwith methodsmod,isPositiveInt, andassertTrue. For each method, provide a Java implementation that is analogous to the corresponding ECMAScript function. What factors did you consider when deciding whether to make the methods static? - Translate the ECMAScript programs E1-4 above into the Java programming language by creating a class called
OkayMaththat has methodsgcd1, ...,gcd4and uses theUtilclass you created in the previous exercise. - Create an ECMAScript variation of program E1 called
gcd1DoWhilethat uses a “do-while” loop instead of awhileloop. Translate the ECMAScript program into Java. - Create a more efficient ECMAScript variation of program E1 called
gcd1FasterWhilethat also uses awhileloop but evaluates another expression instead oftrue. How is your program more efficient than program E1? - Using a
forloop instead of awhileloop, create an ECMAScript program calledgcd1FasterForthat is otherwise identical to the one you created in the previous exercise. - Create a Java class called
FasterMaththat extendsOkayMath(created in a previous exercise) and has a method that overridesOkayMath.gcd1with a Java translation of one of the two ECMAScript functions you created in the previous two exercises.
| ALGORITHM E | from TAOCP Vol. 1 (1973) by Donald Ervin Knuth |