25

それで、私は今日、コレクション内でクローズマッチを見つけるための最良の方法は何であるかを尋ねられました。

たとえば、次のような配列があります。

1, 3, 8, 10, 13, ...

4に最も近い数はいくつですか?

コレクションは数値であり、順序付けられておらず、何でもかまいません。一致する番号と同じです。

選択したさまざまな言語から、私たちが何を思いつくことができるかを見てみましょう。

4

33 に答える 33

22

J: 11 バイト

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
于 2009-01-16T01:02:22.237 に答える
9

Pythonでの私の試み:

def closest(target, collection) :
    return min((abs(target - i), i) for i in collection)[1]
于 2009-01-15T06:03:07.903 に答える
5

Groovy 28B

f={a,n->a.min{(it-n).abs()}}
于 2009-01-15T06:44:25.573 に答える
5

いくつかの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()がないため、さらに多くの方法があります。

于 2009-01-15T06:46:38.250 に答える
4

値がNという列を持つTというテーブルで始まり、値4を探しているとすると、OracleSQLでは59文字かかります。

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

空白の要件を減らすためにselect*を使用しました。

于 2009-01-15T05:53:27.453 に答える
4

PostgreSQL:

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

2つのレコードが「abs(4-id)」の同じ値を共有する場合、出力は不確定であり、おそらく定数ではありません。それを修正するために、私はテストされていない推測のようなものを提案します:

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

このソリューションは、O(N log N)のオーダーのパフォーマンスを提供します。ここで、O(log N)は次のように可能です:https ://stackoverflow.com/a/8900318/1153319

于 2009-01-15T06:30:15.413 に答える
4

実際にこれを行う必要があったため、これが私の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;
于 2009-02-10T07:12:26.173 に答える
3

Python のような Ruby には Enumerable の min メソッドがあるため、並べ替えを行う必要はありません。

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
于 2009-07-08T05:13:45.057 に答える
2

言語: 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));
}
于 2009-01-16T00:07:21.940 に答える
2

J および Ruby ソリューションのアイデアに基づく Scala (62 文字):

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))
于 2009-01-16T10:46:23.273 に答える
2

上記のコードは、浮動小数点数に対しては機能しません。
だから、これがそのための私の改訂されたphpコードです。

function find_closest($match, $set=array()) {
    foreach ($set as $fib) {  
        $diff[$fib] = abs($match - $fib);  
    }  
    return array_search(min($diff), $diff);  
}

$set = array('2.3', '3.4', '3.56', '4.05', '5.5', '5.67');  
echo find_closest(3.85, $set); //return 4.05  
于 2011-01-22T07:17:30.043 に答える
2

Python by me とhttps://stackoverflow.com/users/29253/igorgueは、他のいくつかの回答に基づいています。34 文字のみ:

min([(abs(t-x), x) for x in a])[1]
于 2012-06-07T01:31:13.850 に答える
2

PostgreSQL:

これは、FreeNode の RhodiumToad によって指摘されており、O(log N) のオーダーのパフォーマンスがあり、ここでの他の PostgreSQL の回答よりもはるかに優れています。

select * from ((select * from tbl where id <= 4
order by id desc limit 1) union
(select * from tbl where id >= 4
order by id limit 1)) s order by abs(4 - id) limit 1;

ID が存在する場合の処理​​をより適切に行うには、両方の条件を「または等しい」にする必要があります。これには、2 つのレコードが「abs(4 - id)」の同じ値を共有し、他の PostgreSQL がここで回答する場合の処理​​もあります。

于 2012-01-17T19:14:04.120 に答える
1

編集済み=forループ内

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];
}
于 2009-01-15T05:51:34.040 に答える
1

Haskellエントリ(テスト済み):

import Data.List

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

前面近くの4に近い数字を配置して、リストを並べ替えます。 head最初の要素(4に最も近い)を取ります。

于 2009-01-15T06:09:46.530 に答える
1

Ruby

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

Not the most efficient method, but pretty short.

于 2009-01-15T06:20:33.170 に答える
1

1つの数値のみを返します:

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);
于 2009-01-15T06:25:17.967 に答える
1

1つの数値のみを返します:

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

Console.WriteLine("{0}", 
   arr.OrderBy(n => Math.Abs(numToMatch - n)).ElementAt(0));
于 2009-01-15T06:38:30.857 に答える
1

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;'
于 2009-01-16T00:35:19.857 に答える
1

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
于 2010-01-19T00:48:12.887 に答える
1

Haskellの別の回答は次のとおりです。

import Control.Arrow
near4 = snd . minimum . map (abs . subtract 4 &&& id)
于 2010-01-17T14:49:30.750 に答える
1

Haskell、60 文字 -

f a=head.Data.List.sortBy(compare`Data.Function.on`abs.(a-))
于 2010-01-17T20:24:24.360 に答える
1

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()); 
于 2010-05-26T10:01:55.490 に答える
1

Python、コードをフォーマットする方法がわからず、コードがそのまま実行されるかどうかもわかりませんが、ロジックは機能するはずであり、とにかくそれを行うビルトインがあるかもしれません...

list = [1,4,10,20]
num = 7
for lower in list:
         if lower <= num:
           lowest = lower #closest lowest number

for higher in list:
     if higher >= num:
           highest = higher #closest highest number

if highest - num > num - lowest: # compares the differences
    closer_num = highest
else:
    closer_num = lowest
于 2011-05-19T22:11:20.760 に答える
0
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);
于 2009-01-15T06:06:16.303 に答える
0

リストがそうであることを読んでいないように見える人もいます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です。

于 2009-01-15T06:07:23.853 に答える
0

Python + numpy

import numpy as np
f = lambda lst, target: lst[np.argmin(np.abs(np.array(lst) - target))]

例:

>>> f([1,2,5,3,10],9)
10
于 2012-06-06T08:37:31.337 に答える
0

Excel VBA - ターゲット値に最も近い Excel 範囲のインデックスまたは値を見つける

既存の Excel 範囲を指定すると、rangeOfValues:

  1. Application.Match を使用して、Range 内で最も一致する値のインデックスを検索します (Match メソッドは Double を返すことに注意してください)。

    Dim iMatch as Double 
    iMatch = Application.Match(valueToMatch, rangeOfValues)
    
  2. VLOOKUP/HLOOKUP を使用して、ターゲット値に最も近い範囲値を見つける

    Dim closest as Variant
    closest = VLOOKUP(valueToMatch, rangeOfValues)
    

完全一致が必要な場合:

Dim exactM as Variant
exactM = VLOOKUP(valueToMatch, rangeOfValues, False)
于 2010-01-28T19:43:44.417 に答える
0

反復ライブラリを使用するCommon Lisp 。

(defun closest-match (list n)
     (iter (for i in list)
            (finding i minimizing (abs (- i n)))
于 2009-01-15T23:52:48.443 に答える
0

ルビー。1 つのパス スルー。負の数を適切に処理します。それほど短くはないかもしれませんが、確かにきれいです。

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
于 2009-07-08T05:42:52.347 に答える
0

別のPHPの答え:

function closestMatch($int, $in) {
    $diffs = array();
    foreach ($in as $i)
        $diffs[abs($int - $i)] = $i;
    ksort($diffs);
    foreach ($diffs as $i) return $i;
}
于 2010-06-07T18:53:34.590 に答える
0

F#41 文字:

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
于 2009-02-20T08:51:01.840 に答える