सरणी से निकटतम संख्या प्राप्त करें


163

मेरे पास माइनस 1000 से प्लस 1000 तक की संख्या है और मेरे पास इसमें संख्याओं के साथ एक सरणी है। ऐशे ही:

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

मैं चाहता हूं कि जिस नंबर से मुझे निकटतम संख्या में परिवर्तन मिला है वह सरणी है।

उदाहरण के लिए मुझे 80जितनी संख्या चाहिए, मैं उसे प्राप्त करना चाहता हूं 82


2
सरल रूप से सरल: एक चर सेट xकरें, एक-एक करके सरणी के माध्यम से जाएं, सरणी iमें वर्तमान संख्या की तुलना करें , यदि इसके बीच का अंतर और iवर्तमान मान से छोटा है x, xतो वर्तमान सरणी संख्या पर सेट करें। समाप्त होने पर, सरणी से xनिकटतम संख्या है i
deceze

जवाबों:


208

ES5 संस्करण:

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);


1
नकारात्मक पक्ष यह है कि यह केवल तभी काम करता है जब कम करने की कॉलबैक को उसी दायरे से घोषित var के रूप में कहा जाता है। चूंकि आप goalकम करने के लिए पास नहीं कर सकते , इसलिए आपको इसे वैश्विक दायरे से संदर्भित करना चाहिए।
7yl4r

5
ऐसा करने के लिए एक उच्च आदेश फ़ंक्शन का उपयोग कर सकता है।
dmp

3
@ 7yl4r या इसे किसी फ़ंक्शन में लपेटें? ;)
डोमिनिक

1
@ 7yl4r वास्तव में नहीं है ... आप इसे प्राप्त करने के लिए बाइंड का उपयोग कर सकते हैं ... ---------- // reducer.js फ़ंक्शन रिड्यूसर (लक्ष्य, प्राइम, कर्व) {रिटर्न (Math.abs) (वक्र - लक्ष्य) <Math.abs (मौजूदा - लक्ष्य); वक्र: प्रबल); } // main.js var मायने रखता है = [4, 9, 15, 6, 2], लक्ष्य = 5; मायने रखता है (reducer.bind (शून्य, लक्ष्य)); ---------- मुझे नहीं पता कि हाहाहा टिप्पणियों में कोड कैसे डालते हैं।
मौरिसियो

यह प्रत्येक आइटम पर पुनरावृत्ति करता है जो सूची के आदेश दिए जाने पर इष्टतम नहीं है लेकिन छोटी सूचियों के लिए ठीक है। बाइनरी खोज के बिना भी एक लूप बाहर निकल सकता है अगर अगला नंबर आगे का रास्ता है।
डोमिनिक

144

यहाँ छद्म कोड है जो किसी भी प्रक्रियात्मक भाषा में परिवर्तनीय होना चाहिए:

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

यह बस दिए गए नंबर और प्रत्येक एरे तत्व के बीच के अंतर को पूरा करता है और आपको इनमें से एक को न्यूनतम अंतर के साथ वापस देता है।

उदाहरण के लिए मान:

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.

अवधारणा के प्रमाण के रूप में, यहाँ पायथन कोड जो मैं इस क्रिया में दिखाता था:

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)

और, यदि आपको वास्तव में जावास्क्रिप्ट में इसकी आवश्यकता है , तो एक पूर्ण HTML फ़ाइल के लिए नीचे देखें जो क्रिया में फ़ंक्शन को प्रदर्शित करती है:

<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>

अब ध्यान रखें कि बेहतर दक्षता के लिए गुंजाइश हो सकती है यदि, उदाहरण के लिए, आपके डेटा आइटम सॉर्ट किए जाते हैं (जो कि नमूना डेटा से अनुमान लगाया जा सकता है लेकिन आप इसे स्पष्ट रूप से नहीं बता सकते हैं)। उदाहरण के लिए, आप निकटतम वस्तु खोजने के लिए एक द्विआधारी खोज का उपयोग कर सकते हैं।

