查找最接近的大数


30

任务

给定任何整数数组,例如:

[-1,476,578,27,0,1,-1,1,2]

和该数组的索引(此示例使用基于0的索引,尽管您也可以使用基于1的索引。):

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]

然后返回大于该索引处元素的最接近数字。在该示例中,大于1的最接近数字是27(相距2个索引)。

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]
            ^
Nearest greater number

Output = 27

假设条件

  • 最近的不包括包装。
  • 永远不会给程序一个长度为1的数组(例如[55])。
  • 您将假定有一个大于给定元素的数字。
  • 如果等距离处的元素大2个数字,则可以返回任意一个

I / O对

Input:
Index = 45
Array = [69, 43, 89, 93, 62, 25, 4, 11, 115, 87, 174, 60, 84, 58, 28, 67, 71, 157, 47, 8, 33, 192, 187, 87, 175, 32, 135, 25, 137, 92, 183, 151, 147, 7, 133, 7, 41, 12, 96, 147, 9, 134, 197, 3, 107, 164, 90, 199, 21, 71, 77, 62, 190, 122, 33, 127, 185, 58, 92, 106, 26, 24, 56, 79, 71, 24, 24, 114, 17, 84, 121, 188, 6, 177, 114, 159, 159, 102, 50, 136, 47, 32, 1, 199, 74, 141, 125, 23, 118, 9, 12, 100, 94, 166, 12, 9, 179, 147, 149, 178, 90, 71, 141, 49, 74, 100, 199, 160, 120, 14, 195, 112, 176, 164, 68, 88, 108, 72, 124, 173, 155, 146, 193, 30, 2, 186, 102, 45, 147, 99, 178, 84, 83, 93, 153, 11, 171, 186, 157, 32, 90, 57, 181, 5, 157, 106, 20, 5, 194, 130, 100, 97, 3, 87, 116, 57, 125, 157, 190, 83, 148, 90, 44, 156, 167, 131, 100, 58, 139, 183, 53, 91, 151, 65, 121, 61, 40, 80, 40, 68, 73, 20, 135, 197, 124, 190, 108, 66, 21, 27, 147, 118, 192, 29, 193, 27, 155, 93, 33, 129]
Output = 199

Input:
Index = 2
Array = [4,-2,1,-3,5]
Output = 4 OR 5

Input:
Index = 0
Array = [2124, -173, -155, 146, 193, -30, 2, 186, 102, 4545]
Output = 4545

Input:
Index = 0
Array = [1,0,2,3]
Output = 2

Input:
Index = 2
Array = [3,-1,-3,-2,5]
Output = -1 OR -2

您能否添加一个测试用例,使其在左侧而不是右侧查找结果?即1; [7,1,-4,2]
凯文·克鲁伊森

我认为这2; [3,-1,-3,-2,5]是一个不错的测试案例。有正数,但结果为负。
Stewie Griffin's

我可以使用2索引吗?
泰特斯

@Titus我的意思是,如果你真的想
引力

Answers:


7

MATL,10字节

yt&y)>fYk)

这使用基于1的索引。在线尝试!

说明

考虑输入[4,-2,1,-3,5]3作为一个例子。

y     % Take two inputs implicitly. Duplicate 2nd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5]
t     % Duplicate top of the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5]
&y    % Duplicate 3rd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5], 3
)     % Index: select elements from first input as indicated by second input
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], 1
>     % Greater than, element-wise
      % STACK: [4,-2,1,-3,5], 3, [1,0,0,0,1]
f     % Find: gives indices of non-zero entries
      % STACK: [4,-2,1,-3,5], 3, [1,5]
Yk    % Closest element: gives closest element of each entry in second input
      % ([1,5]) to each entry in the first input (3). In case of a tie it 
      % gives the left-most one
      % STACK: [4,-2,1,-3,5], 1
)     % Index: select elements from first input as indicated by second input
      % STACK: 4
      % Implicitly display

2
你有解释吗?
尼克·克利福德

@NickClifford当然!我正在等待OP的澄清。已添加说明
路易斯·门多



4

JavaScript(ES6),57 55字节

以currying语法获取数组a和索引。i(a)(i)

a=>g=(i,p)=>(x=a[i-p])>a[i]||(x=a[i+p])>a[i]?x:g(i,-~p)

测试用例


可以|代替使用||吗?
尼尔

@Neil不,我们不希望x在满足第一个条件时被覆盖。
Arnauld


3

Haskell,48个字节

i%l=minimum[[j*j,x]|(j,x)<-zip[-i..]l,x>l!!i]!!1

在线尝试!ØrjanJohansen的测试框架。


您可以使用列表!!1来代替保存字节(只需在标头中更改IntegerInt)。
与Orjan约翰森

@ØrjanJohansen谢谢,我已经尝试过了,但是不确定为什么它抱怨类型。
xnor

2

x86-64汇编,40字节

通过分析Johan du Toit2501的C解决方案的启发,以下是可以与MASM结合使用的x86-64平台功能。

