【问题标题】:Find the smallest number that is greater than a given number in a sorted list在排序列表中找到大于给定数字的最小数字
【发布时间】:2012-11-20 02:57:15
【问题描述】:

给定一个排序的数字列表,我需要找到大于给定数字的最小数字。考虑这个列表:


arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]

假设指定的数字是 320。那么,我的方法应该返回 353,因为 353 是大于 320 的最小数字。

我正在尝试使用稍微修改的二进制搜索形式;但是在执行时程序进入无限循环。


def modBinarySearch(arr,x):
    l=len(arr)
    mid=l/2
    if arr[mid]>=x and arr[mid-1]<x:
        return arr[mid]
    elif arr[mid]>x and arr[mid-1]>x:
        modBinarySearch(arr[mid:l],x)
    else: 
        modBinarySearch(arr[0:mid],x)

N=int(raw_input())
arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]
print modBinarySearch(arr,N)

谁能指出我做错了什么?

【问题讨论】:

    标签: python algorithm binary-search


    【解决方案1】:

    如果您的列表大小为 15,请完全放弃二进制搜索并使用顺序搜索。

    您会发现代码更容易编写,除非您需要每秒执行数百万次,否则顺序解决方案将足够快。

    如果您确实需要坚持使用二进制搜索,那么您的第一步应该是实际返回递归调用的结果。

    【讨论】:

      【解决方案2】:

      有一个标准模块 bisect 已经这样做了:

      In [49]: arr[bisect.bisect(arr, 320)]
      Out[49]: 353
      

      我认为这应该是搜索排序列表的首选方法。手册中有几个examples

      至于你的实现,有很多问题:

      1. 您的递归没有正确处理小数组。
      2. 第二个分支中的切片不正确。
      3. 您的函数不返回任何内容。
      4. 因为arr是升序排列,所以arr[mid]&gt;x and arr[mid-1]&gt;x等价于arr[mid-1]&gt;x,提示你没有写你的意思

      最后但同样重要的是,对于这个问题,递归和所有切片都是完全不必要的。

      【讨论】:

      • 这在 Python 2.7 中给出了这条消息:Traceback (most recent call last): File "&lt;pyshell#1&gt;", line 1, in &lt;module&gt; arr[bisect.bisect(arr, 320)] NameError: name 'bisect' is not defined
      • @CSSS:你导入bisect模块了吗?
      • 不..我没有..会试试
      【解决方案3】:

      如果列表已排序:

      x = range(20)
      N= 15
      
      for i in x:
          if i>N:
              print i
              break
      

      给出 16。

      如果使用 numpy:

      x = np.arange(20)
      N = 15
      x[x>15][0]
      

      给出 16。

      如果您正在寻找简单的实现,对于您的具体问题,让我再谈一谈。

      【讨论】:

        【解决方案4】:
        def modBinarySearch(arr, n):
            m = len(arr) / 2
        
            if arr[m] >= n and arr[m - 1] < n:
                return arr[m]
            elif arr[m] > n and arr[m - 1] > n:
                return modBinarySearch(arr[:m], n)
            else:
                return modBinarySearch(arr[m:], n)
        
        
        arr = [1, 2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383]
        n = 320
        print(modBinarySearch(arr, n))
        

        【讨论】:

          【解决方案5】:
               python 3.2
          
               next(i for  i in arr if i>320)
          

          【讨论】:

            【解决方案6】:

            如果 arr[mid] 和 arr[mid-1] 都大于你的数字,你应该在 arr[0:mid] 中搜索,你不觉得吗?

             elif arr[mid]>x and arr[mid-1]>x:
                modBinarySearch(arr[0:mid],x)
            else: 
                modBinarySearch(arr[mid:1],x)
            

            【讨论】:

            • 仍然需要从递归调用中返回值,而不是仅仅丢弃这些信息。没有它,其余代码的作用并不重要。此外,您正在使用 1 (wun),而您应该使用 l (ell)。
            【解决方案7】:

            bisect module 是您的最佳选择:

            from bisect import bisect_left, bisect_right
            
            arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]
            
            
            def find_lt(a, x):
                'Find rightmost value less than x'
                i = bisect_left(a, x)
                if i:
                    return a[i-1]
                raise ValueError
            
            def find_gt(a, x):
                'Find leftmost value greater than x'
                i = bisect_right(a, x)
                if i != len(a):
                    return a[i]
                raise ValueError
            
            print find_lt(arr,320)          
            print find_gt(arr,320)  
            

            打印

            313
            353     
            

            【讨论】:

              【解决方案8】:
              def modBinarySearch(arr,x):
                  l=len(arr)
                  mid=l/2
                  if arr[mid] >= x and arr[mid-1] < x:
                      return arr[mid]
                  elif arr[mid]>x and arr[mid-1]>x:
                      num = modBinarySearch(arr[0:mid],x)
                  else:
                      num = modBinarySearch(arr[mid:l],x)
                  return num
              
              N=int(raw_input('Enter a number: '))
              arr=[1, 2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383]
              print modBinarySearch(arr,N)
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-03-05
                • 2016-09-08
                • 2022-11-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多