今天在使用数组的时候,亲身体验了一把sort、binary_search,以前只是在用map、set之类的时候才用到。
假设有结构体
struct player_info {
uint32_t id;
uint32_t lv;
...
};
player_info players[10];
想对players按id进行排序,并且用二分法进行搜索。
sort有两种方法:
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator, class Compare>
void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
我们需要对Compare进行定义,也是两种
一种直接写函数:
bool myCompare (const player_info& a, const player_info& b)
{
return (a.id < b.id);
}
然后就是:sort(players, players + 10, myCompare);
另一种就是直接对struct进行重载:
struct player_info {
uint32_t id;
uint32_t lv;
...
bool operator < (const player_info& a)const{
return (id < a.id);
}
bool operator == (const player_info& a)const{
return (id == a.id);
}
};
然后就是:sort(players, players + 10);
binary_search有两种方法:
template <class ForwardIterator, class T>
bool binary_search ( ForwardIterator first, ForwardIterator last,
const T& value );
template <class ForwardIterator, class T, class Compare>
bool binary_search ( ForwardIterator first, ForwardIterator last,
const T& value, Compare comp );
我们也需要对Compare进行定义,也是两种
一种直接写函数:
bool myEqual (const player_info& a, const player_info& b)
{
return (a.id == b.id);
}
然后就是:binary_search(players, players + 10, val, myEqual);
注意val好像只能是player_info类型的,不能是其它的,比如uint32_t;
另一种就是直接对struct进行重载:
struct player_info {
uint32_t id;
uint32_t lv;
...
bool operator < (const player_info& a)const{
return (id < a.id);
}
bool operator == (const player_info& a)const{
return (id == a.id);
}
};
然后就是:binary_search(players, players + 10, val);
但是binary_search无法返回我们搜索到的元素,只返回bool,
所以还有个方案就是使用equal_range
equal_range同样有两种方法:
template <class ForwardIterator, class T>
pair<ForwardIterator,ForwardIterator>
equal_range ( ForwardIterator first, ForwardIterator last, const T& value );
template <class ForwardIterator, class T, class Compare>
pair<ForwardIterator,ForwardIterator>
equal_range ( ForwardIterator first, ForwardIterator last, const T& value,
Compare comp );
网上摘录的关于equal_range的Example:
// equal_range example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
bool mygreater (int i,int j) { return (i>j); }
int main () {
int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
pair<vector<int>::iterator,vector<int>::iterator> bounds;
// using default comparison:
sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
bounds=equal_range (v.begin(), v.end(), 20); // ^ ^
// using "mygreater" as comp:
sort (v.begin(), v.end(), mygreater); // 30 30 20 20 20 10 10 10
bounds=equal_range (v.begin(), v.end(), 20, mygreater); // ^ ^
cout << "bounds at positions " << int(bounds.first - v.begin());
cout << " and " << int(bounds.second - v.begin()) << endl;
return 0;
}
Output:
bounds at positions 2 and 5
网上摘录的关于binary_search的Example:
// binary_search example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
bool myfunction (int i,int j) { return (i<j); }
int main () {
int myints[] = {1,2,3,4,5,4,3,2,1};
vector<int> v(myints,myints+9); // 1 2 3 4 5 4 3 2 1
// using default comparison:
sort (v.begin(), v.end());
cout << "looking for a 3... ";
if (binary_search (v.begin(), v.end(), 3))
cout << "found!/n"; else cout << "not found./n";
// using myfunction as comp:
sort (v.begin(), v.end(), myfunction);
cout << "looking for a 6... ";
if (binary_search (v.begin(), v.end(), 6, myfunction))
cout << "found!/n"; else cout << "not found./n";
return 0;
}
Output:
looking for a 3... found!
looking for a 6... not found.
网上摘录的关于sort的Example:
// sort algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
bool myfunction (int i,int j) { return (i<j); }
struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobject;
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33
vector<int>::iterator it;
// using default comparison (operator <):
sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33
// using function as comp
sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)
// using object as comp
sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)
// print out content:
cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
cout << " " << *it;
cout << endl;
return 0;
}
Output:
myvector contains: 12 26 32 33 45 53 71 80
而c语言里德库函数分别为:
void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
void *bsearch(const void *key, const void *base, size_t nmem, size_t size, int (*comp)(const void *, const void *));
key指向所要查找的元素,base指向进行查找的数组,nmem为查找长度,一般为数组长度,size为每个元素所占的字节数,一般用sizeof(...)表示,comp指向比较子函数,它定义比较的规则。需要注意的是,数据必须是经过预先排序的,而排序的规则要和comp所指向比较子函数的规则相同。如果查找成功则返回数组中匹配元素的地址,反之则返回空。对于有多于一个的元素匹配成功的情况,bsearch()未定义返回哪一个。