它遵循Microsoft x64调用约定来传递参数,因此传入数组的总长度,传入ECX感兴趣的位置,并传入EDX指向整数数组的指针R8(这是一个64位平台,因此64位指针)。

它在中返回结果(“最近的最大数字”)EAX

             FindNearestGreater PROC      
8B F2       \    mov     esi, edx     ; move pos parameter to preferred register
8B D9       |    mov     ebx, ecx     ; make copy of count (ecx == i; ebx == count)
            | MainLoop:
8B C6       |    mov     eax, esi     ; temp  = pos
2B C1       |    sub     eax, ecx     ; temp -= i
99          |    cdq
33 C2       |    xor     eax, edx
2B C2       |    sub     eax, edx     ; temp = AbsValue(temp)
            | 
41 8B 14 B0 |    mov     edx, DWORD PTR [r8+rsi*4]
41 39 14 88 |    cmp     DWORD PTR [r8+rcx*4], edx
7E 04       |    jle     KeepGoing    ; jump if (pValues[i] <= pValues[pos])
3B D8       |    cmp     ebx, eax
77 02       |    ja      Next         ; jump if (count > temp)
            | KeepGoing:
8B C3       |     mov     eax, ebx    ; temp = count
            | Next:
8B D8       |     mov     ebx, eax    ; count = temp
E2 E3       |     loop    MainLoop    ; equivalent to dec ecx + jnz, but smaller (and slower)
            | 
            |     ; Return pValues[temp + pos]
03 C6       |     add     eax, esi
41 8B 04 80 |     mov     eax, DWORD PTR [r8+rax*4]
C3          /     ret
             FindNearestGreater ENDP

如果要从C代码中调用它,则原型为:

extern int FindNearestGreater(unsigned int count,
                              unsigned int pos,
                              const    int *pValues);



1

Haskell,53个字节

(#)接受一个Int和的Ints或Integers 列表(实际上是任何Ord类型),并返回列表的元素。

n#l=[x|i<-[1..],x:_<-(`drop`l)<$>[n-i,n+i],x>l!!n]!!0

怎么运行的

  • n是给定的索引,l是给定的列表/“数组”。
  • i从1到更高的值是距n当前测试的距离。
  • 对于每个i,我们检查索引n-in+i
  • xl要测试的元素。如果通过测试,它将成为结果列表理解的一个元素。
    • 用索引任意索引!!可能会出界错误,而drop在这种情况下,则返回整个列表或空列表。模式与匹配,x:_检查结果是否为空。
    • x>l!!n测试我们的元素大于索引处的元素n(保证存在)。
    • !!0 最后返回列表理解的第一个匹配项/元素。

在线尝试!



1

Brachylog,17个字节

hH&∋₎<.&t:I≜+:H∋₍

在线尝试!

说明

hH                      Call the list H
  &∋₎<.                 Output is greater than the number at the specified index
       &t:I≜            Label I (0, then 1, then -1, then 2, then -2, …)
            +           Sum I with the input Index
             :H∋₍       Output is the element of H at index <the sum>

1

Java(OpenJDK 8),98字节

int f(int n,int[]a){for(int s=1,i=1,x=a[n];;n+=i++*s,s=-s)if(0<=n&n<a.length&&a[n]>x)return a[n];}

在线尝试!

按照以下总和的部分总和指定的顺序检查索引:

initial value + 1 - 2 + 3 - 4 + 5 - 6 + ...

我只是在阅读问题,想开始写一个答案。顺便说一句,为什么s=1,and ,s=-s,它在您的答案中没有用。
凯文·克鲁伊森

1
@KevinCruijssen,这是一个错误,我正在修复。它通过了测试用例,因为在所有这些测试用例中,最右边的数字更大。
Leaky Nun

1

C,69字节

t;b;f(*d,c,p){for(b=c;c--;)d[c]>d[p]&(t=abs(p-c))<b?b=t:0;*d=d[p+b];}

第一个参数是输入/输出参数。输出存储在其第一个元素中。

看到它在网上工作


1

R,59个字节

function(l,i)l[j<-l>l[i]][which.min(abs(1:length(l)-i)[j])]

返回一个匿名函数。如果两个元素之间的距离相等,则将返回第一个(较小的索引)。

在线尝试!






0

Java,96字节

int f(int n,int[]a){for(int s=1,i=1,x=a[n];0>(n+=i++*s)|n>=a.length||a[n]<=x;s=-s);return a[n];}

标识符的名称类似于@Leaky Nun的答案。此外,大多数部分的对齐方式基本相同:相比之下,-条件if已替换了-条件for(牺牲了其他分号)。通过将递增部分移动到条件中来除去冒号(因此,以前的if语句的括号实际上是“移动”了)-将&更改为| 对字符数没有影响。


0

Clojure,95个字节

#(%(nth(nth(sort-by first(for[i(range(count %)):when(>(% i)(% %2))][(Math/abs(- i %2))i]))0)1))

这是我能想到的最短的时间:(我也尝试过使用它,但是无法将其带到终点:

#(map(fn[f c](f c))[reverse rest](split-at %2 %))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.