二分算法 python

二分模板

在使用二分查找时,要确保数据是有序的,并根据具体情况处理边界条件。

在具体使用时,只需将nums替换为你的数组,target替换为你要查找的目标值,然后根据具体问题对找到目标值的情况和没找到目标值的情况进行相应的操作。

注意条件的设置

def binary_search(nums, target):
    left, right = 0, len(nums) - 1
    
    while left <= right:
        mid = left + (right - left) // 2
        
        if nums[mid] == target:
            # 找到目标值的情况
            return mid  # 或者执行其他操作
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    # 没找到目标值的情况
    return -1  # 或者执行其他操作

 详解和更多案例看:

算法第三期——二分法(Python)_二分法python-CSDN博客

# 查找57
def bin_search(a, n, x):  # 在数组a中找数字x,返回位置
    left = 0  # 二分法的左端点
    right = n  # 二分法的右端点  0~n-1:左闭右开[0,n)
    while left < right:  # 右端点大于左端点则继续二分
        mid = (right + left) // 2  # 折半前的中间点。//:整除
        if a[mid] >= x:
            right = mid  # 小于中间点则中间点作为右端点
        else:  # a[mid] < x,只是大于,所以要left = mid + 1
            left = mid + 1  # 大于中间点则中间点作为左端点
    return left
 
 
n = 200
a = [0] + [i for i in range(2, 202,2)]  
test = 57
pos = bin_search(a, n, test)  # 二分搜索
print("find =", a[pos]) # find = 58

 

在单调递增序列a中查找x或x的后继:

 

# 查找57
def bin_search(a, n, x):  # 在数组a中找数字x,返回位置
    left = 0  # 二分法的左端点
    right = n  # 二分法的右端点  0~n-1:左闭右开[0,n)
    while left < right:  # 右端点大于左端点则继续二分
        mid = (right + left) // 2  # 折半前的中间点。//:整除
        if a[mid] >= x:
            right = mid  # 小于中间点则中间点作为右端点
        else:  # a[mid] < x,只是大于,所以要left = mid + 1
            left = mid + 1  # 大于中间点则中间点作为左端点
    return left
 
 
n = 200
a = [0] + [i for i in range(2, 202,2)]  
test = 57
pos = bin_search(a, n, test)  # 二分搜索
print("find =", a[pos]) # find = 58
"""
当找到x时,判断x是否是序列中的最后一个元素,如果不是,则返回x的后继;
如果x不存在于序列中,则返回小于x的最接近值作为x的前驱。
"""
def search_successor(a, x):
    left, right = 0, len(a) - 1
    successor = None

    while left <= right:
        mid = left + (right - left) // 2

        if a[mid] == x:
            if mid < len(a) - 1:
                successor = a[mid + 1]
            break
        elif a[mid] < x:
            left = mid + 1
        else:
            successor = a[mid]
            right = mid - 1

    return successor


# 测试用例
a = [1, 3, 5, 7, 9, 11, 13, 15]

result = search_successor(a, 3)
print(f"x的后继是:{result}")    # x的后继是:5

在单调递增序列a中查找x或x的前驱

def bin_search(a, n, x):  
    left = 0  
    right = n  
    while left < right:  
        mid =  (left+right+1)//2  # 不加上1会陷入死循环
        if a[mid] <= x:left = mid 
        else:          right = mid - 1 
    return left
 
 
n = 200
a = [0] + [i for i in range(2, 202,2)]  
test = 57            # # 猜57或57的后继
pos = bin_search(a, n, test)  # 二分搜索
print("find =v ", a[pos]) # find = 56
"""
使用二分查找来在单调递增序列a中查找元素x或x的前驱。
维护左右指针来缩小搜索范围,根据中间元素与x的大小关系来更新左右指针。
当找到x时,我们判断x是否是序列中的第一个元素,如果不是,则返回x的前驱;
如果x不存在于序列中,则返回大于x的最接近值作为x的后继。
"""
def search_predecessor(a, x):
    left, right = 0, len(a) - 1
    predecessor = None
    
    while left <= right:
        mid = left + (right - left) // 2
        
        if a[mid] == x:
            if mid > 0:
                predecessor = a[mid - 1]
            break
        elif a[mid] < x:
            predecessor = a[mid]
            left = mid + 1
        else:
            right = mid - 1
    
    return predecessor

# 测试用例
a = [1, 3, 5, 7, 9, 11, 13, 15]
x = 6

result = search_predecessor(a, x)
print(f"x的前驱是:{result}")    # x的前驱是:5

 

实数域的二分查找

因为实数是无限的,不能像整数那样精确地进行比较。在实数域上的二分查找通常使用近似比较的方式来判断是否找到目标值

在实数域上进行二分查找可能存在精度问题,特别是当目标值非常接近区间边界时。在使用该模板时,请根据具体情况调整精度控制epsilon的值。

"""
引入了一个很小的精度控制epsilon,用于判断二分区间的结束条件。
当区间的长度小于epsilon时,认为已经找到了一个足够接近目标值的近似解,即使不是完全相等也可以接受。
"""
def binary_search(left, right, target):
    epsilon = 1e-6  # 精度控制
    
    while left + epsilon < right:
        mid = (left + right) / 2
        
        if mid == target:
            # 找到目标值的情况
            return mid  # 或者执行其他操作
        elif mid < target:
            left = mid
        else:
            right = mid
    
    # 没找到目标值的情况
    return -1  # 或者执行其他操作

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到图像处理中的二分算法时,一种常见的应用是图像二值化。图像二值化将彩色图像转换为黑白图像,通过设置一个阈值,将亮度大于阈值的像素设为白色,小于阈值的像素设为黑色。 以下是使用二分算法实现图像二值化的一个示例: ```python import numpy as np from PIL import Image def binarize_image(image_path, threshold): # 打开图像并转换为灰度图 image = Image.open(image_path).convert("L") # 将图像转换为NumPy数组 image_array = np.array(image) # 二分算法处理图像 low = 0 high = 255 while high - low > 1: mid = (high + low) // 2 foreground_pixels = image_array > mid background_pixels = image_array <= mid foreground_mean = np.mean(image_array[foreground_pixels]) background_mean = np.mean(image_array[background_pixels]) if foreground_mean > background_mean: low = mid else: high = mid # 根据阈值对图像进行二值化处理 binary_image = image_array > (low + high) / 2 # 创建新的图像对象并保存 binary_image = Image.fromarray(binary_image.astype(np.uint8) * 255) binary_image.save("binary_image.png") # 调用函数进行图像二值化 binarize_image("input_image.png", 128) ``` 在上述代码中,`binarize_image` 函数接受两个参数:`image_path` 是输入图像的路径,`threshold` 是二值化的阈值。函数首先打开图像并将其转换为灰度图像。然后,它使用二分算法来查找最佳阈值,将图像分割为前景和背景。最后,根据阈值对图像进行二值化处理,并保存结果图像为 `binary_image.png`。 请注意,这只是二分算法在图像处理中的一种应用场景。在其他图像处理任务中,可能需要使用不同的方法和技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值