lower_bound

stlÀÇ binary search¸¦ À߸ø »ç¿ë ÇÏ°í ÀÖ¾ú´Ù.
lower_bound¸¦ »ç¿ëÇÏ¸é µÇ´Âµ¥ binary_search Äڵ带 ºñºñ ²¿¾Æ¼­ À߸ø »ç¿ëÇß´Ù.
binary_search.html ¿¡ ³ª¿Í Àִ°ÍÀº »ç¿ëÇÏÁö ¸»ÀÚ. Áö¿ï±î °í¹ÎÇßÁö¸¸ ±×³É ³²°Ü µÐ´Ù.

lower_bound ÇÔ¼ö¸¦ »ç¿ëÇϱâ À§Çؼ­´Â ¹Ì¸® ¼ÒÆà µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.

°øÅëÀûÀ¸·Î »ç¿ëÇÏ´Â Çì´õ¿Í ÄÚµå´Â ´ÙÀ½°ú °°´Ù.

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

lower_bound´Â "algorithm" Çì´õ¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ´Ù.

template< class ForwardIt, class T >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value );

template< class ForwardIt, class T, class Compare >
ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value, Compare comp );

¹üÀ§ [first, last]¿¡¼­ valueº¸´Ù Å©°Å³ª °°Àº ù¹ø° ¿ä¼Ò¸¦ °¡¸®Å°´Â iterator¸¦ ¸®ÅÏÇÑ´Ù.
±âº» µ¥ÀÌÅÍ Å¸ÀÔÀ» »ç¿ëÇÏ´Â °æ¿ì ºñ±³ÇÔ¼ö¸¦ ¸¸µé ÇÊ¿ä°¡ ¾ø´Ù.

¾Æ·¡´Â ¼³¸íÀ» À§ÇØ ºñ±³ ÇÔ¼ö¸¦ ¸¸µé¾ú´Ù.

ºñ±³ ÇÔ¼ö »ç¿ëÇϱâ

void PrintVec(vector<int> vec)
{
    for(unsigned int i = 0; i < vec.size(); i++)
        cout << vec[i] << " ";
    cout << endl;
}

bool comp(const int& lhs, const int& rhs)
{
    return lhs < rhs;
}

void Print(const vector<int>& vec, int value)
{
    vector<int>::const_iterator iter = lower_bound(vec.begin(), vec.end(), value, comp);
    if(iter == vec.end())
        iter = vec.end() - 1;
    cout << value << "> index: " <<  iter - vec.begin() << ", value : " << *iter << endl;
}


void TestFunction()
{
    const int arr[] = {3, 7, 9, 10, 20, 40, 100};
    vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]));
    Print(vec, 2);
    Print(vec, 10);
    Print(vec, 20);
    Print(vec, 15);
    Print(vec, 100);
    Print(vec, 110);
}

°á°ú)
2> index: 0, value : 3
10> index: 3, value : 10
20> index: 4, value : 20
15> index: 4, value : 20
100> index: 6, value : 100
110> index: 6, value : 100

±¸Á¶Ã¼ÀÎ °æ¿ì ºñ±³ ÇÔ¼ö »ç¿ë

struct PairInt
{
    int key;
    int value;
};

bool ComparePairInt(const PairInt& lhs, const int value)
{
    return lhs.key < value;
}

void PrintPairInt(const vector<PairInt>& vec, int key)
{
    vector<PairInt>::const_iterator iter = lower_bound(vec.begin(), vec.end(), key, ComparePairInt);
    if(iter == vec.end())
        iter = vec.end() - 1;
    cout << key << "> key: " <<  iter->key << ", value : " << iter->value << endl;
}

void TestStructFunc()
{
    const PairInt arr[] = {{3, 10}, {7, 30}, {9, 100}, {10, 0}};
    vector<PairInt> vec (arr, arr + sizeof(arr) / sizeof(arr[0]));

    PrintPairInt(vec, 7);
    PrintPairInt(vec, 8);
    PrintPairInt(vec, 15);
}

°á°ú)
7> key: 7, value : 30
8> key: 9, value : 100
15> key: 10, value : 0

±¸Á¶Ã¼ÀÎ °æ¿ì ºñ±³ Ŭ·¡½º(±¸Á¶Ã¼) »ç¿ë

Ŭ·¡½º(±¸Á¶Ã¼)·Î ºñ±³ ÇÒ¶§´Â operator ¿¬»êÀÚ¸¦ »ç¿ëÇؼ­ °Ë»öÇÑ´Ù.

struct CompreInt
{
    bool operator () (const PairInt & lhs, int key) const
    {
        return lhs.key < key;
    }
    bool operator () (const PairInt lhs, const PairInt & rhs) const
    {
        return lhs.key < rhs.key;
    }
};

