github 莫名其妙的打不开了,那就贴在这里吧
#!/usr/bin/env python
# -*- #coding:utf-8
'''
Created on 2013-9-4
@author: mingdong.li
二分查找法,有相同元素列表
'''
import unittest
from test.test_bisect import TestErrorHandling
from test import test_support
_searchMode = {"FIRST":1, "LAST":0}
def binarySearchTemplate(sequence, fromIndex, toIndex, key, searchMode):
"""
@param sequence: is a list or tuple to be searched, it's sequential and no repeating elements
@param fromIndex: the index of the first element to be searched
@param toIndex: the index of the last element to be searched
@param key: the value to be searched for
@param searchMode: FIRST=1(return the index of the first element in the repeating sequence); LAST=0(the last one)
@return: index of the search key, no found will return -1
"""
low = fromIndex
high = toIndex - 1
flag = -1
while(low <= high):
mid = low + ((high-low)>>1)
midValue = sequence[mid]
if midValue < key:
low = mid + 1
elif midValue > key:
high = mid -1
else:
if searchMode is None:
return mid
elif searchMode == _searchMode['FIRST']:
high = mid - 1
flag = mid
elif searchMode == _searchMode['LAST']:
low = mid + 1
flag = mid
else:
if searchMode == _searchMode['FIRST']:
if key == sequence[high]:
# print 'first high'
return high
else:
# print 'first flag'
return flag
elif searchMode == _searchMode['LAST']:
if key == sequence[low-1]:
# print 'last high'
return low-1
else:
# print 'last flag'
return flag
else:
return -1
# return -1
def binarySearch(sequence, key, searchMode=None):
if not isinstance(sequence, list) and not isinstance(sequence, tuple):
return "The %s is not list or tuple" % sequence
return binarySearchTemplate(sequence, 0, len(sequence), key, searchMode)
def test_main(verbose=None):
class TestBinarySearch(unittest.TestCase):
a = [1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 7, 7, 7, 7]
b = (1, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 7)
precomputedCase = [
(binarySearch, 'a', 88, None, "The a is not list or tuple"),
(binarySearch, a, 2, None, 3),
(binarySearch, a, 88, None, -1),
(binarySearch, a, 7, _searchMode['FIRST'], 11),
(binarySearch, a, 7, _searchMode['LAST'], 15),
(binarySearch, a, 1, _searchMode['FIRST'], 0),
(binarySearch, a, 1, _searchMode['LAST'], 2),
(binarySearch, a, 4, _searchMode['FIRST'], 6),
(binarySearch, a, 11, _searchMode['FIRST'], -1),
(binarySearch, a, 11, _searchMode['LAST'], -1),
(binarySearch, b, 2, None, 4),
(binarySearch, b, 88, None, -1),
(binarySearch, b, 7, _searchMode['FIRST'], 11),
(binarySearch, b, 7, _searchMode['LAST'], 12),
(binarySearch, b, 1, _searchMode['FIRST'], 0),
(binarySearch, b, 1, _searchMode['LAST'], 2),
(binarySearch, b, 4, _searchMode['FIRST'], 6),
(binarySearch, b, 11, _searchMode['FIRST'], -1),
(binarySearch, b, 11, _searchMode['LAST'], -1)
]
def test_precomputed(self):
for func, sequ, key, mode, expected in self.precomputedCase:
self.assertEqual(func(sequ, key, mode), expected)
from types import BuiltinFunctionType
test_classes = [TestBinarySearch]
if isinstance(binarySearch, BuiltinFunctionType):
test_classes.append(TestErrorHandling)
test_support.run_unittest(*test_classes)
if __name__ == '__main__':
print "test..."
test_main(verbose=True)