Python 单元测试二进制搜索
我在实现二进制搜索的修改版本时遇到了一些困难(它只需要检查子列表中是否有1,然后继续搜索直到返回索引) 目前我想到的代码是: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]
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 forpython 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 forpython 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