void PrintClass(const vector<PairInt>& vec, int key)
{
    vector<PairInt>::const_iterator iter = lower_bound(vec.begin(), vec.end(), key, CompreInt());
    if(iter == vec.end())
        iter = vec.end() - 1;
    cout << key << "> key: " <<  iter->key << ", value : " << iter->value << endl;
}

void TestStruct()
{
    const PairInt arr[] = {{3, 10}, {7, 30}, {9, 100}, {10, 0}};
    vector<PairInt> vec (arr, arr + sizeof(arr) / sizeof(arr[0]));

    PrintClass(vec, 7);
    PrintClass(vec, 8);
    PrintClass(vec, 15);

    PairInt tmp = {8, 0};
    vector<PairInt>::const_iterator iter = lower_bound(vec.begin(), vec.end(), tmp, CompreInt());
    cout << tmp.key << " " << iter->key << endl;
    tmp.key = 7;
    iter = lower_bound(vec.begin(), vec.end(), tmp, CompreInt());
    cout << tmp.key << " " << iter->key << endl;
}

°á°ú)
7> key: 7, value : 30
8> key: 9, value : 100
15> key: 10, value : 0
8 9
7 7

½ÇÁ¦ : Key¿¡ µû¶ó º¸Á¤Çϱâ

key¿¡ µû¶ó °ªÀ» º¸Á¤ÇÑ´Ù.  (key, value) °ªÀÌ ´ÙÀ½°ú °°ÀÌ ÁÖ¾îÁú¶§,
(3, 10), (7, 30) , (10,  100) , (20, 0)

´ÙÀ½°ú °°ÀÌ key¿¡ µû¶ó °ªÀÌ º¸Á¤ µÇ¾î¾ß ÇÑ´Ù.

key°¡ 2ÀÌ¸é °ªÀº 10, key°¡ À妽º 0º¸´Ù ÀÛÀ¸¸é º¸°£À» ÇÏÁö ¾Ê°í ÃÖÃÊ °ªÀ» »ç¿ëÇÑ´Ù.
key°¡ 3ÀÌ¸é °ªÀº 10
key°¡ 100ÀÌ¸é °ªÀº 0, key°¡ À妽º ¸¶Áö¸· º¸´Ù Å©¸é º¸°£À» ÇÏÁö ¾Ê°í ¸¶Áö¸· °ªÀ» »ç¿ëÇÑ´Ù.

key°¡ 5À̸é 20,  10~30ÀÇ 0.5´Â 20ÀÌ´Ù.
key°¡ 11ÀÌ¸é  90, 100~0ÀÇ 0.1Àº 90ÀÌ´Ù.

NumberMid.h ÆÄÀÏ
#ifndef _NUMBER_MID
#define _NUMBER_MID

#include <vector>
#include <algorithm>
#include <iostream>

//must be Ascending sorting before using Find function.
template <class T1, class T2>
class NumberMid
{
protected:
    struct Node
    {
        T1 key;
        T2 value;
    };
    std::vector<Node> m_list;

public:
    static bool Compare(const Node& lhs, const T1 key)
    {
        return lhs.key < key;
    }

    void Add(const T1 key, const T2 value)
    {
        Node node = {key, value};
        m_list.push_back(node);
    }

    T2 Find(const T1 key)
    {
        vector<Node>::const_iterator iter = lower_bound(m_list.begin(), m_list.end(), key, NumberMid::Compare);
        if(iter == m_list.end())
            iter = m_list.end() - 1;
        return iter->value;
    }

    T2 FindMid(const T1 key)
    {
        vector<Node>::const_iterator iter = lower_bound(m_list.begin(), m_list.end(), key, NumberMid::Compare);
        if(iter == m_list.end())
            iter = m_list.end() - 1;
        if(iter == m_list.begin())
            return iter->value;
       
        vector<Node>::const_iterator prev = iter-1;
        float diff = iter->key - prev->key;
        float alpha = (key - prev->key) / diff;
        T2 value = (1.0f - alpha)*prev->value + alpha*iter->value;
        return value;
    }
};

#endif

Å×½ºÆ® ¼Ò½º
    NumberMid<float, float> mid;
    mid.Add(3, 10);
    mid.Add(7, 30);
    mid.Add(10, 100);
    mid.Add(20, 0);
    float ret1 = mid.Find(7);
    float ret2 = mid.Find(8);
    float ret3 = mid.Find(15);
    float ret4 = mid.FindMid(11);
    float ret5 = mid.FindMid(5);

    cout << "7: " << ret1 << endl;
    cout << "8: " << ret2 << endl;
    cout << "15: " << ret3 << endl;

    cout << "11: " << ret4 << endl;
    cout << "5: " << ret5 << endl;

°á°ú)
7: 30
8: 100
15: 0
11: 90
5: 20

ÂüÁ¶)
http://blogginman.blogspot.com/2005/09/c-tip-lowerbound-and-functors.html?m=1
https://heisseswasser.hatenadiary.org/entry/20100308/1268043943
https://ohmist.tistory.com/m/2