20 Haziran 2019 Perşembe

std::upper_bound - Büyüktür (>) Araması

Giriş
Açıklaması şöyle.
upper_bound requires ForwardIterator. ForwardIterator requires that * returns an actual reference, and that if two iterators are equal then they refer to the same object.
Yani verilen değerden > olan ilk değeri döndürür. Algoritma belirtilen değer ile iterator'ün değerini şöyle karşılaştırır.
if (!(value < *it)) { ... } 
Dolayısıyla arama için kullanılan değerin < operatörünün tanımlı olması gerekir.

std::map için Kullanmayın
std::map sınıfının kendi upper_bound() metodu vardır

Örnek
Şöyle bir örnek verebiliriz. Elimizde BMI değişkeni olsun. BMI 18.5 ise upper_bound dizideki >18 koşulunu ilk sağlayan 25 değerini bulur, Yani 1. indeksi gösteri. switch (1 - 0) yani 1 değeri sayesinde "You are normal" yazısını görürüz.
double const boundaries[] = { 18.5, 25, 30, 35 };

switch (upper_bound(begin(boundaries), end(boundaries), BMI) - boundaries) {
    case 0: cout << "You are underweight "       << endl; break;
    case 1: cout << "You are normal"             << endl; break;
    case 2: cout << "You are overweight"         << endl; break;
    case 3: cout << "You are obese"              << endl; break;
    case 4: cout << "You are gravely overweight" << endl; break;
};
Elma Elma Karşılaştırması
Örnek  - Aynı tipe getirme
Eğer arama için kullanılan değer iteratör ile saklanılan değerden farklıysa hata alabiliriz. Elimizde MyInt isimli bir sınıf olsun. Aşağıdaki kodda upper_bound 2 için int < MyInt operatörünü arayacak ve bulamayacak. Dolayısıyla derleme hatası alırız.
class MyInt {
  public:
    MyInt(int _val){...}
    bool operator<(const MyInt& other) const {...}
};

set<MyInt> s;
s.insert(MyInt(2));
set<MyInt>::iterator it = upper_bound(s.begin(), s.end(), 2);
Derleme hatasını gidermek için şöyle yapabiliriz.
set<MyInt>::iterator it = upper_bound(s.begin(), s.end(), MyInt(2));
Örnek  - İki Karşılaştırma Metodu Kodlama
Elimizde pair içeren bir vector olsun.

std::vector<std::pair<double,long> > v;
Şöyle yapmak istersek elma,armut karşılaştırması yaparız.
auto it = std::upper_bound(v.begin(), v.end(), 25.,...);
Derleme hatasından kurtulmak için elm+armut ve armut+elma karşılaştırmasını kodlamak gerekir. Şöyle yaparız.
struct LT {
  bool operator()(double y, const std::pair<double, long>& x) {
    return x.first < y;
  }
  bool operator()(const std::pair<double, long>& x, double y) {
    return x.first < y;
  }
};
// ...
std::upper_bound(v.begin(), v.end(), 25.0, LT());
Bir diğer çözüm ise elma elma haline getirmek. Şöyle yaparız.
bool lt(const std::pair<double, long>& x, const std::pair<double, long>& y)
{
    return x.first < y.first;
}

std::vector<std::pair<double, long>> v;

auto it = std::upper_bound(v.begin(), v.end(), std::make_pair(25., 0.), lt);

Hiç yorum yok:

Yorum Gönder