二分法,是常用的方法,下面这里有个实例,讲述如何使用二分法写代码。
// Implementation of binary search
#include <iostream>
#include <string>
#include "vector.h"
using namespace std;
void initCityNames(Vector<string> & cities);
int findInSortedVector(string key, Vector<string> & vec);
int binarySearch(string key, Vector<string> & vec, int p1, int p2);
// 不停地使用二分法查找。
int main() {
Vector<string> cities;
initCityNames(cities);
for (string city : cities) {
int index = findInSortedVector(city, cities);
cout << city << " == " << cities[index] << endl;
}
return 0;
}
void initCityNames(Vector<string> & cities) {
cities += "Amsterdam", "Angora", "Athina", "Barcelona", "Berlin",
"Brest", "Brindisi", "Bruxelles", "Bucuresti", "Budapest",
"Cadiz", "Constantinople", "Danzig", "Dieppe", "Edinburgh",
"Erzurum", "Essen", "Frankfurt", "Kharkov", "Kobenhavn",
"Kyiv", "Lisboa", "London", "Madrid", "Marseille", "Moskva",
"Munchen", "Palermo", "Pamplona", "Paris", "Petrograd",
"Riga", "Roma", "Rostov", "Sarajevo", "Sevastopol",
"Smolensk", "Smyrna", "Sochi", "Sofia", "Stockholm",
"Venezia", "Warszawa", "Wien", "Wilno", "Zagrab", "Zurich";
};
int findInSortedVector(string key, Vector<string> & vec) {
return binarySearch(key, vec, 0, vec.size() - 1);
}
// Searches for the specified key in the Vector<string> vec, looking
// only at indices between p1 and p2, inclusive. The function returns
// the index of a matching element, or -1 if no match is found.
int binarySearch(string key, Vector<string> & vec, int p1, int p2) {
if (p1 > p2) return -1;
int mid = (p1 + p2) / 2;
if (key == vec[mid]) return mid;
if (key < vec[mid]) {
return binarySearch(key, vec, p1, mid - 1);
} else {
return binarySearch(key, vec, mid+1, p2);
}
}
实现的代码,这里的Vector是本地写的一个头文件,和标准库的中vector的用法基本上是一样的。
可能是因为历史原因,当时的vector不支持遍历。
android中有处用到二分法,读起来比较晦涩。
ssize_t SortedVectorImpl::indexOf(const void* item) const
{
return _indexOrderOf(item);
}
size_t SortedVectorImpl::orderOf(const void* item) const
{
size_t o;
_indexOrderOf(item, &o);
return o;
}
ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const
{
if (order) *order = 0;
if (isEmpty()) {
return NAME_NOT_FOUND;
}
// binary search
ssize_t err = NAME_NOT_FOUND;
ssize_t l = 0;
ssize_t h = size()-1;
ssize_t mid;
const void* a = arrayImpl();
const size_t s = itemSize();
while (l <= h) {
mid = l + (h - l)/2;
const void* const curr = reinterpret_cast<const char *>(a) + (mid*s);
ALOGE("wangrl VectorImpl curr = %s", curr);
const int c = do_compare(curr, item);
if (c == 0) {
err = l = mid;
break;
} else if (c < 0) {
l = mid + 1;
} else {
h = mid - 1;
}
}
if (order) *order = l;
return err;
}