C++
1,手写重新实现String类,实现自己用过的功能
2,用C++实现NMS算法
3,lambda表达式
4,虚函数和纯虚函数
5,向量点乘和向量叉乘
自己使用C++实现一个String类
常见功能:普通构造函数,拷贝构造函数,析构函数,运算符“+”重载,运算符“=”重载,字符串“==”重载,获取字符串长度,获取制定字符在字符串中位置
#include <iostream>
#include <string.h>
class StringLcg
{
public:
StringLcg(const char* str = NULL);//普通构造函数
StringLcg(const StringLcg& str);//拷贝构造函数
~StringLcg(void);//析构函数
StringLcg& operator=(const StringLcg& str);//重载 =
StringLcg operator+(const StringLcg& str);//重载 +
bool operator==(const StringLcg& str);//重载 ==
int getLenth();//获取字符串长度
int index(char c);//判断字符在字符串中位置
private:
char* data;
};
StringLcg::StringLcg(const char *str)
{
if(str == NULL)
{
this->data = NULL;
}
else
{
this->data = new char[strlen(str) + 1];
strcpy(this->data,str);
}
}
//拷贝构造函数
StringLcg::StringLcg(const StringLcg &str)
{
if(str.data == NULL)
{
this->data = NULL;
}
else
{
this->data = new char[strlen(str.data) + 1];
strcpy(this->data,str.data);
}
}
//析构函数
StringLcg::~StringLcg()
{
if(this->data)
{
delete[] this->data;
this->data = NULL;
}
}
//操作符= 重载
StringLcg& StringLcg::operator =(const StringLcg& str)
{
if(this != &str)
{
delete[] this->data;
this->data = NULL;
if(str.data != NULL)
{
this->data = new char[strlen(str.data) + 1];
this->data = str.data;
}
else
{
this->data = NULL;
}
}
return *this;
}
//操作符+ 重载
StringLcg StringLcg::operator +(const StringLcg& str)
{
StringLcg newString;
if(str.data != NULL)
{
if(this->data != NULL)
{
newString.data = new char[strlen(str.data) + strlen(this->data) + 1];
strcpy(newString.data,this->data);
strcat(newString.data,str.data);
}
else
{
newString = str;
}
}
else
{
return *this;
}
}
//操作符== 重载
bool StringLcg::operator ==(const StringLcg& str)
{
if(strlen(this->data) != strlen(str.data))
{
return false;
}
else
{
return strcmp(this->data,str.data);
}
}
//获取字符串长度
int StringLcg::getLenth()
{
if(this->data == NULL)
return 0;
else
{
return (strlen(this->data));
}
}
用c++实现NMS算法
遇到现场要求手撸代码的需求,先在纸上整理自己思维逻辑,将逻辑整理清楚之后再开始写代码。
不然一边想一边写,会漏洞百出
/*nms的核心思想是将所有的检测框,通过计算iou来排除掉,对比的基础是score
* 所以先按照score对所有的box进行一个排序,然后再组织循环,使得两两做比较,
* 比较iou的值,如果大于设置的阈值,则丢弃不要,剩下的都是可以使用的box了
*/
typedef struct Bbox
{
int x,
int y,
int w,
int h;
float score;
}Bbox;
//比较函数,降序排列
bool cmpScore(Bbox l,Bbox r)
{
return (l.score > r.score)
}
//计算IOU
float iou(Bbox a,Bbox b)
{
int x1 = std::max(a.x,b.x);
int y1 = std::max(a.y,b.y);
int x2 = std::min(a.x + a.w,b.x + b.w);
int y2 = std::min(a.y + a.h,b.y + b.h);
int w = std::max(0,(x2 - x1 + 1));
int h = std::max(0,(y2 - y1 + 1));
double inter = w * h;
double value = inter / (a.w * a.h + b.w * b.h - inter);
}
void nms(vector<Bbox> &boundingBox,const float threshold)
{
if(boundingBox.empty())
return;
//先根据score对所有的boundingBox进行排序
sort(boundingBox.begin(),boundingBox.end(),cmpScore)
int boxNum = boundingBox.size();
vector<int> del(boxNum,false);
for(int i = 0;i < boxNum;i++)
{
for(int j = i + 1;j < boxNum;j++)
{
if(iou(boundingBox.at(i),boundingBox.at(j)) > threshold)
{
del[j] = true;
}
}
}
vector<Bbox> results;
for(int i = 0;i < del.size();i ++)
{
if(del[i] == false)
results.pushback(boundingBox[i])
}
boundingBox = results;
}
虚函数
C++虚函数的主要作用是”运行时多态”,父类中提供虚函数的实现,为子类提供默认的函数实现,子类可以重写父类的虚函数实现子类的特殊化
纯虚函数
C++中包含纯虚函数的类,被称为“抽象类”,抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象
向量点乘
公式:a * b = |a| * |b| * cosθ
点乘又叫向量的内积、数量积,是一个向量和它在另一个向量上的投影的长度的乘积;是标量。
点乘反映着两个向量的“相似度”,两个向量越“相似”,它们的点乘越大。
opencv中对应 Mat.dot()操作
向量叉乘
公式:a ∧ b = |a| * |b| * sinθ
两向量叉乘的结果为一个向量,其模长的绝对值为两向量组成的平行四边形的面积,其方向为两相乘向量的垂直方向。方向遵循右手定则。