1、STL算法里的find和find_if算法的使用:
区别于联系:联系:这个两个函数都是查找某个元素位置的方式;区别:其中find值适用于查找其里面元素值的位置。而find_if值使用与函数第三个参数的为判别式时的使用。
template
InputIterator find ( InputIterator first, InputIterator last, const T& value )
{
for ( ;first!=last; first++) if ( *first==value ) break;
return first;
}
返回区间[first,end)中第一个值等于value的元素的位置。
如果没有找到匹配元素,则返回end。
复杂度:线性复杂度。最多比较次数是:元素的总个数。
程序实例:
下面的程序在int类型的vector中搜寻元素5和12,如果搜索到,就返回其位置if欧泽输出提示信息。
main.cpp(头文件algostuff.h和上一篇博客中的相同):
#include "algostuff.h"
using namespace std;
int main()
{
vector intVec;
INSERT_ELEMENTS(intVec,1,9);
vector::iterator pos;
pos = find(intVec.begin(),intVec.end(),5);
if(pos != intVec.end())
cout << "The value 5 exists,and its position is " <<
distance(intVec.begin(),pos) + 1 << endl;
else
cout << "The value 4 not found!" << endl;
pos = find(intVec.begin(),intVec.end(),12);
if(pos != intVec.end())
cout << "The value 12 exists,and its position is " <<
distance(intVec.begin(),pos) + 1 << endl;
else
cout << "The value 12 not found!" << endl;
}
运行结果(头文件algostuff.h和上一篇博客中的相同):
二、find_if()算法
template
InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
{
for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
return first;
}
它在区间[first,end)中搜寻使一元判断式pred为true的第一个元素。
如果没找到,返回end。
程序实例:
下面程序找出第一个能够被3整除的元素,如果找到返回其位置。
main.cpp:
#include "algostuff.h"
using namespace std;
int main()
{
vector intVec;
INSERT_ELEMENTS(intVec,1,9);
vector::iterator pos;
pos = find_if(intVec.begin(),intVec.end(),
not1(bind2nd(modulus(),3)));
if(pos != intVec.end())
cout << "The value divided by 3 exists,and the first value's position is " <<
distance(intVec.begin(),pos) + 1 << endl;
else
cout << "The value divided by 3 not found!" << endl;
}
运行结果:
还有一个使用例子就是:
// add old tracked objects
for (auto &i : old_result_vec) {
auto it = std::find_if(result_vec.begin(), result_vec.end(),
[&i](bbox_t const& b) { return b.track_id == i.track_id && b.obj_id == i.obj_id; });
//如果是等于迭代器的end(),则表明没有找到。
bool track_id_absent = (it == result_vec.end());
if (track_id_absent) {
//这里的-->就是大于或等于的比较符,这里是旧的帧目标也加到检测结果里
if (i.frames_counter-- > 1)
result_vec.push_back(i);
}
else {
//每个box都有存储被跟踪帧计数,最多是3帧
it->frames_counter = std::min((unsigned)3, i.frames_counter + 1);
}
}
2、新的计时方法std::chrono
其比clock计时准确跟方便。代码:
#include
using namespace std;
using namespace chrono;
auto start = system_clock::now();
// do something...
auto end = system_clock::now();
auto duration = duration_cast(end - start);
cout << "花费了"
<< double(duration.count()) * microseconds::period::num / microseconds::period::den
<< "秒" << endl;
另一个代码例子:
if (!cur_frame.empty()) {
steady_end = std::chrono::steady_clock::now();
//if (std::chrono::duration(steady_end - steady_start).count() >= 1) {
if (std::chrono::duration(steady_end - steady_start).count() >= 1) {
current_det_fps = fps_det_counter;
current_cap_fps = fps_cap_counter;
steady_start = steady_end;
fps_det_counter = 0;
fps_cap_counter = 0;
}
3、其中std::unique_lock与std::lock_guard区别及多线程应用实例
C++多线程编程中通常会对共享的数据进行写保护,以防止多线程对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为(不过这个自己通过很多实验都没有重现这个资源未定义的错误)。通常的做法就是修改共享数据的的时候回进行加锁--mutex。在使用锁的时候通常是在对共享数据进行修改之前进行lock操作。在写完之后再进行unlock操作,如果由于lock之后而忘记unkock。则会导致死锁。
为此C++11中引入里std::unique_lock与std::lock_guard两种数据结构。通过对lock和unlock进行一次博的封装自动实现unlock的功能。
其中为什么需要使用锁这个概念,主要是为了让某个线程一起等待某个条件,只有当某个条件具备时,等待线程才被唤醒。其主要是为了多个线程直接进行协作。
其中锁住的方式有两种:一个是直接使用wait()来进行线程锁住。另一个是使用while跟wait()来进行锁住。其如下:
while (!pred()) wait(lck);
例子:
#include // std::cout
#include // std::thread
#include // std::mutex, std::unique_lock
#include // std::condition_variable
std::mutex mtx; // 全局互斥锁.
std::condition_variable cv; // 全局条件变量.
bool ready = false; // 全局标志位.
void do_print_id(int id)
{
std::unique_lock lck(mtx);
while (!ready) // 如果标志位不为 true, 则等待...
cv.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后,
// 线程被唤醒, 继续往下执行打印线程编号id.
std::cout << "thread " << id << '\n';
}
void go()
{
std::unique_lock lck(mtx);
ready = true; // 设置全局标志位为 true.
cv.notify_all(); // 唤醒所有线程.
}
int main()
{
std::thread threads[10];
// spawn 10 threads:
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(do_print_id, i);
std::cout << "10 threads ready to race...\n";
go(); // go!
for (auto & th : threads)
th.join();
return 0;
}
另一个是:
#include // std::cout
#include // std::thread, std::this_thread::yield
#include // std::mutex, std::unique_lock
#include // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
int cargo = 0;
bool shipment_available()
{
return cargo != 0;
}
// 消费者线程.
void consume(int n)
{
for (int i = 0; i < n; ++i)
{
std::unique_lock lck(mtx);
cv.wait(lck, shipment_available); 这里的结构相当于while(!shipment_available){cv.wait()},要加个条件判断
std::cout << cargo << '\n';
cargo = 0;
}
}
int main()
{
std::thread consumer_thread(consume, 10); // 消费者线程.创建一个线程并传入一个10的参数,
// 主线程为生产者线程, 生产 10 个物品.其是下面的代码就是控制子线程的执行,当调用notif_one()后子线程就执行for里的一次代码
for (int i = 0; i < 10; ++i)
{
while (shipment_available()) //这里是等待子线程wait()后面的代码执行完即cargo被置为0即表示运行完一次for里的代码。
{
std::this_thread::yield(); //这里是进行一下延时。
}
std::unique_lock lck(mtx);
cargo = i + 1;
cv.notify_one(); //这里对wait进行解锁一次。
}
consumer_thread.join();
return 0;
}
4、for的在c++11后新增的类型lambda的的用法:
// 第三种用法:简化数组遍历语法(从vs2008开始支持)
for each(auto item in vecNum)
{
strText.Format("%d", item);
AfxMessageBox(strText);
}
// 第四种用法:STL函数
std::for_each(vecNum.begin(), vecNum.end(), [](int item){
CString strText;
strText.Format("%d", item);
AfxMessageBox(strText);
});
// 第五种用法:C++11新增加的(VS2012支持)
for(auto item : vecNum)
{
strText.Format("%d", item);
AfxMessageBox(strText);
}
5、在vector里判断某个元素是否存在方法;
vector vStr;
vStr.pushback("hh");
int nRet = std::count(vStr.begin(), vStr.end(), "xiaochun");//判断vector中是否有 "xiaochun" 这个元素
处理上面的方法,还可以使用上面的find函数。
6、判断map变量里的某个元素是否存在:
1.判断某元素是否存在
map mapDemo;
bool bRet = mapDemo.count(100);//判断mapDemo中是否有 key = 100 的元素
2.查找某个元素
map::iterator iter = mapDemo.find(100);
if (iter != m_Int.end())
{
//找到了
}
else
{
//没找到
}