Нахождение самого близкого соответствия в наборе [закрытых] чисел

Я бы рекомендовал использовать PDO (объекты данных PHP) для запуска параметризованных SQL-запросов.

Это не только защищает от SQL-инъекции, но и ускоряет выполнение запросов.

И используя функции PDO, а не mysql_, mysqli_ и pgsql_, вы делаете свое приложение немного более абстрактным из базы данных, в редких случаях, когда вам нужно переключать поставщиков баз данных .

25
задан 6 revs, 5 users 65% 16 November 2014 в 21:54
поделиться

28 ответов

11 байтов в J:

C=:0{]/:|@-

Примеры:

>> a =: 1 3 8 10 13
>> 4 C a
3
>> 11 C a
10
>> 12 C a
13

моя разбивка для неспециалиста:

0{         First element of
]          the right argument
/:         sorted by
|          absolute value 
@          of
-          subtraction
22
ответ дан 2 revs 28 November 2019 в 17:43
поделиться

Perl - 66 символов:

perl -e 'for(qw/1 3 8 10 13/){$d=($_-4)**2; $c=$_ if not $x or $d<$x;$x=$d;}print $c;'
1
ответ дан gpojd 28 November 2019 в 17:43
поделиться

41 символ в F#:

let C x = Seq.min_by (fun n -> abs(n-x))

как в

#light

let l = [1;3;8;10;13]

let C x = Seq.min_by (fun n -> abs(n-x))

printfn "%d" (C 4 l)   // 3 
printfn "%d" (C 11 l)  // 10
printfn "%d" (C 12 l)  // 13
0
ответ дан Brian 28 November 2019 в 17:43
поделиться

язык Common LISP использование выполняют итерации библиотеки.

(defun closest-match (list n)
     (iter (for i in list)
            (finding i minimizing (abs (- i n)))
0
ответ дан user49117 28 November 2019 в 17:43
поделиться

Некоторые из Вас, кажется, не читают, что список unordered (хотя с примером, как это, я могу понять Ваш беспорядок). В Java:

public int closest(int needle, int haystack[]) { // yes i've been doing PHP lately
  assert haystack != null;
  assert haystack.length; > 0;
  int ret = haystack[0];
  int diff = Math.abs(ret - needle);
  for (int i=1; i<haystack.length; i++) {
    if (ret != haystack[i]) {
      int newdiff = Math.abs(haystack[i] - needle);
      if (newdiff < diff) {
        ret = haystack[i];
        diff = newdiff;
      }
    }
  }
  return ret;
}

Не точно краткий, но эй его Java.

0
ответ дан 2 revs 28 November 2019 в 17:43
поделиться
int numberToMatch = 4;

var closestMatches = new List<int>();
closestMatches.Add(arr[0]); // closest tentatively

int closestDifference = Math.Abs(numberToMatch - arr[0]);


for(int i = 1; i < arr.Length; i++)
{
    int difference = Math.Abs(numberToMatch - arr[i]);
    if (difference < closestDifference)
    {
        closestMatches.Clear();
        closestMatches.Add(arr[i]);
        closestDifference = difference;
    }
    else if (difference == closestDifference)
    {       
        closestMatches.Add(arr[i]);
    }
}


Console.WriteLine("Closest Matches");
foreach(int x in closestMatches) Console.WriteLine("{0}", x);
0
ответ дан 2 revs 28 November 2019 в 17:43
поделиться

ОТРЕДАКТИРОВАННЫЙ = в для цикла

int Closest(int val, int[] arr)
{
    int index = 0;
    for (int i = 0; i < arr.Length; i++)
        if (Math.Abs(arr[i] - val) < Math.Abs(arr[index] - val))
            index = i;
    return arr[index];
}
1
ответ дан Brad Gilbert 28 November 2019 в 17:43
поделиться

возвраты только одно число:

var arr = new int[] { 1, 3, 8, 10, 13 };
int numToMatch = 4;
Console.WriteLine("{0}", 
     arr.Select(n => new{n, diff = Math.Abs(numToMatch - n) }).OrderBy(x => x.diff).ElementAt(0).n);
1
ответ дан 2 revs 28 November 2019 в 17:43
поделиться

Ruby

def c(r,t)
r.sort{|a,b|(a-t).abs<=>(b-t).abs}[0]
end

Не наиболее эффективный метод, но довольно короткий.

1
ответ дан Joshua Swink 28 November 2019 в 17:43
поделиться

Запись Haskell (протестировала):

import Data.List

near4 = head . sortBy (\n1 n2 -> abs (n1-4) `compare` abs (n2-4))

Виды список путем помещения чисел ближе в 4 близости передняя сторона. head берет первый элемент (самый близкий к 4).

1
ответ дан Norman Ramsey 28 November 2019 в 17:43
поделиться

Scala (62 символа), на основе идеи J и решений Ruby:

def c(l:List[Int],n:Int)=l.sort((a,b)=>(a-n).abs<(b-n).abs)(0)

Использование:

println(c(List(1,3,8,10,13),4))
2
ответ дан 2 revs 28 November 2019 в 17:43
поделиться

Язык: C, Символьное количество: 79

c(int v,int*a,int A){int n=*a;for(;--A;++a)n=abs(v-*a)<abs(v-n)?*a:n;return n;}

Подпись:

int closest(int value, int *array, int array_size);

Использование:

main()
{
    int a[5] = {1, 3, 8, 10, 13};
    printf("%d\n", c(4, a, 5));
}
2
ответ дан strager 28 November 2019 в 17:43
поделиться

возвраты только одно число:

var arr = new int[] { 1, 3, 8, 10, 13 };
int numToMatch = 4;

Console.WriteLine("{0}", 
   arr.OrderBy(n => Math.Abs(numToMatch - n)).ElementAt(0));
1
ответ дан Michael Buen 28 November 2019 в 17:43
поделиться

PostgreSQL:

select n from tbl order by abs(4 - n) limit 1

В случае, где две записи совместно используют то же значение для "брюшного пресса (4 - идентификатор)", вывод был бы в детерминанте и возможно не константа. Для фиксации этого, я предлагаю что-то как непротестированное предположение:

select n from tbl order by abs(4 - n) + 0.5 * 4 > n limit 1;

Это решение обеспечивает, производительность на порядке O (N регистрируют N), где O (зарегистрируйтесь, N) возможно, например: https://stackoverflow.com/a/8900318/1153319

4
ответ дан 4 revs, 2 users 58% 28 November 2019 в 17:43
поделиться

Поскольку я на самом деле должен был сделать это, вот мой PHP

$match = 33;

$set = array(1,2,3,5,8,13,21,34,55,89,144,233,377,610);

foreach ($set as $fib)
    {
        $diff[$fib] = (int) abs($match - $fib);
    }
$fibs = array_flip($diff);
$closest = $fibs[min($diff)];

echo $closest;
4
ответ дан garrow 28 November 2019 в 17:43
поделиться

Предположение, что значения запускаются в таблице по имени T со столбцом по имени N, и мы ищем значение 4 тогда в SQL Oracle, требуется 59 символов:

select*from(select*from t order by abs(n-4))where rownum=1

я использовал выбор * для сокращения пробельных требований.

4
ответ дан WW. 28 November 2019 в 17:43
поделиться

Некоторые C# Linq... слишком много способов сделать это!

decimal[] nums = { 1, 3, 8, 12 };
decimal target = 4;

var close1 = (from n in nums orderby Math.Abs(n-target) select n).First();
var close2 = nums.OrderBy(n => Math.Abs(n - target)).First();

Console.WriteLine("{0} and {1}", close1, close2);

Еще больше путей, если Вы используете список вместо этого, так как плоскость ol массивы не имеет никакого.Sort ()

5
ответ дан Andrew Backer 28 November 2019 в 17:43
поделиться

Groovy 28B

f={a,n->a.min{(it-n).abs()}}
5
ответ дан matyr 28 November 2019 в 17:43
поделиться

Моя попытка в Python:

def closest(target, collection) :
    return min((abs(target - i), i) for i in collection)[1]
9
ответ дан sykora 28 November 2019 в 17:43
поделиться

Более короткий Python: 41 символ

f=lambda a,l:min(l,key=lambda x:abs(x-a))
19
ответ дан Triptych 28 November 2019 в 17:43
поделиться

Рубин . Один проход. Прекрасно обрабатывает отрицательные числа. Возможно, не очень коротко, но, безусловно, красиво.

class Array
  def closest int
    diff = int-self[0]; best = self[0]
    each {|i|
      if (int-i).abs < diff.abs
        best = i; diff = int-i
      end
    }
    best
  end
end

puts [1,3,8,10,13].closest 4
0
ответ дан 28 November 2019 в 17:43
поделиться

Ruby, как Python, имеет метод min для Enumerable, поэтому вам не нужно выполнять сортировку.

def c(value, t_array)
  t_array.min{|a,b|  (value-a).abs <=> (value-b).abs }
end

ar = [1, 3, 8, 10, 13]
t = 4
c(t, ar) = 3
3
ответ дан 28 November 2019 в 17:43
поделиться

Вот еще один ответ Хаскелла:

import Control.Arrow
near4 = snd . minimum . map (abs . subtract 4 &&& id)
1
ответ дан 28 November 2019 в 17:43
поделиться

Haskell, 60 символов -

f a=head.Data.List.sortBy(compare`Data.Function.on`abs.(a-))
1
ответ дан 28 November 2019 в 17:43
поделиться

KDB + , 23b:

C:{x first iasc abs x-}

Использование:

q)a:10?20
q)a
12 8 10 1 9 11 5 6 1 5

