Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 单元测试二进制搜索_Python - Fatal编程技术网

Python 单元测试二进制搜索

Python 单元测试二进制搜索,python,Python,我在实现二进制搜索的修改版本时遇到了一些困难(它只需要检查子列表中是否有1,然后继续搜索直到返回索引) 目前我想到的代码是: def binary_search(inList): low = 0 high = len(inList) -1 while low <= high: mid = (low+high)//2 upper = inList[mid:high] lower = inList[low:mid-1]

我在实现二进制搜索的修改版本时遇到了一些困难(它只需要检查子列表中是否有1,然后继续搜索直到返回索引)

目前我想到的代码是:

def binary_search(inList):
    low = 0
    high = len(inList) -1
    while low <= high:
        mid = (low+high)//2
        upper = inList[mid:high]
        lower = inList[low:mid-1]
        if any(lower):
            inList = lower
            high = mid-1
        elif any(upper):
            inList = upper
            low = mid
        else:
        return mid

        assert low < high
    return -1
我还注意到,当列表被销毁时,一些垃圾箱丢失了


我将如何创建一个测试套件,它将捕获这些问题,并让我将此算法扩展到其他输入集(例如,两半中的1,相邻的2个1等)。

您可以使用
unittest
构建一个简单的测试套件,该套件可以测试不同输入的结果,这个例子应该很简单

这应该可以让你开始了——试着运行这个脚本(在修改导入以导入二进制搜索模块之后),google for
python unittest
应该会让你对如何扩展这个脚本有很多想法

import unittest

from <your module> import binary_search

