2011-01-10 8 views

Antwort

54
// Reduce a fraction by finding the Greatest Common Divisor and dividing by it. 
function reduce(numerator,denominator){ 
    var gcd = function gcd(a,b){ 
    return b ? gcd(b, a%b) : a; 
    }; 
    gcd = gcd(numerator,denominator); 
    return [numerator/gcd, denominator/gcd]; 
} 

reduce(2,4); 
// [1,2] 

reduce(13427,3413358); 
// [463,117702] 
+2

Das ist eine sehr elegante 'gcd' Funktion. Die einzige Änderung, die ich vorschlagen würde, ist eine Form der Eingangsüberprüfung für 'NaN', da' gcd (NaN, 1) '' 1' erzeugt, wo ich 'NaN' oder einen Fehler erwarten würde. – zzzzBov

+2

@zzzzBov Ein interessanter Randfall. Gewiss könnte man 'if (isNaN (Zähler) || isNaN (Nenner)) addieren NaN;' als erste Zeile. – Phrogz

+1

Spaß Tatsache, diese Lösung verwendet Euklid-Algorithmus, um GCD zu finden: https://en.wikipedia.org/wiki/Euclidean_algorithm – camou

7

Nein, aber Sie können sich selbst ziemlich leicht schreiben. Im Wesentlichen müssen Sie die oberen und unteren Teile des Bruches durch ihren "größten gemeinsamen Nenner" teilen ... Was Sie aus dem Algorithmus von Euklid berechnen können.

Lesen Sie hier für weitere Informationen: http://www.jimloy.com/number/euclids.htm

edit:

Code

(weil jeder es zu tun scheint, dies allerdings nicht genutzt wird Rekursion)
var FractionReduce = (function(){ 
    //Euclid's Algorithm 
    var getGCD = function(n, d){ 
     var numerator = (n<d)?n:d; 
     var denominator = (n<d)?d:n;   
     var remainder = numerator; 
     var lastRemainder = numerator; 

     while (true){ 
      lastRemainder = remainder; 
      remainder = denominator % numerator; 
      if (remainder === 0){ 
       break; 
      } 
      denominator = numerator; 
      numerator = remainder; 
     } 
     if(lastRemainder){ 
      return lastRemainder; 
     } 
    }; 

    var reduce = function(n, d){ 
     var gcd = getGCD(n, d); 

     return [n/gcd, d/gcd]; 
    }; 

    return { 
      getGCD:getGCD, 
      reduce:reduce 
      }; 

}()); 

alert(FractionReduce.reduce(3413358, 13427)); 
+0

+1 für den Umgang mit Zähler> Nenner – Phrogz

5

zu Reduziere einen Bruch, teile den Zähler und den Nenner durch den größten gemeinsamen Faktor. Phrogz und David haben bereits den Quellcode zur Verfügung gestellt.

Wenn Sie jedoch Javascript Bibliotheken für die Handhabung von Brüchen suchen, dann hier sind ein paar zur Auswahl.

  1. Fraction.js
  2. Math.Rational
  3. Ratio.js
  4. Rational.js

Hier ist ein Beispiel unter Verwendung von Ratio.js.

var a = Ratio(2,4); 

a.toString() == "2/4"; 
a.simplify().toString() == "1/2"; // reduce() returns a clone of the Ratio() 
a.toString() == "2/4"; // Ratio functions are non-destructive. 
+0

Nützlich, danke. Ich habe eine Frage gestellt, in der Sie nach der relativen Effizienz dieser Bibliotheken gefragt werden: http: // stackoverflow.com/questions/15840390/Was ist die effizienteste Fraktion-Bibliothek in Javascript? noredirect = 1 # comment22538987_15840390 – Omn

+1

@Omn Also haben Sie bereits die Leistung mit jsperf.com Profil? Wenn Sie Probleme mit Ratio.js sehen, wenn Sie einfach ein Ticket öffnen, werde ich versuchen, es zu beheben. https://github.com/LarryBattle/Ratio.js –

+0

Ich habe keine Erfahrung beim Erstellen und Ausführen von Benchmarks. Am Ende ging ich einfach in den Code und schaute auf etwas, das besser zu kodieren, zu kommentieren und Funktionen zu implementieren schien. Ich beendete das Gespräch mit Ratio.js, aber ich hatte seither keine Gelegenheit, an diesem Projekt zu arbeiten. Ich werde Sie sicherlich wissen lassen, wenn ich irgendwelche Probleme finde, und ich kann nur Bugfixes beisteuern, wenn ich das Problem selbst sehen kann. – Omn

1

Ich weiß, es ist schon eine Antwort, aber ich möchte eine JS-Bibliothek teilen, die ich gefunden, wenn ich etwas zu konvertieren Dezimalzahlen in Fraktionen und Reduktions Fraktionen anschaute.

Die Bibliothek ruft Fraction.js an, was mir sehr geholfen hat und mir viel Zeit und Arbeit erspart hat. Hoffe, dass es für jemand anderen sehr nützlich sein kann!

0

Hier ist eine rekursive Funktion mit ECMAScript 6 reduzieren. Es funktioniert für die meisten Fraktionen, solange der Rest nicht zu klein ist. 0 wurde neu definiert, damit es für Arrays wie [1.2, 2.4, 12, 24] funktioniert. Ich habe es in Chrome und IE Edge getestet, sodass es sich in anderen Browsern oder Upgrades möglicherweise anders verhält. Es sollte also mit einem Array von Floats funktionieren.

Array.prototype.gcd = function() { 
    if (this.length === 0) 
    return null; 
    return this.reduce((prev, curr) => { 
    if (curr <= 1.00000000001e-12) 
     return prev 
    else 
     return [curr, prev % curr].gcd(); 
    }); 
    } 

    var reducedValueGCD = [1.2, 2.4, 12, 24, 240].gcd(); 

Suche nach MDN reduzieren oder weiteren Informationen here.

Verwandte Themen