आपको यह भी ध्यान रखना चाहिए कि, जब तक आपको इसे प्रति सेकंड कई बार करने की आवश्यकता नहीं होती है, तब तक दक्षता में सुधार ज्यादातर ध्यान देने योग्य होगा जब तक कि आपके डेटा सेट बहुत अधिक न हों। बड़े जाते।

यदि आप करते हैं इसे उस तरह से कोशिश करने के लिए (और गारंटी ले सकते हैं सरणी आरोही क्रम में सॉर्ट किया जाता है) चाहते हैं, यह एक अच्छा प्रारंभिक बिंदु है:

<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>

यह मूल रूप से प्रत्येक पुनरावृत्ति, एक क्लासिक एल्गोरिथ्म के लिए समाधान स्थान को आधा करने के लिए मध्यम मूल्य के ब्रैकेटिंग और चेकिंग का उपयोग करता O(log N)है जबकि ऊपर अनुक्रमिक खोज थी 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

जैसा कि कहा गया है, कि छोटे डेटासेट के लिए या उन चीजों के लिए बहुत अंतर नहीं करना चाहिए, जिन्हें अंधाधुंध तेज़ करने की आवश्यकता नहीं है , लेकिन यह एक विकल्प है जिस पर आप विचार कर सकते हैं।


2
@micha, मैंने उत्तर के लिए eqivalent JS कोड जोड़ा है, मुझे अभी भाषाओं को बदलने में कुछ समय लगा है जिसका मैं अधिक उपयोग कर रहा था :-)
paxdiablo

2
इस एल्गोरिथ्म के लिए खराब रनटाइम यदि आपके पास बड़े डेटासेट हैं।
ylun.ca

4
@ ylun.ca, क्योंकि इस प्रश्न में कोई स्पष्ट विवरण नहीं है कि डेटा सॉर्ट किया गया है (उदाहरण सॉर्ट किया गया है लेकिन यह संयोग हो सकता है), आपको O (n) से बेहतर दक्षता नहीं मिल सकती है। किसी भी मामले में, उस आकार के डेटासेट के लिए, दक्षता ज्यादातर अप्रासंगिक है। लेकिन आपकी बात एक मान्य है, इसलिए मैं उत्तर को और अधिक पूर्ण बनाने के लिए इस आशय के नोट्स जोड़ूंगा।
पैक्सडीब्लो

1
धन्यवाद, काश मैं एक से अधिक बार उत्थान कर पाता! स्टैक ओवरफ्लो पर अधिक जवाब इस तरह का प्रयास होना चाहिए।
रिचर्ड वानबरगेन

48

ईएस 6 (2015) संस्करण:

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);

पुन: प्रयोज्यता के लिए आप एक करी फ़ंक्शन में प्लेसहोल्डर ( http://ramdajs.com/0.19.1/docs/#curry या https://lodash.com/docs#curry ) का समर्थन कर सकते हैं । यह आपकी जरूरत के आधार पर बहुत लचीलापन देता है:

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]);

24

नीचे दिए गए कार्य कोड:

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));


8
जितना ज़्यादा उतना अच्छा।
हॉट डिक्स

6
मेरा तर्क है कि यह एक बेहतर समाधान है क्योंकि यह केवल जावास्क्रिप्ट का उपयोग करता है। स्वीकृत उत्तर jQuery का उपयोग करता है, जिसका मूल प्रश्न में उल्लेख नहीं किया गया था, और जो अन्य इस प्रश्न को देख रहे हैं, वे उपयोग नहीं कर रहे होंगे।
बीन

17

अनसोल्ड एरेज़ के साथ काम करता है