q)C[a]4
5
1
ответ дан 28 November 2019 в 17:43
поделиться

В Java используйте карту с возможностью навигации

NavigableMap <Integer, Integer>navMap = new ConcurrentSkipListMap<Integer, Integer>();  

navMap.put(15000, 3);  
navMap.put(8000, 1);  
navMap.put(12000, 2);  

System.out.println("Entry <= 12500:"+navMap.floorEntry(12500).getKey());  
System.out.println("Entry <= 12000:"+navMap.floorEntry(12000).getKey());  
System.out.println("Entry > 12000:"+navMap.higherEntry(12000).getKey()); 
1
ответ дан 28 November 2019 в 17:43
поделиться

Excel VBA - найти индекс диапазона Excel или значение, наиболее близкое к целевому

Учитывая существующий диапазон Excel, rangeOfValues:

  1. найти индекс наиболее близкого к целевому значению Диапазона с помощью Application.Match (обратите внимание, что метод Match возвращает Double)

    Dim iMatch как Double 
    iMatch = Application.Match (valueToMatch, rangeOfValues)
    
  2. найти ближайшее к целевому значению значение Диапазона с помощью VLOOKUP/HLOOKUP

     Ближайшее к нему значение как Вариант
    closest = VLOOKUP(valueToMatch, диапазонОфВалансы)
    

Если необходимо точное совпадение:

Dim exactM as Variant
exactM = VLOOKUP(valueToMatch, rangeOfValues, False)
0
ответ дан 28 November 2019 в 17:43
поделиться

другой ответ PHP:

function closestMatch($int, $in) {
    $diffs = array();
    foreach ($in as $i)
        $diffs[abs($int - $i)] = $i;
    ksort($diffs);
    foreach ($diffs as $i) return $i;
}
0
ответ дан 28 November 2019 в 17:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: