Holen Sie sich die nächstgelegene Nummer aus dem Array

163

Ich habe eine Zahl von minus 1000 bis plus 1000 und ich habe ein Array mit Zahlen. So was:

[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]

Ich möchte, dass sich die Nummer, die ich habe, in die nächste Nummer des Arrays ändert.

Zum Beispiel bekomme 80ich die Nummer, die ich bekommen möchte 82.

Anfänger
quelle
2
Unmöglich einfach: Legen Sie eine Variable beiseite x, gehen Sie das Array nacheinander durch, vergleichen Sie sie imit der aktuellen Nummer im Array, wenn die Differenz zwischen ihr und ikleiner als der aktuelle Wert in ist x, setzen Sie sie xauf die aktuelle Array-Nummer. Wenn Sie fertig sind, xhaben Sie die Nummer, idie dem Array am nächsten kommt .
Täuschung

Antworten:

208

ES5-Version:

var counts = [4, 9, 15, 6, 2],
  goal = 5;

var closest = counts.reduce(function(prev, curr) {
  return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});

console.log(closest);

Joe Grund
quelle
1
Nachteil ist, dass es nur funktioniert, wenn der Rückruf von reduct aus demselben Bereich wie die deklarierten vars aufgerufen wird. Da Sie die goalReduzierung nicht bestehen können , müssen Sie sie aus einem globalen Bereich referenzieren.
7yl4r
5
könnte auch eine Funktion höherer Ordnung verwenden, um dies zu tun.
dmp
3
@ 7yl4r oder in eine Funktion einwickeln? ;)
Dominic
1
@ 7yl4r nicht wirklich ... Sie können bind verwenden, um dies zu erreichen ... ---------- // reducer.js Funktionsreduzierer (Ziel, prev, curr) {return (Math.abs (curr - Ziel) <Math.abs (prev - Ziel)? curr: prev); } // main.js var zählt = [4, 9, 15, 6, 2], Ziel = 5; zählt.reduzieren (reducer.bind (null, Ziel)); ---------- Ich weiß nicht, wie ich Code in die Kommentare einfügen soll hahaha.
Mauricio Soares
Dies iteriert über jedes Element, was nicht optimal ist, wenn die Liste bestellt wird, aber für kleine Listen in Ordnung ist. Auch ohne eine binäre Suche könnte eine Schleife beendet werden, wenn die nächste Nummer weiter entfernt ist.
Dominic
144

Hier ist der Pseudocode, der in jede prozedurale Sprache konvertierbar sein sollte:

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)

def closest (num, arr):
    curr = arr[0]
    foreach val in arr:
        if abs (num - val) < abs (num - curr):
            curr = val
    return curr

Es berechnet einfach die absoluten Unterschiede zwischen der angegebenen Anzahl und jedem Array-Element und gibt Ihnen einen der mit dem minimalen Unterschied zurück.

Für die Beispielwerte:

number = 112  112  112  112  112  112  112  112  112  112
array  =   2   42   82  122  162  202  242  282  322  362
diff   = 110   70   30   10   50   90  130  170  210  250
                         |
                         +-- one with minimal absolute difference.

Als Proof of Concept ist hier der Python-Code, mit dem ich dies in Aktion gezeigt habe:

def closest (num, arr):
    curr = arr[0]
    for index in range (len (arr)):
        if abs (num - arr[index]) < abs (num - curr):
            curr = arr[index]
    return curr

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)

Und wenn Sie es wirklich in Javascript brauchen, finden Sie unten eine vollständige HTML-Datei, die die Funktion in Aktion demonstriert:

<html>
    <head></head>
    <body>
        <script language="javascript">
            function closest (num, arr) {
                var curr = arr[0];
                var diff = Math.abs (num - curr);
                for (var val = 0; val < arr.length; val++) {
                    var newdiff = Math.abs (num - arr[val]);
                    if (newdiff < diff) {
                        diff = newdiff;
                        curr = arr[val];
                    }
                }
                return curr;
            }
            array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
            number = 112;
            alert (closest (number, array));
        </script>
    </body>
</html>

Denken Sie jetzt daran, dass möglicherweise die Effizienz verbessert werden kann, wenn beispielsweise Ihre Datenelemente sortiert sind (dies könnte aus den Beispieldaten abgeleitet werden, aber Sie geben es nicht explizit an). Sie können beispielsweise eine binäre Suche verwenden, um das nächstgelegene Element zu finden.

Sie sollten auch bedenken , dass, wenn Sie es tun müssen , viele Male pro Sekunde, werden die Effizienzverbesserungen werden meist unnoticable es sei denn , Ihre Datensätze bekommen viel größer.

Wenn Sie es auf diese Weise versuchen möchten (und garantieren können, dass das Array in aufsteigender Reihenfolge sortiert ist), ist dies ein guter Ausgangspunkt:

<html>
    <head></head>
    <body>
        <script language="javascript">
            function closest (num, arr) {
                var mid;
                var lo = 0;
                var hi = arr.length - 1;
                while (hi - lo > 1) {
                    mid = Math.floor ((lo + hi) / 2);
                    if (arr[mid] < num) {
                        lo = mid;
                    } else {
                        hi = mid;
                    }
                }
                if (num - arr[lo] <= arr[hi] - num) {
                    return arr[lo];
                }
                return arr[hi];
            }
            array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
            number = 112;
            alert (closest (number, array));
        </script>
    </body>
</html>

Grundsätzlich wird die Klammerung und Überprüfung des Mittelwerts verwendet, um den Lösungsraum für jede Iteration um die Hälfte zu reduzieren. Dies ist ein klassischer O(log N)Algorithmus, während die obige sequentielle Suche wie folgt lautete O(N):

0  1  2   3   4   5   6   7   8   9  <- indexes
2 42 82 122 162 202 242 282 322 362  <- values
L             M                   H  L=0, H=9, M=4, 162 higher, H<-M
L     M       H                      L=0, H=4, M=2, 82 lower/equal, L<-M
      L   M   H                      L=2, H=4, M=3, 122 higher, H<-M
      L   H                          L=2, H=3, difference of 1 so exit
          ^
          |
          H (122-112=10) is closer than L (112-82=30) so choose H

Wie bereits erwähnt, das sollte nicht viel Unterschied für kleine Datenmengen oder für Dinge, die nicht brauchen blendend schnell zu sein, aber es ist eine Option , die Sie betrachten wünschen können.

paxdiablo
quelle
2
@micha, ich habe der Antwort den entsprechenden JS-Code hinzugefügt. Es hat nur eine Weile gedauert, bis ich die Sprache von einer Sprache geändert habe, an die ich eher
gewöhnt war
2
Schlechte Laufzeit für diesen Algorithmus, wenn Sie große Datenmengen haben.
ylun.ca
4
@ ylun.ca, da die Frage, dass die Daten sortiert sind (das Beispiel ist sortiert, aber das kann Zufall sein), keine explizite Aussage enthält, können Sie keine bessere Effizienz als O (n) erzielen . In jedem Fall ist für einen Datensatz dieser Größe die Effizienz meistens irrelevant. Aber Ihr Punkt ist gültig, deshalb werde ich entsprechende Notizen hinzufügen, um die Antwort hoffentlich vollständiger zu machen.
Paxdiablo
1
Vielen Dank, ich wünschte, ich könnte mehr als einmal upvoten! Weitere Antworten zum Stapelüberlauf sollten diese Art von Aufwand erfordern.
Richard Vanbergen
48

ES6 (2015) Version:

const counts = [4, 9, 15, 6, 2];
const goal = 5;

const output = counts.reduce((prev, curr) => Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);

console.log(output);

