【问题标题】:Search a number in a sorted 2D array在已排序的二维数组中搜索数字
【发布时间】:2019-07-01 03:54:17
【问题描述】:

我正在尝试在二维数组列表中查找我正在查找的数字。但是,在搜索之前必须先对其进行排序。

当我尝试在二维数组中查找数字时,一切似乎都运行良好。这只是以仍然有效的方式对 2D 数组进行排序的事实。假设我想对一个 3x3 二维数组进行排序。它应该显示的方式是:

    [[8, 27, 6],
     [1, 0, 11],
     [10, 9, 3]]

然后,我将使用二进制搜索方法通过已排序的 2D 数组查找一个数字。我的中间值将位于搜索数组的中间。

这只是一个示例,但是当我输入随机数字然后对行和列进行排序时,我想要完成什么。使用这个想法,我使用 Python 中的 random.randint() 库来随机化我的数字。然后,我试图在我的二维数组中进行排序,但在继续之前它并不是真正的排序。

n = 5
m = 5

def findnum_arr(array, num):
    low = 0
    high = n * m - 1
    while (high >= low):
        mid = (low + high) // 2
        i = mid // m
        j = mid % m

        if (num == array[i][j]):
            return True
        if (num < array[i][j]):
            high = mid - 1
        else:
            low = mid + 1
    return False

if __name__ == '__main__':
    multi_array = [[random.randint(0, 20) for x in range(n)] for y in range(m)]
    sorted(multi_array)

排序:

    [[0, 1, 3],
     [6, 8, 9],
     [10, 11, 27]]

应该是已排序的二维数组。是否可以用 sorted 函数分别对行和列进行排序?

【问题讨论】:

    标签: python python-3.x sorting search 2d


    【解决方案1】:

    终于找到了一个合适的解决方案,不使用numpy,避免sum()模块。

    if __name__ == '__main__':
        x = 7
        multi_array = [[random.randint(0, 200) for x in range(n)] for y in range(m)]
        # one_array = sorted(list(itertools.chain.from_iterable(multi_array))) Another way if you are using itertools
        one_array = sorted([x for row in multi_array for x in row])
        sorted_2d = [one_array[i:i+m] for i in range(0, len(one_array), n)]
    
        print("multi_array list is: \n{0}\n".format(multi_array))
        print("sorted 2D array: \n{0}\n".format(sorted_2d))
        if not findnum_arr(sorted_2d, x):
            print("Not Found")
        else:
            print("Found")
    

    输出:

    multi_array list is:
    [[40, 107, 23, 27, 42], [150, 84, 108, 191, 172], [154, 22, 161, 26, 31], [18, 150, 197, 77, 191], [96, 124, 81, 1
    25, 186]]
    
    sorted 2D array:
    [[18, 22, 23, 26, 27], [31, 40, 42, 77, 81], [84, 96, 107, 108, 124], [125, 150, 150, 154, 161], [172, 186, 191, 1
    91, 197]]
    
    Not Found
    

    我想找到一个标准库模块,我可以在其中将 2D 数组扁平化为 1D 并对其进行排序。然后,我将对我的一维数组进行列表理解并将其构建为二维数组。这听起来很多工作,但似乎工作正常。让我知道是否有更好的方法可以在没有 numpy 的情况下更快地做到这一点:)

    【讨论】:

      【解决方案2】:

      在嵌套列表上调用 sorted,该列表将根据列表中的第一个索引进行排序。

      例子:

      arr = [[8, 27, 6],[1, 0, 11],[10, 15, 3], [16, 12, 14], [4, 9, 13]]
      

      会回来

      [[1, 0, 11], [4, 9, 13], [8, 27, 6], [10, 15, 3], [16, 12, 14]]
      

      要按照您想要的方式进行操作,您必须先压平然后再整形。

      为此,我会尝试引入 numpy.

      import numpy as np
      
      
      a = np.array(sorted(sum(arr, [])))
      
      #sorted(sum(arr, [])) flattens the list
      
      b = np.reshape(a, (-1,3)).tolist()
      

      为清晰而编辑:您可以使用 m 和 n 作为 np.reshape 中的参数。第一个参数 (m) 将返回数组的数量,而 (n) 将返回数组的数量。

      在任一参数中使用 -1 意味着重新整形的数组将适合返回另一个参数的要求。

      b 会返回

      [[0, 1, 3], [4, 6, 8], [9, 10, 11], [12, 13, 14], [15, 16, 27]]
      

      【讨论】:

      • 当我重塑它时,-1 会是什么?
      • 当使用 np.reshape 时,参数是(列表的数量,列表的大小)。将任一设置为负值就适合它。调用 (-1, 3) 意味着您将拥有许多长度为 3 的数组。如果您将其称为 (3, -1),则意味着您需要三个数组,并且它们的长度可以满足该要求。
      • 但是我们会遇到“硬编码”数组大小的问题。 2D 数组只是一个示例,我对所有尺寸的 2D(1x1、2x2、3x3...n x m)都感兴趣。如何以模块化方式重塑我的 2D?
      • 这就是为什么我说用你的 n 替换 3。你实际上可以把它写成 (m, n),也许我应该这样写。为了清楚起见,编辑了我的原始帖子。
      • 所以如果我使用 numpy,总是有可能解决这个问题,因为我使用的是它提供的模块。我的想法是将二维数组展平为一维数组,然后对其进行排序。但它让我再次将其转换为 2D 数组:使用列表推导对我的工作有帮助吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 2021-02-03
      • 2021-12-18
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      相关资源
      最近更新 更多