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


在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 <iostream>
#include <thread>
#include <algorithm>
#include <vector>

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 <iostream>
#include <vector>
#include <algorithm>
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 <iostream>
#include <vector>
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 <algorithm>
#include <iostream>
#include <vector>
 
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 <algorithm>
#include <iostream>
#include <vector>

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
*/
### 回答1: 要实现C++的登录注册功能,你需要以下步骤: 1.创建一个用户类,其中包含用户名和密码等信息。 2.创建一个用户管理类,用于管理所有用户,包括添加、删除、查找和验证用户等功能。 3.在主函数中实现登录和注册功能,包括输入用户名和密码、验证用户信息等。 下面是一个简单的C++登录注册功能实现示例: ``` #include <iostream> #include <string> #include <vector> using namespace std; // 用户类 class User { public: User(string name, string password) { this->name = name; this->password = password; } string getName() { return name; } string getPassword() { return password; } private: string name; string password; }; // 用户管理类 class UserManager { public: UserManager() { users.push_back(User("admin", "admin")); // 默认添加一个管理员账号 } // 添加用户 void addUser(User user) { users.push_back(user); } // 删除用户 void deleteUser(string name) { for (int i = 0; i < users.size(); i++) { if (users[i].getName() == name) { users.erase(users.begin() + i); break; } } } // 查找用户 User* findUser(string name) { for (int i = 0; i < users.size(); i++) { if (users[i].getName() == name) { return &users[i]; } } return NULL; } // 验证用户 bool validateUser(string name, string password) { User* user = findUser(name); if (user != NULL && user->getPassword() == password) { return true; } return false; } private: vector<User> users; }; int main() { UserManager userManager; while (true) { cout << "请选择功能:" << endl; cout << "1.登录" << endl; cout << "2.注册" << endl; cout << "3.退出" << endl; int choice; cin >> choice; if (choice == 1) { string name, password; cout << "请输入用户名和密码:" << endl; cin >> name >> password; if (userManager.validateUser(name, password)) { cout << "登录成功!" << endl; } else { cout << "用户名或密码错误!" << endl; } } else if (choice == 2) { string name, password; cout << "请输入用户名和密码:" << endl; cin >> name >> password; User* user = userManager.findUser(name); if (user != NULL) { cout << "该用户名已存在!" << endl; } else { userManager.addUser(User(name, password)); cout << "注册成功!" << endl; } } else if (choice == 3) { break; } else { cout << "输入错误!请重新输入。" << endl; } } return 0; } ``` 在这个示例中,我们通过创建用户类和用户管理类实现了登录和注册功能。主函数中使用 `while` 循环实现了菜单选择功能,用户可以选择登录、注册或退出。在登录和注册过程中,我们使用 `userManager` 对象来管理所有用户,并使用其提供的方法来验证用户和添加新用户。 ### 回答2: 实现C的登录注册功能可以有多种方法,以下是一种常见的实现方式。 用户注册功能: 1. 前端页面中,用户输入注册信息,包括用户名、密码等,并点击注册按钮。 2. 后端接收到注册请求后,首先需要验证输入的注册信息是否符合要求,如用户名是否已存在、密码是否符合安全要求等。 3. 如果验证通过,将用户输入的注册信息存储在数据库中,包括用户名和密码。 4. 注册成功后,返回给前端注册成功的提示信息,可以要求用户直接登录或返回首页。 用户登录功能: 1. 前端页面中,用户输入登录信息,包括用户名和密码,并点击登录按钮。 2. 后端接收到登录请求后,首先需要验证输入的登录信息是否正确,即与数据库中的用户信息进行比对。 3. 如果验证通过,生成一个登录凭证(如session id或token),并将该凭证存储在服务器端的session中或传递给前端。 4. 登录成功后,返回给前端登录成功的提示信息,可以跳转到用户个人主页或其他页面。 5. 如果验证不通过,返回给前端登录失败的提示信息,要求用户重新输入正确的登录信息。 登录状态的保持: 1. 可以通过在前端或后端设置Cookie或localStorage等机制,保存登录凭证的信息。 2. 用户下次打开网页时,前端从Cookie或localStorage等中读取登录凭证,发送给后端验证。 3. 如果凭证有效,则用户无需再输入登录信息,可以直接进入登录状态;如果凭证无效或过期,则要求用户重新登录。 以上是一个简单的登录注册功能的实现过程,具体的实现方式可能会因技术栈、项目需求和安全性要求等不同而有所差异。 ### 回答3: C登录注册功能的实现主要包括以下几个步骤: 1. 前端界面设计:首先要设计一个用户友好的前端界面,包括登录页面和注册页面。登录页面需要包含用户名和密码的输入框,以及登录按钮;注册页面需要包含用户名、密码、确认密码和注册按钮。 2. 数据库设计:为了存储用户的信息,需要设计一个数据库表格来存储用户的用户名和密码。可以使用关系型数据库如MySQL或非关系型数据库如MongoDB来存储用户信息。 3. 后端代码编写:后端代码负责处理用户输入的登录和注册信息,并将其与数据库中的数据进行比对。 4. 登录功能实现:当用户在登录页面输入用户名和密码并点击登录按钮时,前端将用户输入的信息发送给后端。后端根据用户输入的用户名在数据库中查找对应的记录,并将数据库中存储的密码与用户输入的密码进行比对。如果密码匹配,则登录成功,否则登录失败。 5. 注册功能实现:当用户在注册页面输入用户名、密码和确认密码并点击注册按钮时,前端将用户输入的信息发送给后端。后端首先检查用户名是否已经存在于数据库中,如果存在,则返回错误提示信息;如果不存在,并且两次输入的密码一致,则将用户输入的用户名和密码存储到数据库中,并返回注册成功提示信息。 6. 错误处理和验证:在登录和注册过程中,需要进行错误处理和验证。例如,在前端可以通过正则表达式对用户名和密码进行格式验证,确保输入的合法性;在后端可以通过异常处理机制对数据库操作的异常进行捕获和处理,确保系统的稳定性和安全性。 综上所述,C登录注册功能的实现需要前后端协同工作,并且需要设计数据库来存储用户信息,并进行合理的验证和错误处理。只有用户输入的用户名和密码与数据库中的记录匹配,才能实现登录功能;只有用户输入的用户名在数据库中不存在,并且两次输入的密码一致,才能实现注册功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ystraw_ah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值