जबकि यहां कुछ अच्छे समाधान पोस्ट किए गए थे, जावास्क्रिप्ट एक लचीली भाषा है जो हमें कई अलग-अलग तरीकों से एक समस्या को हल करने के लिए उपकरण प्रदान करती है। यह सब निश्चित रूप से आपकी शैली में आता है। यदि आपका कोड अधिक कार्यात्मक है, तो आपको कम भिन्नता उपयुक्त लगेगी, अर्थात:

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

हालांकि, कुछ को लगता है कि उनकी कोडिंग शैली के आधार पर, पढ़ना मुश्किल हो सकता है। इसलिए मैं समस्या को हल करने का एक नया तरीका प्रस्तावित करता हूं:

  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

न्यूनतम मूल्य का उपयोग करते हुए अन्य दृष्टिकोणों के विपरीत Math.min.apply, इस में इनपुट सरणी arrको क्रमबद्ध करने की आवश्यकता नहीं होती है । हमें अनुक्रमणिका के बारे में परवाह करने या पहले से इसे हल करने की आवश्यकता नहीं है।

मैं स्पष्टता के लिए लाइन द्वारा कोड लाइन समझाऊंगा:

  1. arr.map(function(k) { return Math.abs(k - x) })एक नया सरणी बनाता है, अनिवार्य रूप से दिए गए नंबरों (संख्या में arr) के पूर्ण मान को माइनस करता है इनपुट नंबर (x )। हम अगले सबसे छोटे नंबर की तलाश करेंगे (जो इनपुट नंबर के सबसे करीब है)
  2. Math.min.apply(Math, indexArr) यह उस सरणी में सबसे छोटी संख्या को खोजने का एक कानूनी तरीका है जिसे हमने अभी बनाया है (इससे ज्यादा कुछ नहीं)
  3. arr[indexArr.indexOf(min)]यह शायद सबसे दिलचस्प हिस्सा है। हमें हमारी सबसे छोटी संख्या मिली है, लेकिन हमें यकीन नहीं है कि हमें प्रारंभिक संख्या ( x) को जोड़ना या घटाना चाहिए । ऐसा इसलिए है क्योंकि हम Math.abs()अंतर ढूंढते थे। हालाँकि, array.mapअनुक्रमणिका को उसी स्थान पर रखते हुए, इनपुट सरणी का एक नक्शा (तार्किक रूप से) बनाता है। इसलिए, निकटतम संख्या का पता लगाने के लिए, हम दिए गए सरणी में न्यूनतम पाए गए सूचकांक को वापस करते हैं indexArr.indexOf(min)

मैंने इसे प्रदर्शित करते हुए एक बिन बनाया है ।


1
मुझे नहीं पता, लेकिन मुझे लगता है कि किसी को प्रदर्शन संदेह हो सकता है क्योंकि यह व्यावहारिक रूप से है 3nऔर यह ईएस 5 है, भले ही आप 2016 में जवाब दें और अन्य समाधान अभी भी ठीक हैं, हालांकि इस सवाल को स्पष्ट रूप से पूछने वाले इस नॉब ने उस समय एक प्रोग्रामर नहीं था।
noob

1
हाँ, यह आपको सीखने के लिए बहुत अच्छा है! वैसे मैंने केवल प्रदर्शन संदेह के बारे में बात की, यह तर्क नहीं दिया कि यह वास्तव में खराब प्रदर्शन करता है, लेकिन मैंने आपके लिए संख्याएँ O(n)चलाईं और आपका समाधान लगभग 100k ops / sec कम करता है तो @paxdiablo O(log n)यादृच्छिक संख्याओं पर। एक एल्गोरिथ्म डिजाइन करते समय हमेशा पहले वे कहते हैं। (यदि आप जानते हैं कि आप क्या कर रहे हैं और आप को वापस करने के लिए बेंचमार्क मिल गया है, को छोड़कर।)
दोपहर 23

