zoukankan      html  css  js  c++  java
  • DAY 006--查找某个值是否在列表中(二分法)

    005 题目如下:                                        

    1、给定一个num_list= [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

    2、根据用户输入的值,判断是否在num_list中

    流程分析:                                                                    

    1、编写一个查找函数,运用二分法+递归思想:

    • 1.1、先定义好列表的位置:
      • lower=0:序列的起始值)
      • high=len(lst)-1:序列最后一个元素的索引值
      • middle=(lower+high)//2
    • 1.2、从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
    • 1.3、如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找(运用函数递归的思想),而且跟开始一样从中间元素开始比较。
    • 1.4、如果在某一步骤数组为空,则代表找不到。

    2、如何运用函数递归的思想?

    • 2.1、如果value>lst[middle],说明函数应该去列表的后1/2去找:return func(list[middle+1:],value)
    • 2.2、如果value<lst[middle],说明函数应该去列表的前1/2去找:return func(list[:middle-1],value)

    3、如果找到了值,返回True,如果没有找到,返回False

    代码分析:                                                                     

    def binary_search_loop(lst,value):
        low, high = 0, len(lst)-1
        while low <= high:
            mid = (low + high) // 2
            if lst[mid] < value:
                lst=lst[mid+1:]
                return binary_search_loop(lst,value)
            elif lst[mid] > value:
                lst = lst[:mid]
                return binary_search_loop(lst, value)
            else:
                return True
        return False
    
    
    number_list = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
    
    def main():
        while True:
            num=input(">>:").strip()
            try:
                num=int(num)
            except:
                raise TypeError("请输入数字")
            if binary_search_loop(number_list,num):
                print("%d存在列表中"%num)
            else:
                print("该值不存在")
    if __name__=="__main__":
        main()

    方法二流程分析:                                                           

    1、编写一个查找函数,运用二分法+循环思想:

    • 1.1、先定义好列表的位置:
      • lower=0:序列的起始值)
      • high=len(lst)-1:序列最后一个元素的索引值
      • middle=(lower+high)//2
    • 1.2、从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
    • 1.3、如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找(运用循环的思想),而且跟开始一样从中间元素开始比较。
    • 1.4、如果在某一步骤数组为空,则代表找不到。

    2、如何运用循环的思想?

    • 2.1、如果value>lst[middle],说明函数应该去列表的后1/2去找:lower=middle+1
    • 2.2、如果value<lst[middle],说明函数应该去列表的前1/2去找:high=middle-1

    2、如果找到了值,返回True,如果没有找到,返回False

    方法二代码:                                                                 

    def binary_search_loop(lst,value):
        low, high = 0, len(lst)-1
        while low <= high:
            mid = (low + high) // 2
            if lst[mid] < value:
                low = mid + 1
            elif lst[mid] > value:
                high = mid-1
            else:
                return True
        return False
    
    
    number_list = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
    
    def main():
        while True:
            num=input(">>:").strip()
            try:
                num=int(num)
            except:
                raise TypeError("请输入数字")
            if binary_search_loop(number_list,num):
                print("%d存在列表中"%num)
            else:
                print("该值不存在")
    if __name__=="__main__":
        main()

     

    题目反思:                                                                    

    1、本题还可以用for循环查找的,但是使用for循环容易造成查找速度慢,如果数据量过大,for循环肯定不能使用

    2、在使用二分法+递归中,要考虑到

    • lower==high,也就是列表在二分法后只剩一个元素的情况,
    • 然后去判断这个元素是不是等于输入的值,如果不是则返回False

    3、我做题过程中的BUG主要有两个:

    • 第一个是第 2 点
    • 第二个是没有考虑到 num_list[middle]=num 的情况

    4、在搜寻资料中,还看见了二分法循环实现,然后自己照着二分法+循环的方法实现了本题,根据程序的运行,发现二分法循环更加节约查询的时间。

    5、关于二分法循环和二分法递归的方法更多详细比较,在算法思想的第一篇,欢迎观阅!

    新学知识点:                                                                 

    1、二分法概念

    2、二分法实现方法:递归、循环

    3、又一次使用了递归,加深了一点对递归的理解

    4、二分法+循环是很好的解题思想,记住这道题!

    Mark on 2018.04.09

  • 相关阅读:
    Openstack API 开发 快速入门
    virtualBox虚拟机到vmware虚拟机转换
    使用Blogilo 发布博客到cnblogs
    Openstack Troubleshooting
    hdoj 1051 Wooden Sticks(上升子序列个数问题)
    sdut 2430 pillars (dp)
    hdoj 1058 Humble Numbers(dp)
    uva 10815 Andy's First Dictionary(快排、字符串)
    sdut 2317 Homogeneous squares
    hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
  • 原文地址:https://www.cnblogs.com/JunSheep/p/8743074.html
Copyright © 2011-2022 走看看