【问题标题】:Binary Search Algorithm - Project Ideas [closed]二进制搜索算法 - 项目想法 [关闭]
【发布时间】:2021-05-07 02:42:22
【问题描述】:

我正在编写一个关于二进制搜索的 python 项目,但我希望能够为这个算法实现一个图形界面。 你有什么想法我可以使用这个算法来实现接口吗? 我的意思是项目想法,而不是实施本身..

谢谢

这是我的代码:

# It returns index of x in given array arr if present,
# else returns -1
def binary_search(arr, x):
    low = 0
    high = len(arr) - 1
    mid = 0
 
    while low <= high:
 
        mid = (high + low) // 2
 
        # If x is greater, ignore left half
        if arr[mid] < x:
            low = mid + 1
 
        # If x is smaller, ignore right half
        elif arr[mid] > x:
            high = mid - 1
 
        # means x is present at mid
        else:
            return mid
 
    # If we reach here, then the element was not present
    return -1
 
 
# Test array
arr = [ 2, 3, 4, 10, 40 ]
x = 10
 
# Function call
result = binary_search(arr, x)
 
if result != -1:
    print("Element is present at index", str(result))
else:
    print("Element is not present in array")```

【问题讨论】:

  • 可以动态(及时)绘制搜索树,类似于可视化here in Wikipedia
  • 你是在画 ASCII 艺术还是要实现一个真正的 UI 框架?
  • 重点是这是一个大学项目,我的教授要求为此提供图形界面.. 所以,是的,我将使用按钮和其他东西实现一个真正的 UI 框架。
  • 为了好玩,我在my answer的控制台中实现了ASCII-art图形,请看看,也许它会给你一些有用的想法。

标签: python python-3.x binary-search


【解决方案1】:

尽管您要求图形界面,但仍然只是为了好玩,我决定为您的二进制搜索任务实现以下简单的 ASCII 艺术可视化,给您一些想法可能对您有用。

在将图形绘制到控制台时,我使用了一些 ANSI escape codes。 Windows 上的这个转义码需要安装一次colorama 模块python -m pip install colorama。在 Linux 上它不需要安装任何东西。

代码可以调整为不同的随机种子值或数字数量或数字大小(最多 100、最多 1000 等)。值是随机选择的,具有固定的种子值(random.seed(...) 行中的更改值)。

首先我展示在我的 Linux (asciinema link) 上录制的 ASCII 视频截屏视频,然后是代码:

代码

Try it online!

import platform, time, sys
if platform.system() == 'Windows':
    import colorama
    colorama.init()

def vis(data, steps):
    def str_set(s, i, c):
        return s[:i] + c + s[i + 1:]
    def astr_set(a, j, i, c):
        a[j] = str_set(a[j], i, c)
    dlen = max(len(str(e)) for e in data) + 1
    loline = ''.join(str(e).zfill(dlen - 1) + '|' for e in data)
    ll = len(loline)
    N = len(steps)
    h1 = 3
    lines = [' ' * ll for e in range(h1 * N)] + [loline]
    def emit_frame():
        sys.stdout.write("\033[F" * len(lines) + '\n'.join(lines) + '\n')
        time.sleep(1)
    emit_frame()
    for i in range(N - 1):
        lpcur, lpnext = [dlen * steps[i + e] + (dlen - 2) // 2 for e in (0, 1)]
        for j in range(h1 - 1):
            astr_set(lines, i * h1 + j, lpcur, '|')
        dir_ = -1 if steps[i + 1] < steps[i] else +1 if steps[i + 1] > steps[i] else 0
        for j in range((i + 1) * h1, len(lines) - 1):
            astr_set(lines, j, lpcur, '.' if j < len(lines) - 2 else '?')
        for j in range(lpcur, lpnext + dir_, dir_):
            astr_set(lines, (i + 1) * h1 - 1, j, ('/' if dir_ < 0 else '\\') if j in (lpcur, lpnext) else '-')
            if j == lpcur:
                emit_frame()
        if i == N - 2:
            for j in range((i + 1) * h1, len(lines) - 1):
                astr_set(lines, j, lpnext, '|' if j < len(lines) - 2 else 'V')
            emit_frame()

def binary_search(f, l, r, target):
    steps = []
    while l <= r:
        m = (l + r) // 2
        steps.append(m)
        fm = f(m)
        if fm < target:
            l = m + 1
        elif fm > target:
            r = m - 1
        else:
            break
    return steps

def main():
    import random
    random.seed(3)
    data = sorted(random.randrange(100) for i in range(30))
    target = data[random.randrange(len(data))]
    steps = binary_search(lambda x: data[x], 0, len(data) - 1, target)
    vis(data, steps)

if __name__ == '__main__':
    main()

最终输出:

                                          |                                               
                                          |                                               
                                          \-----------------------\                       
                                          .                       |                       
                                          .                       |                       
                                          .                       \-----------\           
                                          .                       .           |           
                                          .                       .           |           
                                          .                       .     /-----/           
                                          .                       .     |     .           
                                          .                       .     |     .           
                                          .                       .  /--/     .           
                                          .                       .  |  .     .           
                                          .                       .  |  .     .           
                                          ?                       ?  V  ?     ?           
01|08|16|19|19|24|29|29|30|33|47|49|50|60|60|60|60|66|69|69|70|70|74|75|77|77|80|81|81|91|

我还创建了我的代码(下载代码 hereTry it online)的稍微修改的无限 ASCII 截屏版本,它可以生成下一个快速播放的视频(asciinema link):


还有一个版本,它使用 Unicode 字符来绘制漂亮的箭头和线条,它还显示了更密集的树,使用更多的数字进行搜索(下载代码 hereTry it online),你会得到下一个视频(asciinema link),在浏览器的新标签/窗口中打开下一个视频图像,可以看到它更漂亮更大:


还有一次尝试制作更高级的代码和可视化。现在是两级可视化,前半步是垂直绘制的,其余的步是水平绘制的。这样做是为了实现更高的图像密度,将 mor 数字放在控制台屏幕上。

像往常一样,下载代码here 和/或Try it online here。结果视频如下(加上asciinema link):

【讨论】:

  • 从我的角度来看看起来很棒,所以我投了赞成票。
  • @AlyAly12 几秒钟前,我刚刚在答案中添加了另一个代码版本和视频,带有 unicode 好字符。
  • @ArtiomKozyrev 刚刚更新了我的答案,添加了带有 Unicode 绘图的第三版算法,看起来更漂亮!见图片here。几乎是图形化的!
  • @AlyAly12 刚刚做了另一种算法,最高级的一种,请参阅我的答案结尾,其中显示了实际的算法,您还可以查看its video here。该算法是两级的,可以一次在屏幕上显示很多数字。二分搜索步骤的前半部分是垂直绘制的,其余的步骤是水平绘制的。因此,我设法在一个屏幕上放置了 500 个(3 位)数字。我制作这个算法是为了让您了解如何在一个屏幕上放置额外数量的数字以及如何制作两级垂直+水平绘图。
  • @ArtiomKozyrev 如果您仍然对我的答案的进展感兴趣 - 我刚刚更新了我的答案并在答案末尾添加了第四版算法。它绘制了最先进的控制台图形,您可以see it here。现在我做了两级方法,一半是垂直的,一半是水平的,这让我可以在一个屏幕上容纳难以置信的 500 个 3 位数字!!!请参阅asciinema link 了解更多更长和更高分辨率的视频。我的答案中提供了代码。
【解决方案2】:

您可以在项目中使用 django 框架

  1. 在前端提供一个包含两个字段的表单
  1. 数组本身
  2. 要在数组中搜索的值
  1. 在提交表单时获取值并对输入值应用二进制搜索算法。
  2. 在 UI 上显示结果

【讨论】:

    猜你喜欢
    • 2012-01-10
    • 1970-01-01
    • 2022-11-25
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多