1
सरल समाधान के लिए सहारा। मेरे उपयोग-मामले के लिए महान काम करता है (मेरे पास पूर्व-क्रमबद्ध सरणी होने की विलासिता नहीं है जैसे noob करता है।)
jaggedsoft

2
आप इसे सभी एरियों पर पुन: प्रयोज्य बनाने के लिए findClosest को कम कॉलबैक फ़ंक्शन कर सकते हैं: const findClosest = goal => (a,b) => Math.abs(a - goal) < Math.abs(b - goal) ? a : b;
Jakob E

1
उदाहरण: [2, 42, 82, 122, 162, 202, 242, 282, 322, 362].reduce(findClosest(80))
जैकब ई

11

क्रमबद्ध सरणियों के लिए (रैखिक खोज)

अब तक के सभी उत्तर पूरे ऐरे से खोजने पर ध्यान केंद्रित करते हैं। आपकी सरणी को ध्यान में रखते हुए पहले से ही हल किया गया है और आप वास्तव में केवल निकटतम संख्या चाहते हैं यह संभवतः सबसे तेज़ समाधान है:

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));

ध्यान दें कि एल्गोरिथ्म को एक बाइनरी ट्री का उपयोग करके बड़े पैमाने पर सुधार किया जा सकता है।


जबकि यहाँ यह रणनीति अच्छी है, इसके कई प्रकार हैं। उदाहरण, a[i]या i[0]
वेस्ले वर्कमैन

1
धन्यवाद, @WesleyWorkman बस उन्हें ठीक कर दिया। मुझे उम्मीद है कि मुझे सब मिल जाएगा। वैसे, आप दूसरों के उत्तरों को भी संपादित कर सकते हैं।
ह्यूबर्ट ग्रेज्सकोविआक

