【c++】 vector 查找/二分查找/查找Pair

文章目录

  • 1. find()
  • 2. 二分查找(lower_bound)
  • 3. 查找Pair
  • 4.实现二分
    • low_bound
    • 二分查找
  • 5.stl的二分
    • lower_bound和upper_bound

在vector中查找元素方法很多,比较简单的是利用标准库中提供的方法来查找。
对vector中的pair进行多次find操作

1. find()

std::vector<int>::iterator iter=find(_adjlists.begin(), _adjlists.end(), v);
if(iter == _adjlists.end()){ 
	// 没查到
}
else{
	// 找到了
}

2. 二分查找(lower_bound)

C++标准库里的二分查找算法剖析
对于需要多次查询,为了提高查询效率,可以考虑先排序,然后使用二分查找。
lower_bound返回的是[v.begin(), v.end()]中第一个大于或等于查找值的迭代器,所以我们需要额外判断元素是否找到且真的相等。
直接看例子:

#include 
#include 
#include 
#include 

int main()
{
    std::vector<int> vec;
    for(int i = 10; i > 0; i--)
        vec.push_back(i);
    for(int i : vec){
        std::cout << i << " ";
    }
    std::cout << std::endl;
    std::sort(vec.begin(), vec.end());
    for(int i : vec){
        std::cout << i << " ";
    }
    std::cout << std::endl;

    auto first = std::lower_bound(vec.begin(), vec.end(), 2);
    if(!(first == vec.end()) && (*first == 2)){
        std::cout << "find:" << *first << std::endl;
    }
    else{
        std::cout << "no find." << std::endl;
    }

    first = std::lower_bound(vec.begin(), vec.end(), 0);
    if(!(first == vec.end()) && (*first == 0)){
        std::cout << "find:" << *first << std::endl;
    }
    else{
        std::cout << "no find." << std::endl;
    }

    first = std::lower_bound(vec.begin(), vec.end(), 11);
    if(!(first == vec.end()) && (*first == 11)){
        std::cout << "find:" << *first << std::endl;
    }
    else{
        std::cout << "no find." << std::endl;
    }
}

运行结果:

10 9 8 7 6 5 4 3 2 1 
1 2 3 4 5 6 7 8 9 10 
find:2
no find.
no find.

3. 查找Pair

如果vector中的元素时Pair<>时,可以参考下面的例子:

#include 
#include 
#include 
using namespace std;

// Functor
template<class vertex_t, class value_t>
class isEqualALL {
public:
    explicit isEqualALL(vertex_t node) : node(node) {}
    bool operator() (const std::pair<vertex_t, value_t>& element) const {
        return element.first == node;
    }
private:
    const vertex_t node;
};

int main(void)
{

    vector<pair<int, int>> sortList;
    sortList = {
        pair<int, int>(1, 100),
        pair<int, int>(2, 200),
        pair<int, int>(3, 300),
        pair<int, int>(4, 400),
    };

    auto it = std::find_if( sortList.begin(), sortList.end(), isEqualALL<int, int>(2));

    if (it != sortList.end()) {
        cout << it->first << " " << it->second << endl;
    }

    return 0;
}

运行结果

2 200

4.实现二分

low_bound

找出第一个目标值。

#include 
#include 
using namespace std; 
// lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。
// 也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一
// 定是和目标值相等的元素,还可能是比目标值大的元素。
// 如果找到,则返回下标,否则返回-1
int myLowerBound(vector<int> &data, int k)
{
	int start = 0;
	int last = data.size();
	while (start < last) {
		int mid = (start + last) / 2;
		if (data[mid] >= k) {
			last = mid;
		} else {
			start = mid + 1;
		}
	}
    std::cout << "find data=" << data[start] << std::endl;
    if (data[start] == k) {
        return start;
    }
	return -1;
}


int main() {
    vector<int> a = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 6, 6};

    for (int i = 0; i <= 5; i++) {
        int rt = myLowerBound(a, i);
        std::cout << "  index=" << rt
        << " k=" << i << " rt=" << a[i] << std::endl;
    }

    return 0;
}

二分查找

从 [ left , right ] 中找出唯一的目标值。

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = (right - left) / 2 + left; //避免整数溢出:使用 (right - left) / 2 的形式可以避免整数溢出的问题。如果使用 (right + left) / 2 的形式,当 right 和 left 值非常大时,相加可能会导致整数溢出。
            int num = nums[mid];
            if (num == target) {
                return mid;
            } else if (num > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/binary-search/solution/er-fen-cha-zhao-by-leetcode-solution-f0xw/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5.stl的二分

详细介绍:https://en.cppreference.com/w/cpp/algorithm/lower_bound

#include 
#include 
#include 
 
struct PriceInfo { double price; };
 
int main()
{
    const std::vector<int> data {1, 2, 4, 5, 5, 6};
 
    for (int i = 0; i < 8; ++i)
    {
        // Search for first element x such that i ≤ x
        auto lower = std::lower_bound(data.begin(), data.end(), i);
 
        std::cout << i << " ≤ ";
        lower != data.end()
            ? std::cout << *lower << " at index " << std::distance(data.begin(), lower)
            : std::cout << "not found";
        std::cout << '\n';
    }
 
    std::vector<PriceInfo> prices {{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
 
    for (double to_find : {102.5, 110.2})
    {
        auto prc_info = std::lower_bound(prices.begin(), prices.end(), to_find,
            [](const PriceInfo& info, double value)
            {
                return info.price < value;
            });
 
        prc_info != prices.end()
            ? std::cout << prc_info->price << " at index " << prc_info - prices.begin()
            : std::cout << to_find << " not found";
        std::cout << '\n';
    }
}

lower_bound和upper_bound

#include 
#include 
#include 

struct PriceInfo { 
    int minKey;
    int maxKey; 
};

int main()
{
    const std::vector<int> data {1, 2, 4, 5, 5, 6};
 
    for (int i = 0; i < 7; ++i)
    {
        // Search first element that is greater than i
        auto upper = std::upper_bound(data.begin(), data.end(), i);
 
        std::cout << i << " < ";
        upper != data.end()
            ? std::cout << *upper << " at index " << std::distance(data.begin(), upper)
            : std::cout << "not found";
        std::cout << '\n';
    }
 
    std::vector<PriceInfo> prices {{0,2}, {3,5}, {5,5}, {5,6}, {6,7}};
 
    for (double to_find : {3, 5, 4})
    {
        auto prc_info = std::upper_bound(prices.begin(), prices.end(), to_find,
            [](double value, const PriceInfo& info)
            {
                return value < info.maxKey;
            });
        
        std::cout << "prc_info=" << prc_info->maxKey 
                  << " at index " << prc_info - prices.begin() 
                  << std::endl;
    }

    std::cout << "----" << std::endl;

        for (double to_find : {3, 5, 4})
    {
        auto prc_info = std::lower_bound(prices.begin(), prices.end(), to_find,
            [](const PriceInfo& info, double value)
            {
                return info.maxKey < value;
            });
        
        std::cout << "prc_info=" << prc_info->maxKey 
                  << " at index " << prc_info - prices.begin() 
                  << std::endl;
    }
}

/*
output:
0 < 1 at index 0
1 < 2 at index 1
2 < 4 at index 2
3 < 4 at index 2
4 < 5 at index 3
5 < 6 at index 5
6 < not found
prc_info=5 at index 1
prc_info=6 at index 3
prc_info=5 at index 1
----
prc_info=5 at index 1
prc_info=5 at index 1
prc_info=5 at index 1
*/

你可能感兴趣的:(c/c++,c++,算法,开发语言)