class TestBinarySearchForOne(unittest.TestCase):

    def test_small_range(self):
        self.assertEquals(1, binary_search(range(0, 2))

    def test_not_found(self):
        self.assertEquals(-1, binary_search([0, 4, 9, 190])

if __name__ == '__main__':
    unittest.main()
导入单元测试
从导入二进制搜索
类TestBinarySearchForOne(unittest.TestCase):
def测试小范围(自):
self.assertEquals(1,二进制搜索(范围(0,2))
def测试未找到(自身):
self.assertEquals(-1,二进制搜索([0,4,9190])
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
unittest.main()

您可以使用
unittest
构建一个简单的测试套件,该套件可以测试不同输入的结果,本例应该非常简单

这应该可以让你开始了——试着运行这个脚本(在修改导入以导入二进制搜索模块之后),google for
python unittest
应该会让你对如何扩展这个脚本有很多想法

import unittest

from <your module> import binary_search

class TestBinarySearchForOne(unittest.TestCase):

    def test_small_range(self):
        self.assertEquals(1, binary_search(range(0, 2))

    def test_not_found(self):
        self.assertEquals(-1, binary_search([0, 4, 9, 190])

if __name__ == '__main__':
    unittest.main()
导入单元测试
从导入二进制搜索
类TestBinarySearchForOne(unittest.TestCase):
def测试小范围(自):
self.assertEquals(1,二进制搜索(范围(0,2))
def测试未找到(自身):
self.assertEquals(-1,二进制搜索([0,4,9190])
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
unittest.main()

我不太明白您到底想做什么;您只需要更改“经典”算法中的两行,如下所示:


我不太明白您到底想做什么;您只需要更改“经典”算法中的两行,如下所示:


老兄,你问的问题就像三个问题合一,但这里什么都没有

要创建测试套件,只需编写一些好的示例并断言它们有效,例如:

from binary_search import binary_search

# Test a basic case
inlist = [0] * 256
inlist[123] = 1
assert binary_search(inlist) == 123

# Test a case with odd len
inlist = [0] * 99
inlist[20] = 1
assert binary_search(inlist, 20)

# Test the case with no 1s
inlist = [0] * 256
assert binary_search(inlist) == -1

# It's good to test corner cases just in case
inlist = [0] * 256
inlist[0] = 1
assert binary_search(inlist) == 0
inlist = [0] * 256
inlist[255] = 1
assert binary_search(inlist) == 255

你可能想考虑使用类似于NoSE或UnTestMoST之类的东西来帮助你组织测试,但无论如何都要在每次更改代码以确保其工作时运行测试。如果你将新的特性添加到代码中,例如允许在列表中搜索多个1s,那么你就要添加测试。哈维奥

您可能已经知道这一点,但我想说的是,这是一个在列表中查找1的非常糟糕的算法。问题是
any
是一个O(N)操作,因此在循环的每次迭代中,您都在执行N/2或N个操作。循环运行log(N)时间。这涉及到一些数学问题,但您可以很容易地证明这是一个O(N*log(N))算法,而只需使用
inlist.index(1)
(或基本for循环),您就可以在N个操作中找到1

然而,为了帮助您学习,我继续并修复了您的算法,这里是一个工作版本,它通过了上述测试:)

def二进制搜索(inList):
低=0
高=透镜(inList)
低<高:
中=(低+高)//2
上=内列表[中:高]
下部=内部列表[下部:中部]
如有(较低):
高=中
elif any(上):
低=中+1
其他:
#双方都没有1
返回-1
断言低==高
中途返回

您的版本的主要问题是您同时修改了低/高和inlist。因为低/高是inlist的索引,所以当您修改inlist时,它们不再指向正确的位置。

伙计,您问的问题就像三个问题合一,但这里什么都没有

要创建测试套件,只需编写一些好的示例并断言它们有效,例如:

from binary_search import binary_search

# Test a basic case
inlist = [0] * 256
inlist[123] = 1
assert binary_search(inlist) == 123

# Test a case with odd len
inlist = [0] * 99
inlist[20] = 1
assert binary_search(inlist, 20)

# Test the case with no 1s
inlist = [0] * 256
assert binary_search(inlist) == -1

# It's good to test corner cases just in case
inlist = [0] * 256
inlist[0] = 1
assert binary_search(inlist) == 0
inlist = [0] * 256
inlist[255] = 1
assert binary_search(inlist) == 255

你可能想考虑使用类似于NoSE或UnTestMoST之类的东西来帮助你组织测试,但无论如何都要在每次更改代码以确保其工作时运行测试。如果你将新的特性添加到代码中,例如允许在列表中搜索多个1s,那么你就要添加测试。哈维奥

您可能已经知道这一点,但我想说的是,这是一个在列表中查找1的非常糟糕的算法。问题是
any
是一个O(N)操作,因此在循环的每次迭代中,您都在执行N/2或N个操作。循环运行log(N)时间。这涉及到一些数学问题,但您可以很容易地证明这是一个O(N*log(N))算法,而只需使用
inlist.index(1)
(或基本for循环),您就可以在N个操作中找到1

然而,为了帮助您学习,我继续并修复了您的算法,这里是一个工作版本,它通过了上述测试:)

def二进制搜索(inList):
低=0
高=透镜(inList)
低<高:
中=(低+高)//2
上=内列表[中:高]
下部=内部列表[下部:中部]
如有(较低):
高=中
elif any(上):
低=中+1
其他:
#双方都没有1
返回-1
断言低==高
中途返回

您的版本的主要问题是您同时修改了低/高和inlist。因为低/高是inlist中的索引,所以当您修改inlist时,它们不再指向正确的位置。

谢谢!我想您不知道为什么代码经过3次迭代后现在给我空列表?很抱歉,我发现了这一点困难的
from binary_search import binary_search

# Test a basic case
inlist = [0] * 256
inlist[123] = 1
assert binary_search(inlist) == 123

# Test a case with odd len
inlist = [0] * 99
inlist[20] = 1
assert binary_search(inlist, 20)

# Test the case with no 1s
inlist = [0] * 256
assert binary_search(inlist) == -1

# It's good to test corner cases just in case
inlist = [0] * 256
inlist[0] = 1
assert binary_search(inlist) == 0
inlist = [0] * 256
inlist[255] = 1
assert binary_search(inlist) == 255
def binary_search(inList):
    low = 0
    high = len(inList)
    while low < high:
        mid = (low + high) // 2
        upper = inList[mid:high]
        lower = inList[low:mid]
        if any(lower):
            high = mid
        elif any(upper):
            low = mid + 1
        else:
            # Neither side has a 1
            return -1

    assert low == high
    return mid