मुझे उच्च निकटतम मूल्य प्राप्त करने के लिए उपरोक्त उत्तर कोड में सुधार करने की आवश्यकता है? उदाहरण: [११०, १११, १२०, १४०, १४ [, १४ ९, १५५, १ 188 188, १ 111 110, १ ९ ०] यदि मैं १५० खोजता हूं, तो मुझे १५५ नहीं १४ ९ मिलना चाहिए। मैंने कोशिश की लेकिन इसे हल करने में कठिनाई आ रही है। क्या आप मदद कर सकतें है। धन्यवाद
user1199842

9

सभी समाधान अति-इंजीनियर हैं।

यह उतना ही सरल है:

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

1
वास्तव में, बिंदु से बहुत अधिक। लेकिन "सरणी से निकटतम संख्या प्राप्त करने के लिए" आपको अभी भी क्रमबद्ध सरणी से पहला तत्व चुनना है।
शाए उलमान

6

यह समाधान ES5 अस्तित्विक मात्रा का उपयोग करता है Array#some, जो अगर किसी शर्त को पूरा करता है, तो पुनरावृत्ति को रोकने की अनुमति देता है।

इसके विपरीत Array#reduce, एक परिणाम के लिए सभी तत्वों को पुनरावृत्त करने की आवश्यकता नहीं है।

कॉलबैक के अंदर, deltaखोजे गए मूल्य और वास्तविक के बीच एक पूर्णitem लिया जाता है और अंतिम डेल्टा के साथ तुलना की जाती है। यदि अधिक या बराबर है, तो पुनरावृत्ति रुक ​​जाती है, क्योंकि उनके डेल्टा के साथ अन्य सभी मूल्य वास्तविक मूल्य से अधिक हैं।

यदि deltaकॉलबैक छोटा है, तो वास्तविक आइटम को परिणाम को सौंपा गया है और इसमें deltaसहेजा गया है lastDelta

अंत में, समान डेल्टा वाले छोटे मान लिए जाते हैं, जैसे नीचे दिए गए उदाहरण में 22, जिसके परिणामस्वरूप 2

यदि अधिक से अधिक मूल्यों की प्राथमिकता है, तो डेल्टा चेक को निम्न से बदलना होगा:

if (delta >= lastDelta) {

सेवा:

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

यह (बड़े मूल्यों की प्राथमिकता) 22परिणाम के साथ मिलेगा 42

इस फ़ंक्शन को सरणी में सॉर्ट किए गए मानों की आवश्यकता है।


छोटे मूल्यों की प्राथमिकता वाला कोड:

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

अधिक मूल्यों की प्राथमिकता वाला कोड:

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


तो आप मानते हैं कि दिए गए सरणी को क्रमबद्ध किया गया है ... जो आपको बहुत समय से नरक से बचाता है।
Redu

1
इस ऑप्स सरणी को सॉर्ट किया गया है, इसलिए हां :)
नीना स्कोल्ज़

पहला समाधान इनपुट पर टूटता है जिसमें दो बार समान संख्या होती है। जैसेclosestValue([ 2, 2, 42, 80 ], 50) === 2
सेबैस्टियन वर्कामेन

@ SébastienVercammen, op का डेटा अद्वितीय और सॉर्ट किया गया है।
नीना स्कोल्ज़

@NinaScholz ओपी ने केवल यह निर्धारित किया "मेरे पास संख्याओं के साथ एक सरणी है" और "मैं चाहता हूं कि जिस संख्या को मुझे सरणी के निकटतम संख्या में परिवर्तन मिला है" । उदाहरण सरणी सिर्फ एक उदाहरण था। एक ऐरे अद्वितीय प्रविष्टियों की गारंटी नहीं देता है।
सेबास्टियन वर्केमेन 15

4

ES6

सॉर्ट किए गए और अनसर्टेड एरेज़ के साथ काम करता है

नंबर इंटेगर और फ्लोट्स, स्ट्रिंग्स का स्वागत किया

/**
 * 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

उदाहरण:

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

3

मुझे नहीं पता कि मैं एक पुराने प्रश्न का उत्तर देने वाला हूं, लेकिन जैसा कि यह पोस्ट Google खोजों पर पहली बार दिखाई देता है, मुझे उम्मीद थी कि आप मुझे अपना समाधान और मेरा 2 सी यहां जोड़कर माफ कर देंगे।

आलसी होने के नाते, मैं विश्वास नहीं कर सकता था कि इस प्रश्न का हल एक LOOP होगा, इसलिए मैंने थोड़ा और खोज किया और फ़िल्टर फ़ंक्शन के साथ वापस आ गया :

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);

बस इतना ही !


1
तो निचले बाउंड के बारे में क्या है? आप हमेशा अगले उच्च मूल्य का उपयोग करते हैं। लेकिन आपका दृष्टिकोण मुझे goog.math.clamp(Google बंद) याद दिलाता है केवल सरणियों के साथ और निचले बाउंड के बारे में परवाह किए बिना।
नोब

आपका समाधान सरणी से अगला उच्च नंबर देता है। न तो निकटतम और न ही सटीक मान पाए जाते हैं।
ह्यूबर्ट ग्रेज्सकोविआक

2

इसी तरह के सवाल का मेरा जवाब भी संबंधों के लिए लेखांकन है और यह सादे जावास्क्रिप्ट में है, हालांकि यह द्विआधारी खोज का उपयोग नहीं करता है इसलिए यह ओ (एन) है और ओ (लॉगएन) नहीं है:

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


2

मुझे फ़्यूज़न से दृष्टिकोण पसंद है, लेकिन इसमें एक छोटी सी त्रुटि है। जैसे कि यह सही है:

    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];
    }

यह थोड़ा तेज भी है क्योंकि यह बेहतर forलूप का उपयोग करता है ।

अंत में मैंने अपना कार्य इस तरह लिखा:

    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;
    };

मैंने इसके साथ परीक्षण किया console.time()और यह अन्य फ़ंक्शन की तुलना में थोड़ा तेज है।


अरे, क्या आप बता सकते हैं कि यह एक क्यों है improved for loop? उल्टे लूप्स हमेशा एक प्रदर्शन सुधार नहीं होते हैं।
A1rPun

आप .lengthकेवल एक बार मूल्यांकन करते हैं, जब आप घोषणा करते हैं i, जबकि इस लूप के लिए। लेकिन मुझे लगता है var i = arr.length;while (i--) {}भी तेजी से होगा
जॉन

मैंने अपना उत्तर अपडेट कर दिया। मैंने इसे बदल दिया while। अब यह और भी तेज है।
जॉन

0

सरणी पर थोड़ा संशोधित बाइनरी खोज काम करेगा।


3
जी, यह विचित्र है - जाहिरा तौर पर किसी को द्विआधारी खोज पसंद नहीं है। (यहां तक ​​कि सोचा कि यह सबसे अच्छा सामान्य उपाय है।)
हॉट डिक्स

0

एक छोटी सी सीमा के लिए, सरलतम बात यह है कि आपके उदाहरण का उपयोग करने के लिए मानचित्र सरणी, जहां, उदाहरण के लिए, 80 वीं प्रविष्टि में मूल्य 82 होगा। बहुत बड़ी, विरल सीमा के लिए, शायद जाने का रास्ता एक द्विआधारी खोज है।

क्वेरी भाषा के साथ आप अपने इनपुट नंबर के कुछ दूरी के मानों के लिए क्वेरी कर सकते हैं और फिर परिणामी कम सूची के माध्यम से सॉर्ट कर सकते हैं। लेकिन एसक्यूएल के पास "अगला" या "पिछले" की अच्छी अवधारणा नहीं है, जिससे आपको "स्वच्छ" समाधान मिल सके।


0

यहां एक अन्य प्रकार हमारे पास वृत्ताकार श्रेणी है जो सिर से पैर की अंगुली को जोड़ता है और दिए गए इनपुट को केवल न्यूनतम मान देता है। इससे मुझे एन्क्रिप्शन एल्गोरिथम में से एक के लिए चार कोड मान प्राप्त करने में मदद मिली।

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;
  });
}

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();
}

0

सबसे कुशल एक द्विआधारी खोज होगी। हालाँकि, सरल समाधान भी बाहर निकल सकते हैं जब अगला नंबर वर्तमान से एक और मैच हो । यहाँ लगभग सभी समाधानों पर ध्यान नहीं दिया जा रहा है कि सरणी का आदेश दिया गया है और पूरी तरह से पुनरावृत्ति कर रहा है: /

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);

इसे गैर-आदिम लोगों पर भी चलाया जा सकता है closest(data, 21, item => item.age)

सरणी में सूचकांक को वापस findकरने के findIndexलिए बदलें ।


अनियंत्रित सरणी के बारे में क्या?
एडजी

अनियंत्रित के लिए एक समाधान लें जो बाहर नहीं निकलता है, हालांकि यदि आप कई बार काम कर रहे हैं तो एक बार सरणी को सॉर्ट करने के लिए यह अधिक इष्टतम हो सकता है। जैसा कि उल्लेख किया गया है कि यदि सरणी वास्तव में बड़ी है तो एक द्विआधारी खोज एक रैखिक की तुलना में अधिक कुशल होगी।
डोमिनिक

0

सरणी में दो निकटतम संख्या ज्ञात करने के लिए

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));

-5

यहाँ जटिलता O (सरणी (n)) में सरणी से किसी संख्या के निकटतम तत्व को खोजने के लिए कोड स्निपेट है: -

इनपुट: - {१,६०,०, -१०,१००,6 },५६} तत्व: - ५६ निकटतम संख्या में ऐरे: - ६०

स्रोत कोड (जावा):

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;
    }
}

पोस्ट ने टैग्स में जावास्क्रिप्ट के लिए कहा
शान्नोन होच्किंस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.