Zur Wiederverwendbarkeit können Sie eine Curry-Funktion einbinden, die Platzhalter unterstützt ( http://ramdajs.com/0.19.1/docs/#curry oder https://lodash.com/docs#curry ). Dies bietet viel Flexibilität, je nachdem, was Sie benötigen:

const getClosest = curry((counts, goal) => {
  return counts
    .reduce((prev, curr) => Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});

const closestTo5 = getClosest(_, 5);
const closestTo = getClosest([4, 9, 15, 6, 2]);
Joe Grund
quelle
24

Arbeitscode wie folgt:

var array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

function closest(array, num) {
  var i = 0;
  var minDiff = 1000;
  var ans;
  for (i in array) {
    var m = Math.abs(num - array[i]);
    if (m < minDiff) {
      minDiff = m;
      ans = array[i];
    }
  }
  return ans;
}
console.log(closest(array, 88));

Umesh Patil
quelle
8
Je mehr, desto besser.
Hot Licks
6
Ich würde argumentieren, dass dies eine bessere Lösung ist, da nur JavaScript verwendet wird. Die akzeptierte Antwort verwendet jQuery, das in der ursprünglichen Frage nicht erwähnt wurde und das andere, die sich diese Frage ansehen, möglicherweise nicht verwenden.
Sean the Bean
17

Funktioniert mit unsortierten Arrays

Obwohl hier einige gute Lösungen veröffentlicht wurden, ist JavaScript eine flexible Sprache, mit der wir ein Problem auf viele verschiedene Arten lösen können. Natürlich hängt alles von Ihrem Stil ab. Wenn Ihr Code funktionaler ist, finden Sie die reduzierte Variation geeignet, dh:

  arr.reduce(function (prev, curr) {
    return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
  });

Einige können dies jedoch je nach Codierungsstil schwer lesen. Deshalb schlage ich einen neuen Weg zur Lösung des Problems vor:

  var findClosest = function (x, arr) {
    var indexArr = arr.map(function(k) { return Math.abs(k - x) })
    var min = Math.min.apply(Math, indexArr)
    return arr[indexArr.indexOf(min)]
  }

  findClosest(80, [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]) // Outputs 82

Im Gegensatz zu anderen Ansätzen mitMath.min.apply , muss das Eingabearray arrnicht sortiert werden . Wir müssen uns nicht um die Indizes kümmern oder sie vorher sortieren.

Ich werde den Code der Klarheit halber Zeile für Zeile erklären:

  1. arr.map(function(k) { return Math.abs(k - x) }) Erstellt ein neues Array, in dem im Wesentlichen die absoluten Werte der angegebenen Zahlen gespeichert werden (Zahl in arr ) abzüglich der eingegebenen Zahl ( x) . Wir werden als nächstes nach der kleinsten Zahl suchen (die auch der eingegebenen Zahl am nächsten kommt).
  2. Math.min.apply(Math, indexArr) Dies ist ein legitimer Weg, um die kleinste Zahl in dem Array zu finden, das wir gerade zuvor erstellt haben (nichts weiter dazu)
  3. arr[indexArr.indexOf(min)]Dies ist vielleicht der interessanteste Teil. Wir haben unsere kleinste Zahl gefunden, sind uns aber nicht sicher, ob wir die ursprüngliche Zahl addieren oder subtrahieren sollen ( x). Das liegt daran, dass wir Math.abs()den Unterschied gefunden haben. Allerdings array.mapschafft (logisch) eine Karte der Eingangsanordnung, die Indizes an der gleichen Stelle zu halten. Um die nächstgelegene Zahl herauszufinden, geben wir einfach den Index des gefundenen Minimums im angegebenen Array zurück indexArr.indexOf(min).

Ich habe einen Behälter erstellt, der dies demonstriert.

Dan Mindru
quelle
1
Ich weiß es nicht, aber ich denke, man könnte Leistungszweifel haben, da dies praktisch ist 3nund es ES5 ist, obwohl Sie 2016 antworten und andere Lösungen in Ordnung sind, obwohl dieser Noob, der diese Frage gestellt hat, zu diesem Zeitpunkt eindeutig kein Programmierer war.
Noob
1
Ja, es ist toll zu sehen, wie du lernst! Übrigens habe ich nur über Leistungszweifel gesprochen, ohne zu argumentieren, dass es tatsächlich schlechter O(n)abschneidet, aber ich habe die Zahlen für Sie angegeben und Ihre Lösung führt O(log n)bei Zufallszahlen etwa 100.000 Ops / Sek. Weniger aus als @paxdiablo . Beim Entwerfen eines Algorithmus wird immer zuerst sortiert. (Außer wenn Sie wissen, was Sie tun und Benchmarks haben, die Sie unterstützen.)
Noob
1
Requisiten für die einfache Lösung. Funktioniert hervorragend für meinen Anwendungsfall (ich habe nicht den Luxus, ein vorsortiertes Array zu haben, wie es Noob tut.)
jaggedsoft
2
Sie können die findClosest-Rückgabe zu einer Funktion zum Reduzieren des Rückrufs machen, um sie auf allen Arrays wiederverwendbar zu machen: const findClosest = goal => (a,b) => Math.abs(a - goal) < Math.abs(b - goal) ? a : b;
Jakob E
1
Beispiel: [2, 42, 82, 122, 162, 202, 242, 282, 322, 362].reduce(findClosest(80))
Jakob E
11

Für sortierte Arrays (lineare Suche)

Alle bisherigen Antworten konzentrieren sich auf die Suche im gesamten Array. Wenn man bedenkt, dass Ihr Array bereits sortiert ist und Sie wirklich nur die nächste Nummer wollen, ist dies wahrscheinlich die schnellste Lösung:

var a = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
var target = 90000;

/**
 * Returns the closest number from a sorted array.
 **/
function closest(arr, target) {
  if (!(arr) || arr.length == 0)
    return null;
  if (arr.length == 1)
    return arr[0];

  for (var i = 1; i < arr.length; i++) {
    // As soon as a number bigger than target is found, return the previous or current
    // number depending on which has smaller difference to the target.
    if (arr[i] > target) {
      var p = arr[i - 1];
      var c = arr[i]
      return Math.abs(p - target) < Math.abs(c - target) ? p : c;
    }
  }
  // No number in array is bigger so return the last.
  return arr[arr.length - 1];
}

// Trying it out
console.log(closest(a, target));

Beachten Sie, dass der Algorithmus erheblich verbessert werden kann, z. B. mithilfe eines Binärbaums.

Hubert Grzeskowiak
quelle
Während diese Strategie hier gut ist, hat dies mehrere Tippfehler. Beispiel a[i]oder i[0].
Wesley Workman
1
Danke, @WesleyWorkman. Habe sie einfach repariert. Ich hoffe ich habe alles. Sie können übrigens auch die Antworten anderer bearbeiten.
Hubert Grzeskowiak
Wo muss ich die Korrektur im oben beantworteten Code vornehmen, um den höheren nächstgelegenen Wert zu erhalten? Beispiel: [110, 111, 120, 140, 148, 149, 155, 177, 188, 190] Wenn ich 150 suche, sollte ich 155 und nicht 149 erhalten. Ich habe versucht, aber Schwierigkeiten bei der Lösung dieses Problems zu finden. Kannst du bitte helfen. Danke
user1199842
9

Alle Lösungen sind überentwickelt.

Es ist so einfach wie:

const needle = 5;
const haystack = [1, 2, 3, 4, 5, 6, 7, 8, 9];

haystack.sort((a, b) => {
  return Math.abs(a - needle) - Math.abs(b - needle);
});

// 5
Gajus
quelle
1
In der Tat viel mehr auf den Punkt. Um jedoch "die nächstgelegene Zahl aus dem Array herauszuholen", müssen Sie noch das erste Element aus dem sortierten Array auswählen.
Shaya Ulman
6

Diese Lösung verwendet einen existenziellen ES5- QuantifiziererArray#some , mit dem die Iteration gestoppt werden kann, wenn eine Bedingung erfüllt ist.

Im Gegensatz Array#reducedazu müssen nicht alle Elemente für ein Ergebnis iteriert werden.

Innerhalb des Rückrufs ein Absolut deltazwischen dem gesuchten Wert und dem tatsächlichen Wertitem genommen und mit dem letzten Delta verglichen. Wenn größer oder gleich, stoppt die Iteration, da alle anderen Werte mit ihren Deltas größer als der tatsächliche Wert sind.

Wenn der deltaRückruf kleiner ist, wird das eigentliche Element dem Ergebnis zugeordnet und deltain gespeichert lastDelta.

Schließlich werden kleinere Werte mit gleichen Deltas genommen, wie im folgenden Beispiel von 22, was zu ergibt 2.

Wenn es eine Priorität für größere Werte gibt, muss die Delta-Prüfung geändert werden von:

if (delta >= lastDelta) {

zu:

if (delta > lastDelta) {
//       ^^^ without equal sign

Dies würde mit 22dem Ergebnis kommen42 einhergehen (Priorität größerer Werte).

Diese Funktion benötigt sortierte Werte im Array.


Code mit Priorität kleinerer Werte:

function closestValue(array, value) {
    var result,
        lastDelta;

    array.some(function (item) {
        var delta = Math.abs(value - item);
        if (delta >= lastDelta) {
            return true;
        }
        result = item;
        lastDelta = delta;
    });
    return result;
}

var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

console.log(21, closestValue(data, 21)); // 2
console.log(22, closestValue(data, 22)); // 2  smaller value
console.log(23, closestValue(data, 23)); // 42
console.log(80, closestValue(data, 80)); // 82

Code mit Priorität größerer Werte:

function closestValue(array, value) {
    var result,
        lastDelta;

    array.some(function (item) {
        var delta = Math.abs(value - item);
        if (delta > lastDelta) {
            return true;
        }
        result = item;
        lastDelta = delta;
    });
    return result;
}

var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

console.log(21, closestValue(data, 21)); //  2
console.log(22, closestValue(data, 22)); // 42 greater value
console.log(23, closestValue(data, 23)); // 42
console.log(80, closestValue(data, 80)); // 82

Nina Scholz
quelle
Sie nehmen also an, dass das angegebene Array sortiert ist ... Das erspart Ihnen verdammt viel Zeit.
Reduzieren Sie den
1
Das Array der Operation sieht sortiert aus, also ja :)
Nina Scholz
Die erste Lösung wird bei Eingaben unterbrochen, die zweimal dieselbe Nummer enthalten. zBclosestValue([ 2, 2, 42, 80 ], 50) === 2
Sébastien Vercammen
@ SébastienVercammen, die Daten von op sind eindeutig und sortiert.
Nina Scholz
@NinaScholz OP hat nur festgestellt, dass "Ich habe ein Array mit Zahlen" und "Ich möchte, dass die Nummer, die ich habe, auf die nächste Nummer des Arrays geändert wird" . Das Beispielarray war nur ein Beispiel. Ein Array garantiert keine eindeutigen Einträge.
Sébastien Vercammen
4

ES6

Funktioniert mit sortierten und unsortierten Arrays

Numbers Integers and Floats, Strings begrüßt

/**
 * Finds the nearest value in an array of numbers.
 * Example: nearestValue(array, 42)
 * 
 * @param {Array<number>} arr
 * @param {number} val the ideal value for which the nearest or equal should be found
 */
const nearestValue = (arr, val) => arr.reduce((p, n) => (Math.abs(p) > Math.abs(n - val) ? n - val : p), Infinity) + val

Beispiele:

let values = [1,2,3,4,5]
console.log(nearestValue(values, 10)) // --> 5
console.log(nearestValue(values, 0)) // --> 1
console.log(nearestValue(values, 2.5)) // --> 2

values = [100,5,90,56]
console.log(nearestValue(values, 42)) // --> 56

values = ['100','5','90','56']
console.log(nearestValue(values, 42)) // --> 56
Sébastien
quelle
3

Ich weiß nicht, ob ich eine alte Frage beantworten soll, aber da dieser Beitrag zuerst in der Google-Suche erscheint, hoffte ich, dass Sie mir verzeihen, dass ich meine Lösung und meine 2c hier hinzufüge.

Da ich faul war, konnte ich nicht glauben, dass die Lösung für diese Frage eine Schleife sein würde, also suchte ich ein bisschen mehr und kam mit der Filterfunktion zurück :

var myArray = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
var myValue = 80;

function BiggerThan(inArray) {
  return inArray > myValue;
}

var arrBiggerElements = myArray.filter(BiggerThan);
var nextElement = Math.min.apply(null, arrBiggerElements);
alert(nextElement);

Das ist alles !

FrenchieFred
quelle
1
Was ist also mit der Untergrenze? Sie verwenden immer den nächsthöheren Wert. Aber Ihr Ansatz erinnert mich an goog.math.clamp(Google Closure) nur mit Arrays und ohne Rücksicht auf die Untergrenze.
Noob
Ihre Lösung gibt die nächsthöhere Zahl aus dem Array zurück. Es werden weder der nächste noch der genaue Wert gefunden.
Hubert Grzeskowiak
2

Meine Antwort auf eine ähnliche Frage berücksichtigt auch Bindungen und ist in einfachem Javascript, obwohl keine binäre Suche verwendet wird, also O (N) und nicht O (logN):

var searchArray= [0, 30, 60, 90];
var element= 33;

function findClosest(array,elem){
    var minDelta = null;
    var minIndex = null;
    for (var i = 0 ; i<array.length; i++){
        var delta = Math.abs(array[i]-elem);
        if (minDelta == null || delta < minDelta){
            minDelta = delta;
            minIndex = i;
        }
        //if it is a tie return an array of both values
        else if (delta == minDelta) {
            return [array[minIndex],array[i]];
        }//if it has already found the closest value
        else {
            return array[i-1];
        }

    }
    return array[minIndex];
}
var closest = findClosest(searchArray,element);

https://stackoverflow.com/a/26429528/986160

Michail Michailidis
quelle
2

Ich mag den Ansatz von Fusion, aber es gibt einen kleinen Fehler. So ist es richtig:

    function closest(array, number) {
        var num = 0;
        for (var i = array.length - 1; i >= 0; i--) {
            if(Math.abs(number - array[i]) < Math.abs(number - array[num])){
                num = i;
            }
        }
        return array[num];
    }

Es ist auch etwas schneller, weil es die verbesserte forSchleife verwendet.

Am Ende habe ich meine Funktion so geschrieben:

    var getClosest = function(number, array) {
        var current = array[0];
        var difference = Math.abs(number - current);
        var index = array.length;
        while (index--) {
            var newDifference = Math.abs(number - array[index]);
            if (newDifference < difference) {
                difference = newDifference;
                current = array[index];
            }
        }
        return current;
    };

Ich habe es mit getestet console.time()und es ist etwas schneller als die andere Funktion.

Jon
quelle
Hey, kannst du erklären, warum es ein ist improved for loop? Umgekehrte Schleifen sind nicht immer eine Leistungsverbesserung.
A1rPun
Sie werten .lengthnur einmal aus, wenn Sie deklarieren i, während für diese Schleife. Aber ich denke var i = arr.length;while (i--) {}wäre noch schneller
Jon
Ich habe meine Antwort aktualisiert. Ich habe es geändert in while. Jetzt geht es noch schneller.
Jon
0

Eine leicht modifizierte binäre Suche im Array würde funktionieren.

Holygeek
quelle
3
Gee, das ist bizarr - anscheinend mag jemand keine binären Suchen. (Auch wenn das die beste allgemeine Lösung ist.)
Hot Licks
0

Für einen kleinen Bereich ist es am einfachsten, ein Kartenarray zu haben, in dem beispielsweise der 80. Eintrag den Wert 82 enthält, um Ihr Beispiel zu verwenden. Für einen viel größeren, spärlichen Bereich ist der Weg wahrscheinlich eine binäre Suche.

Mit einer Abfragesprache können Sie Werte in einiger Entfernung zu beiden Seiten Ihrer Eingabenummer abfragen und dann die resultierende reduzierte Liste sortieren. SQL hat jedoch kein gutes Konzept für "Weiter" oder "Zurück", um Ihnen eine "saubere" Lösung zu bieten.

Hot Licks
quelle
0

Eine andere Variante hier ist ein kreisförmiger Bereich, der Kopf bis Fuß verbindet und nur einen minimalen Wert für die gegebene Eingabe akzeptiert. Dies hatte mir geholfen, Zeichencodewerte für einen der Verschlüsselungsalgorithmen zu erhalten.

function closestNumberInCircularRange(codes, charCode) {
  return codes.reduce((p_code, c_code)=>{
    if(((Math.abs(p_code-charCode) > Math.abs(c_code-charCode)) || p_code > charCode) && c_code < charCode){
      return c_code;
    }else if(p_code < charCode){
      return p_code;
    }else if(p_code > charCode && c_code > charCode){
      return Math.max.apply(Math, [p_code, c_code]);
    }
    return p_code;
  });
}
Vikas
quelle
0
#include <algorithm>
#include <iostream>
#include <cmath>

using namespace std;

class CompareFunctor
{

public:
    CompareFunctor(int n) { _n = n; }
    bool operator()(int & val1, int & val2)
    {
        int diff1 = abs(val1 - _n);
        int diff2 = abs(val2 - _n);
        return (diff1 < diff2);
    }

private:
    int _n;
};

int Find_Closest_Value(int nums[], int size, int n)
{
    CompareFunctor cf(n);
    int cn = *min_element(nums, nums + size, cf);
    return cn;
}

int main()
{
    int nums[] = { 2, 42, 82, 122, 162, 202, 242, 282, 322, 362 };
    int size = sizeof(nums) / sizeof(int);
    int n = 80;
    int cn = Find_Closest_Value(nums, size, n);
    cout << "\nClosest value = " << cn << endl;
    cin.get();
}
Rushikesh
quelle
0

Am effizientesten wäre eine binäre Suche. Es können jedoch auch einfache Lösungen beendet werden, wenn die nächste Zahl weiter mit der aktuellen übereinstimmt . Fast alle Lösungen hier berücksichtigen nicht, dass das Array geordnet ist und durch das Ganze iteriert: /

const closest = (orderedArray, value, valueGetter = item => item) =>
  orderedArray.find((item, i) =>
    i === orderedArray.length - 1 ||
    Math.abs(value - valueGetter(item)) < Math.abs(value - valueGetter(orderedArray[i + 1])));

var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

console.log('21 -> 2', closest(data, 21) === 2);
console.log('22 -> 42', closest(data, 22) === 42); // equidistant between 2 and 42, select highest
console.log('23 -> 42', closest(data, 23) === 42);
console.log('80 -> 82', closest(data, 80) === 82);

Dies kann auch auf Nicht-Grundelementen ausgeführt werden, z closest(data, 21, item => item.age)

Wechseln Sie findzu findIndex, um den Index im Array zurückzugeben.

Dominic
quelle
Was ist mit ungeordnetem Array?
EdG
Nehmen Sie für Ungeordnete eine der Lösungen, die nicht beendet wird. Wenn Sie die Arbeit jedoch mehrmals ausführen, ist es möglicherweise optimaler, das Array einmal zu sortieren. Wie bereits erwähnt, ist eine binäre Suche effizienter als eine lineare, wenn das Array wirklich groß ist.
Dominic
0

So finden Sie zwei nächstgelegene Zahlen im Array

function findTwoClosest(givenList, goal) {
  var first;
  var second;
  var finalCollection = [givenList[0], givenList[1]];
  givenList.forEach((item, firtIndex) => {
    first = item;

    for (let i = firtIndex + 1; i < givenList.length; i++) {
      second = givenList[i];

      if (first + second < goal) {
        if (first + second > finalCollection[0] + finalCollection[1]) {
          finalCollection = [first, second];
        }
      }
    }
  });

  return finalCollection;
}

var counts = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
var goal = 80;
console.log(findTwoClosest(counts, goal));
M Abdullah
quelle
-5

Hier ist das Code-Snippet, um das Element zu finden, das einer Zahl aus einem Array in Complexity O (nlog (n)) am nächsten kommt: -

Eingabe: - {1,60,0, -10,100,87,56} Element: - 56 Nächste Zahl im Array: - 60

Quellcode (Java):

package com.algo.closestnumberinarray;
import java.util.TreeMap;


public class Find_Closest_Number_In_Array {

    public static void main(String arsg[]) {
        int array[] = { 1, 60, 0, -10, 100, 87, 69 };
        int number = 56;
        int num = getClosestNumber(array, number);
        System.out.println("Number is=" + num);
    }

    public static int getClosestNumber(int[] array, int number) {
        int diff[] = new int[array.length];

        TreeMap<Integer, Integer> keyVal = new TreeMap<Integer, Integer>();
        for (int i = 0; i < array.length; i++) {

            if (array[i] > number) {
                diff[i] = array[i] - number;
                keyVal.put(diff[i], array[i]);
            } else {
                diff[i] = number - array[i];
                keyVal.put(diff[i], array[i]);
            }

        }

        int closestKey = keyVal.firstKey();
        int closestVal = keyVal.get(closestKey);

        return closestVal;
    }
}
Totes Schwimmbad
quelle
Post fragte nach Javascript in Tags
Shannon Hochkins