STLシリーズ(2)二分探索
関数:binary_search
- コンテンツの不明な記事に記載されていない関数参照がある場合は、前の記事STLシリーズ(1)ソートの使用法を確認してください
- この号の内容には、似ているが異なる言葉がたくさんあります。注意深く読み、比較に注意を払い、記憶を深め、内容が反復的で動揺していると感じないでください。
- 太字のステートメントに注意してください
- メッセージやコメントを残す
使用法1(基本検索)
コンテンツ:
binary_search( 数组名 + n1, 数组名 + n2, 值 )
n1和n2都是 int 类型的表达式 , 可以包含变量
如果n1 = 0,则 + n1 可以不写
查找区间为下标范围为[n1,n2)的元素, 下标为n2的元素不在查找区间内
在该区间内查找"等于"值的元素, 返回值为true(找到) 或false(没找到)
"等于"的含义: a 等于 b <==> a < b和b < a都不成立
例:
int a[] = {
12,45,3,98,21,7 };
sort(a, a + 6);
Print(a, 6); //结果: 3,7,12,21,45,98
cout << "Result : " << binary_search(a, a + 6, 12) << endl; //Result : 1
cout << "Result : " << binary_search(a, a + 6, 77) << endl; //Result : 0
- STLバイナリ検索を使用する前にソートを使用してください。
使用法2(カスタムソートルール検索)
コンテンツ:
カスタムソートルールでソートするために、要素はバイナリ検索用の任意のT型配列です。
binary_search(数组名 +n1 , 数组名 + n2 , 值 , 排序规则结果名() );
n1和n2都是int类型得表达式,可以包含变量
如果 n1 = 0 , 则 + n1可以不写
查找区间为下标范围[n1,n2)的元素 , 下标为n2的元素不在查找区间内
在该区间内查找"等于"值的元素, 返回值为true(找到) 或false(没找到)
*查找时的排序规则,必须和排序时的规则一致!
"等于"的含义: a 等于 b <==> "a必须在b前面"和"b必须在a前面"都不成立
印象を深めるために重要なことが何度も強調されてきました!水の記事ではありません!
例:
int a[] = {
12,45,3,98,21,7 };
sort(a, a + 6, Rule1()); //按从小到大排序(此处使用Rule1规则进行排序)
Print(a, 6); // 21,12,3,45,7,98
cout << "Result : " << binary_search(a, a + 6, 7) << endl; //Result : 0
cout << "Result : " << binary_search(a, a + 6, 8, Rule1()) << endl; //Result : 1
return 0;
上記のコードの4行目は間違ったコードです
ここで、コンパイラの戻り値0は、それが見つからなかったことを意味するものではありません。
binary_search()バイナリ検索ルールは照合と一致している必要があります。そうでない場合、戻り値は意味をなしません。
完全なコード:(カスタム関数を含む)
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Rule1 {
bool operator()(const int& a1, const int& a2)const {
return a1 % 10 < a2 % 10;
}
};
void Print(int a[], int size);
int main() {
int a[] = {
12,45,3,98,21,7 };
sort(a, a + 6);
Print(a, 6);
cout << "Result : " << binary_search(a, a + 6, 12) << endl;
cout << "Result : " << binary_search(a, a + 6, 77) << endl;
sort(a, a + 6, Rule1());//按从小到大排序
Print(a, 6);
cout << "Result : " << binary_search(a, a + 6, 7) << endl;
cout << "Result : " << binary_search(a, a + 6, 8, Rule1()) << endl;
return 0;
}
void Print(int a[], int size) {
int i;
for (i = 0; i < size - 1; i++) {
cout << a[i] << ",";
}
cout << a[i];
cout << endl;
}
関数lower_bound
使用法1(下限を見つける)
要素タイプTを使用して、小さいものから大きいものにソートされた基本データ型を検索します
T * lower_bound(数组名 + n1 , 数组名 + n2 , 值);
ポインタを返すT * p;
* pが持つ要素である検索間隔における最小の添字よりも大きいかまたは等しい、見出されない場合、「値」添字n2を持つ要素にP点
注:n2はクエリ範囲内にありません!
例:
int a[NUM] = {
12,5,3,5,98,21,7 };
sort(a, a + NUM);
Print(a, NUM); // 结果: 3,5,5,7,12,21,98
int* p1 = lower_bound(a, a + NUM, 5); //范围整个数组,p1指向下标最小的 大于等于5的元素
cout << " p1指向的内容:"<< *p1 << " 下标:" << p1 - a << endl; // 结果:5,1
使用法2(下限を見つけるためのカスタムルール)
要素タイプがTで、カスタムの並べ替えルールに従って並べ替えられた配列を検索します
T * lower_bound(数组名 + n1 , 数组名 + n2 , 值 , 排序规则结构名());
ポインタを返すT * p;
* pは検索間隔の最小の添え字です。カスタムの並べ替えルールに従って、「値」の後に要素を並べ替えることができます。見つからない場合、pは添え字n2の要素を指します。
注:n2はクエリ範囲内にありません!
例:
int a[NUM] = {
12,5,3,5,98,21,7 };
sort(a, a + NUM, Rule1());
Print(a, NUM); // 结果 :21,12,3,5,5,7,98
cout << *lower_bound(a, a + NUM, 16, Rule1()) << endl; // 结果 : 7 (输出元素值)
cout << lower_bound(a, a + NUM, 25, Rule1()) - a << endl; // 结果 : 3 (输出下标值)
次の内容の理由を分析してみることができます
関数upper_bound
使用法1(上限を見つける)
コンテンツ:
要素タイプTを使用して、小さいものから大きいものにソートされた基本タイプの配列を検索します
T * upper_bound(数组名 + n1 , 数组名 + n2 , 值);
ポインタを返すT * p;
* pは、検索間隔で添え字が最小で「値」より大きい要素です。見つからない場合、pは添え字n2の要素を指します。
例:
int a[NUM] = {
12,5,3,5,98,21,7 };
sort(a, a + NUM);
Print(a, NUM); // 结果: 3,5,5,7,12,21,98
int* p2 = upper_bound(a, a + NUM, 5); //范围整个数组,p2指向下标最小的 大于5的元素
cout << *p2 << endl; // 结果:7
cout << *upper_bound(a, a + NUM, 13) << endl;//查找大于13的下标最小的元素值 结果 :21
使用法2(上限を見つけるためのカスタムルール)
コンテンツ:
要素が任意のT型であり、カスタムの並べ替えルールに従って並べ替えられている配列を検索します
T * upper_bound(数组名 + n1 , 数组名 + n2 , 值 , 排序规则结构体());
ポインタを返すT * p;
* pは、検索間隔で添え字が最小の要素です。カスタムの並べ替え規則に従って、**は**「値」の後の要素である必要があります。見つからない場合、pは添え字n2の要素を指します。
例:
int a[NUM] = {
12,5,3,5,98,21,7 };
sort(a, a + NUM, Rule1());
Print(a, NUM); // 结果 :21,12,3,5,5,7,98
cout << *lower_bound(a, a + NUM, 16, Rule1()) << endl; // 结果 : 7 (输出元素值)
cout << lower_bound(a, a + NUM, 25, Rule1()) - a << endl; // 结果 : 3 (输出下标值)
cout << upper_bound(a, a + NUM, 18, Rule1()) - a << endl; // 结果 : 7 (无意义)(个位数大于8无法找到)(找不到时返回终点元素)
if (upper_bound(a, a + NUM, 18, Rule1()) == a + NUM)
cout << "not found" << endl; // ==>not found;
cout << *upper_bound(a, a + NUM, 5, Rule1()) << endl; // 结果 : 7 (自己想想原因)
cout << *upper_bound(a, a + NUM, 4, Rule1()) << endl; // 结果 : 5
完全なコード:
#include<iostream>
#include<algorithm>
#include<cstring>
#define NUM 7
using namespace std;
struct Rule1 {
bool operator()(const int& a1, const int& a2)const {
return a1 % 10 < a2 % 10;
}
};
void Print(int a[], int size);
int main() {
int a[NUM] = {
12,5,3,5,98,21,7 };
sort(a, a + NUM);
Print(a, NUM); // 结果: 3,5,5,7,12,21,98
int* p1 = lower_bound(a, a + NUM, 5); //范围整个数组,p1指向下标最小的 大于等于5的元素
cout << " p1指向的内容:"<< *p1 << " 下标:" << p1 - a << endl; // 结果:5,1
int* p2 = upper_bound(a, a + NUM, 5); //范围整个数组,p2指向下标最小的 大于5的元素
cout << *p2 << endl; // 结果:7
cout << *upper_bound(a, a + NUM, 13) << endl;//查找大于13的下标最小的元素值 结果 :21
sort(a, a + NUM, Rule1());
Print(a, NUM); // 结果 :21,12,3,5,5,7,98
cout << *lower_bound(a, a + NUM, 16, Rule1()) << endl; // 结果 : 7 (输出元素值)
cout << lower_bound(a, a + NUM, 25, Rule1()) - a << endl; // 结果 : 3 (输出下标值)
cout << upper_bound(a, a + NUM, 18, Rule1()) - a << endl; // 结果 : 7 (无意义)(个位数大于8无法找到)(找不到时返回终点元素)
if (upper_bound(a, a + NUM, 18, Rule1()) == a + NUM)
cout << "not found" << endl; // ==>not found;
cout << *upper_bound(a, a + NUM, 5, Rule1()) << endl; // 结果 : 7 (自己想想原因)
cout << *upper_bound(a, a + NUM, 4, Rule1()) << endl; // 结果 : 5
return 0;
}
void Print(int a[], int size) {
int i;
for (i = 0; i < size - 1; i++) {
cout << a[i] << ",";
}
cout << a[i];
cout << endl;
}