C++primer第十一章使用类(矢量随机游走实例)
操作符重载
操作符重载(operator overoading)是一种形式的 C++多态。
第8章介绍了C++是如何使用户能够定义多个名称相同但特征标(参数列表)不同的函数的。这被称为函数重载(function overloading)或函数多态(functional polymorphism),旨在让您能够用同名的函数来完成相同的基本操作,即使这种操作被用于不同的数据类型
实际上,很多 C++(也包括C语言)操作符已经被重载。例如,将*操作符用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。C++根据操作数的数目和类型来决定采用哪种操作。
数组加法
op是将要重载的操作符。例如,operator +()重载+操作符,operator*()重载*操作符。op 必须是有效的 C++操作符,不能虚构一个新的符号。例如,不能有 operator@()这样的函数,因为 C++中没有@操作符。
操作符重载范例
mytime0.h
// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:int hours;int minutes;public:Time();Time(int h, int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0, int m = 0);Time Sum(const Time &t) const;void Show() const;
};
#endif
Sum()函数的代码。注意参数是引用,但返回类型却不是引用。将参数声明为引用的目的是为了提高效率。如果按值传递Time 对象,代码的功能将相同,但传递引用,速度将更快,使用的内存将更少。
mytime0.cpp
// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{hours = minutes = 0;
}Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::AddMin(int m)
{minutes += m;hours += minutes / 60;minutes %= 60;
}void Time::AddHr(int h)
{hours += h;
}void Time::Reset(int h, int m)
{hours = h;minutes = m;
}
Time Time::Sum(const Time &t) const
{Time sum;sum.minutes = minutes + t.minutes;sum.hours = hours + t.hours + sum.minutes / 60;sum.minutes %= 60;return sum;
}
void Time::Show() const
{std::cout << hours << " hours. " << minutes << "minutes";
}
usetime0.cpp
#include <iostream>
#include "mytime0.h"
int main()
{using std::cout;using std::endl;Time planning;Time coding(2, 40);Time fixing(5, 55);Time total;cout << "planning time =";planning.Show();cout << endl;cout << "coding time =";coding.Show();cout << endl;cout << "fixing time =";fixing.Show();cout << endl;total = coding.Sum(fixing);cout << "coding.Sum(fixing)=";total.Show();return 0;
}
添加加法操作符
将 Time 类转换为重载的加法操作符很容易,只要将 Sum()的名称改为 operator+()即可。这样做是对的,只要把操作符(这里为+)放到operator的后面,并将结果用作方法名即可。在这里,可以在标识符中使用字母、数字或下划线之外的其他字符。
mytime1.h
// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:int hours;int minutes;public:Time();Time(int h, int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0, int m = 0);// Time Sum(const Time &t) const;Time operator+(const Time &t) const;void Show() const;
};
#endif
mytime1.cpp
// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{hours = minutes = 0;
}Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::AddMin(int m)
{minutes += m;hours += minutes / 60;minutes %= 60;
}void Time::AddHr(int h)
{hours += h;
}void Time::Reset(int h, int m)
{hours = h;minutes = m;
}
Time Time::operator+(const Time &t) const
{Time sum;sum.minutes = minutes + t.minutes;sum.hours = hours + t.hours + sum.minutes / 60;sum.minutes %= 60;return sum;
}
void Time::Show() const
{std::cout << hours << " hours. " << minutes << "minutes";
}
usetime1.cpp
#include <iostream>
#include "mytime0.h"
int main()
{using std::cout;using std::endl;Time planning;Time coding(2, 40);Time fixing(5, 55);Time total;cout << "planning time =";planning.Show();cout << endl;cout << "coding time =";coding.Show();cout << endl;cout << "fixing time =";fixing.Show();cout << endl;total = coding + fixing;cout << "coding + fixing=";total.Show();cout << endl;Time morefixing(3, 28);cout << "more fixing time = ";morefixing.Show();cout << endl;total = morefixing.operator+(total); // function notationcout << "morefixing.operator+(total)=";total.Show();cout << endl;return 0;
}
重载限制
重载的操作符(有些例外情况)不必是成员函数,但必须至少有一个操作数是用户定义的类型
其他重载操作符
时间的减和乘
mytime2.h
// mytime0.h-- Time class before operator overloading
#ifndef MYTIMEO H
#define MYTIMEO H
class Time
{
private:int hours;int minutes;public:Time();Time(int h, int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0, int m = 0);// Time Sum(const Time &t) const;Time operator+(const Time &t) const;Time operator-(const Time &t) const;Time operator*(double n) const;void Show() const;
};
#endif
mytime2.cpp
// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{hours = minutes = 0;
}Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::AddMin(int m)
{minutes += m;hours += minutes / 60;minutes %= 60;
}void Time::AddHr(int h)
{hours += h;
}void Time::Reset(int h, int m)
{hours = h;minutes = m;
}
Time Time::operator+(const Time &t) const
{Time sum;sum.minutes = minutes + t.minutes;sum.hours = hours + t.hours + sum.minutes / 60;sum.minutes %= 60;return sum;
}
Time Time::operator-(const Time &t) const
{Time diff;int tot1, tot2;tot1 = t.minutes + 60 * t.hours;tot2 = minutes + 60 * hours;diff.minutes = (tot2 - tot1) % 60;diff.hours = (tot2 - tot1) / 60;return diff;
}
Time Time::operator*(double mult) const
{Time result;long totalminutes = (minutes + 60 * hours) * mult;result.minutes = totalminutes % 60;result.hours = totalminutes / 60;return result;
}
void Time::Show() const
{std::cout << hours << " hours. " << minutes << "minutes";
}
usetime2.cpp
#include <iostream>
#include "mytime0.h"
int main()
{using std::cout;using std::endl;Time weeding(4, 35);Time waxing(2, 47);Time total;Time diff;Time adjusted;cout << "weeding time =";weeding.Show();cout << endl;cout << "waxing time =";waxing.Show();cout << endl;cout << "total time =";total = weeding + waxing;cout << "coding + fixing=";total.Show();cout << endl;diff = weeding - waxing;cout << "coding - fixing=";diff.Show();cout << endl;adjusted = total * 1.5;cout << "Adjusted work time = ";total.Show();cout << endl;return 0;
}
友元简介
C++控制对类对象私有部分的访问。通常,公有类方法提供惟一的访问途径,但是有时候这种限制太严格,以致上不适合特定的编程问题。在这种情况下,C++提供了另外一种形式的访问权限:
友元。
友元有三种:
介绍如何成为友元之前,先介绍为何需要友元。在为类重载一元操作符时(带两个参数的操作符)常常需要友元。将Time对象乘以实数就属于这种情况
从概念上说,2.75*B应与 B*2.75 相同,但第一个表达式不对应于成员函数,因为 2.75 不是 Time 类型的对象。记住,左侧的操作数应是调用对象,但2.75不是对象。因此,编译器不能使用成员函数调用来替换该表达式。
决这个难题的一种方式是,告知每个人(包括程序员自己),只能按B*2.75 这种格式编写,不能写成 2.75*B。这是一种对服务器友好-客户警惕的(server-ffiendly,client-beware)解决方案,与OOP无关。
(无法直接访问B中的内容)
创建友元
创建友元函数的第是将其原型放在类声明中,并在原型声明前加上关键字friend
第二步是编写函数定义。因为它不是成员函数,所以不要使用Time:限定符。另外,不要在定义中使用关键字 friend,定义应该如下:
常用的友元:重载<<操作符
之所以可以这样做,是因为<<是可被重载的 C++操作符之一
前面讲过,cout 是一个 ostream 对象,它是智能的,能够识别所有的 C++基本类型。这是因为对于每种基本类型,ostream类声明中都包含了相应的重载的 operator<<()定义
因此,要使 cout 能够识别 Time 对象,一种方法是将一个新的函数操作符定义添加到 ostream 类声明中。但修改iostream 文件是个危险的主意,这样做会在标准接口上浪费时间。更好的办法是,通过Time类声明来让 Time 类知道如何使用 cout
<<第一种重载版本
司用 cout<<trip 应使用cout对象本身,而不是它的拷贝,因此该函数按引用(而不是按值)来传递该对象。这样,表达式 cout<<trip 将导致 os 成为 cout 的一个别名;而表达式 cenr <<trip 将导致 os 成为 cen
的一个别名。Time对象可以按值或按引用来传递,因为这两种形式都使函数能够使用对象的值。按引用传递使用的内存和时间都比按值传递少。
<<第二种重载版本
问题:
例如
修改方法
调用os类的引用所以
特别的
头文件
// mytime0.h-- Time class before operator overloading
#ifndef MYTIME0_H_
#define MYTIME0_H_
class Time
{
private:int hours;int minutes;public:Time();Time(int h, int m = 0);void AddMin(int m);void AddHr(int h);void Reset(int h = 0, int m = 0);// Time Sum(const Time &t) const;Time operator+(const Time &t) const;Time operator-(const Time &t) const;Time operator*(double n) const;friend Time operator*(double m, const Time &t){return t * m;} // inline definitionfriend std::ostream &operator<<(std::ostream &os, const Time &t);
};
#endif
其中包括 operator*()和 operator<<()这两个友元函数。它将第-个友元函数作为内联函数,因为其代码很短(当定义同时也是原型时,就像这个例子中那样,要使用 fiend前缀)。
源代码
// mytime0.cpp--implement Time methods
#include <iostream>
#include "mytime0.h"
Time::Time()
{hours = minutes = 0;
}Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::AddMin(int m)
{minutes += m;hours += minutes / 60;minutes %= 60;
}void Time::AddHr(int h)
{hours += h;
}void Time::Reset(int h, int m)
{hours = h;minutes = m;
}
Time Time::operator+(const Time &t) const
{Time sum;sum.minutes = minutes + t.minutes;sum.hours = hours + t.hours + sum.minutes / 60;sum.minutes %= 60;return sum;
}
Time Time::operator-(const Time &t) const
{Time diff;int tot1, tot2;tot1 = t.minutes + 60 * t.hours;tot2 = minutes + 60 * hours;diff.minutes = (tot2 - tot1) % 60;diff.hours = (tot2 - tot1) / 60;return diff;
}
Time Time::operator*(double mult) const
{Time result;long totalminutes = (minutes + 60 * hours) * mult;result.minutes = totalminutes % 60;result.hours = totalminutes / 60;return result;
}
std::ostream &operator<<(std::ostream &os, const Time &t)
{os << t.hours << " hours, " << t.minutes << " minutes";return os;
}
源代码
#include <iostream>
#include "mytime0.h"
int main()
{using std::cout;using std::endl;Time aida(3, 35);Time tosca(2, 48);Time temp;cout << "Aida and Tosca:\n";cout << aida << ";" << tosca << endl;temp = aida + tosca; // operator+()cout << "Aida + Tosca:" << temp << endl;temp = aida * 1.17; // member operator*()cout << "Aida*l.17:" << temp << endl;cout << "10*Tosca:" << 10 * tosca << endl;return 0;
}
重载操作符:作为成员函数还是非成员函数
两种加法操作符
对于两种加法
定义操作符时候只能使用其中一种格式,不然会产生歧义。
重载:矢量类
头文件
// vect.h--Vector class with<<,mode state
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR
{class Vector{private:double x;double y;double mag;char mode;double ang;void set_mag();void set_ang();void set_x();void set_y();public:Vector();Vector(double nl, double n2, char form = 'r');void set(double nl, double n2, char form = 'r');~Vector();double xval() const { return x; } // report x valuedouble yval() const { return y; } // report y valuedouble magval() const { return mag; } // report magnitudedouble angval() const { return ang; } // report anglevoid polar_mode();void rect_mode(); // operator overloadingVector operator+(const Vector &b) const;Vector operator-(const Vector &b) const;Vector operator-() const;Vector operator*(double n) const;friend Vector operator*(double n, const Vector &a);friend std::ostream &operator<<(std::ostream &os, const Vector &v);};} // end namespace VECTOR
#endif
源代码
// vector.cpp --methods for Vector class
#include <cmath>
#include "vector.h"
#include <iostream>
using std::atan2;
using std::cos;
using std::cout;
using std::sin;
namespace VECTOR
{const double Rad_to_deg = 57.2957795130823;// private methods// calculates magnitude from x and yvoid Vector::set_mag(){mag = sqrt(x * x + y * y);}void Vector::set_ang(){if (x == 0.0 && y == 0.0)ang = 0.0;elseang = atan2(y, x);}// set xfrom polar coordinatevoid Vector::set_x(){x = mag * cos(ang);}// set y from polar coordinatevoid Vector::set_y(){y = mag * sin(ang);}// public methodsVector::Vector() // default constructor{x = y = mag = ang = 0.0;mode = 'r';}Vector::Vector(double n1, double n2, char form){mode = form;if (form == 'r'){x = n1;y = n2;set_mag();set_ang();}else if (form == 'p'){mag = n1;ang = n2 / Rad_to_deg;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector()-- ";cout << "vector set to 0\n";x = y = mag = ang = 0.0;mode = 'r';}}// set vector from rectangular coordinates if form is r(the// default)or else from polar coordinates if form is pvoid Vector::set(double n1, double n2, char form){mode = form;if (form == 'r'){x = n1;y = n2;set_mag();set_ang();}else if (form == 'p'){mag = n1;ang = n2 / Rad_to_deg;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector()-- ";cout << "vector set to 0\n";x = y = mag = ang = 0.0;mode = 'r';}}Vector::~Vector(){} // destructorvoid Vector::polar_mode() // set to polar mode{mode = 'p';}void Vector::rect_mode() // set to rectangular mode{mode = 'r';}// operator overloading// add two VectorsVector Vector::operator+(const Vector &b) const{return Vector(x + b.x, y + b.y);}// subtract Vector b from aVector Vector::operator-(const Vector &b) const{return Vector(x - b.x, y - b.y);}// reverse sign of VectorVector Vector::operator-() const{return Vector(-x, -y);}// multiple vector by nVector Vector::operator*(double n) const{return Vector(n * x, n * y);}// friend methods// multiply n byVector aVector operator*(double n, const Vector &a){return a * n;}// display rectangular coordinates if mode is r// else display polar coordinates if mode is pstd::ostream &operator<<(std::ostream &os, const Vector &v){if (v.mode == 'r'){os << "(x,y)=(" << v.x << "," << v.y << ")";}else if (v.mode == 'p'){os << "(m,a)=(" << v.mag << ","<< v.ang * Rad_to_deg << ")";}elseos << "Vector object mode is invalid";return os;}
} // end namespace VECTOR
使用状态成员
状态成员
为Vector类重载操作符
加法
可以使用的加法(无法使用极坐标)
改进
采用的加法(简单)
乘法
友元内联函数来解决乘法交换顺序的问题
对已重载的操作符进行重载
减法(二元操作符)
取反(一元操作符)
模拟随机游走
// randwalk.cpp-…using the Vector class
// compile with the vect.cpp file
#include <iostream>
// rand(),srand()prototypes// time()prototype
#include <cstdlib>
#include <ctime>
#include "vector.h"
int main()
{using namespace std;using VECTOR::Vector;srand(time(0)); // seed random - number generatordouble direction;Vector step;Vector result(0.0, 0.0);unsigned long steps = 0;double target;double dstep;cout << "Enter target distance(q to quit):";while (cin >> target){cout << "Enter step length:";if (!(cin >> dstep))break;while (result.magval() < target){direction = rand() % 360;step.set(dstep, direction, 'p');result = result + step;steps++;}cout << "After " << steps << " steps, the subject"" has the following location : \n ";cout << result << endl;result.polar_mode();cout << " or\n " << result << endl;cout << " Average outward distance per step = "<< result.magval() / steps << endl;steps = 0;result.set(0.0, 0.0);cout << "Enter target distance(qto quit):";}cout << "Bye!\n";return 0;
}
类的自动转换和强制类型转换
内置类型转换
将一个标准类型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,则C++自动将这个值转换为接收变量的类型。
例如
不兼容的类型不能自动转换
但是可以进行强制类型转换
类的转换
可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一种类型是有意义的。
stonewt.h
// stonewt.h --definition forStonewtCass
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:enum{Lbs_per_stn = 14}; // pounds per stoneint stone; // whole stonesdouble pds_left; // fractional poundsdouble pounds; // entire weight in poundspublic:Stonewt(double lbs); // constructor for double poundsStonewt(int stn, double lbs); // constructor for stone,1bsStonewt(); // default constructor~Stonewt();void show_lbs() const;// show weight in pounds formatvoid show_stn() const;// show weight in stone format}
};#endif
源文件
#include <iostream>
using std::cout;
#include "stonewt.h"
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{stone = int(lbs) / Lbs_per_stn; // integer divisionpds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;
}// construct Stonewt obiect from stone,double values
Stonewt::Stonewt(int stn, double lbs)
{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;
}Stonewt::Stonewt() // default constructor,wt=0
{stone = pounds = pds_left = 0;
}Stonewt::~Stonewt()
// destructor
{
}
// show weight in stones
void Stonewt::show_stn() const
{cout<< stone << "stone," << pds_left << "pounds\n";
}
// show weight in pounds
void Stonewt::show_lbs() const
{cout << pounds << "pounds\n";
}
对于函数
接受两个参数的不可以不能作为转换函数
避免意外的类型转换
最新的C++实现新增了一个关键字(explicit),用来关闭这种自动特性。也就是说,可以这样声明构造函数:
但是仍可以进行显示强制类型转换
隐式转换
不发生歧义下,会进行二步转换
下面两条语句都首先将int转换为double,然后使用 Stonewt(double)构造函数。
#include <iostream>
using std::cout;
#include "stonewt.h"
void display(const Stonewt &st, int n);
int main()
{Stonewt pavarotti = 260; // uses constructor to initializeStonewt wolfe(285.7); // same as Stonewt wolfe =285.7Stonewt taft(21.8);cout << "The tenor weighed ";pavarotti.show_stn();cout << "The detective weighed ";wolfe.show_stn();cout << "The President weighed ";taft.show_lbs();pavarotti = 265.8;// uses constructor for conversiontaft = 325; // same as taft= Stonewt(325);cout << "After dinner,the tenor weighed ";pavarotti.show_stn();cout << "After dinner,the President weighed ";taft.show_lbs();display(taft, 2);cout << "The wrestler weighed even more,\n";display(422, 2);cout << "No stone left unearned\n";return 0;
}void display(const Stonewt &st, int n)
{for (int i = 0; i < n; i++){cout << "Wow!";st.show_stn();}
}
二步转换
转换函数
如果定义了转换函数下列就是可行的
转换函数声明
更改上述代码
// stonewt.h --definition forStonewtCass
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:enum{Lbs_per_stn = 14}; // pounds per stoneint stone; // whole stonesdouble pds_left; // fractional poundsdouble pounds; // entire weight in poundspublic:Stonewt(double lbs); // constructor for double poundsStonewt(int stn, double lbs); // constructor for stone,1bsStonewt(); // default constructor~Stonewt();void show_lbs() const;// show weight in pounds formatvoid show_stn() const;// show weight in stone format}// conversion functionsoperator int() const;operator double() const;
};#endif
源文件
#include <iostream>
using std::cout;
#include "stonewt.h"
// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{stone = int(lbs) / Lbs_per_stn; // integer divisionpds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);pounds = lbs;
}// construct Stonewt obiect from stone,double values
Stonewt::Stonewt(int stn, double lbs)
{stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;
}Stonewt::Stonewt() // default constructor,wt=0
{stone = pounds = pds_left = 0;
}Stonewt::~Stonewt()
// destructor
{
}
// show weight in stones
void Stonewt::show_stn() const
{cout<< stone << "stone," << pds_left << "pounds\n";
}
// show weight in pounds
void Stonewt::show_lbs() const
{cout << pounds << "pounds\n";
}Stonewt::operator double() const
{return pounds;
}
Stonewt::operator int() const
{return int(pounds + 0.5);
}
源文件
#include <iostream>
#include "stonewt.h"
int main()
{using std::cout;Stonewt poppins(9, 2.8); // 9 stone,2.8 poundsdouble p_wt = poppins; // implicit conversioncout << "Convert to double =>";cout << "Poppins:" << p_wt << " pounds.\n";cout << "Convert to int =>";cout << "Poppins:" << int(poppins) << " pounds.\n";return 0;
}
最好使用显式转换,而避免隐式转换。关键字 explicit 不能用于转换函数,但只需用一个功能相同的非转换函数替换该转换数即可,但仅在被显式地调用时,该函数才会执行。也就是说,可以将:
转换函数和友元函数
重载加法的两种方式
成员函数
友元函数
下列合理
进行状态转换
只有友元函数允许
原因:
相关文章:

C++primer第十一章使用类(矢量随机游走实例)
操作符重载 操作符重载(operator overoading)是一种形式的 C多态。 第8章介绍了C是如何使用户能够定义多个名称相同但特征标(参数列表)不同的函数的。这被称为函数重载(function overloading)或函数多态(functional polymorphism),旨在让您能够用同名的函数来完成…...

服务器为什么会受到网络攻击?
随着科技的 快速发展,企业也开展了越来越多的线上业务,但同时也遭受到各种各样的网络攻击,那服务器为什么会受到网络攻击呢?下面就让小编带领大家一起来了解一下吧! 首先企业中服务器被攻击的原因有很多,主…...

IDA Pro基本使用
IDA Pro基本使用 1.DllMain的地址是什么? 打开默认在的位置1000D02E就是DllMain地址 按空格键可以看到图形化界面选择options、general勾选对应的选项在图像化也能看到 2.使用Imports 窗口并浏览到 gethostbyname,导入函数定位到什么地址? 这里可以打开Impo…...

Day.js时间插件的安装引用与常用方法大全
🚀 个人简介:某大型国企资深软件研发工程师,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~ 💟 作 者:码喽的自我修养ǹ…...

aws 容器镜像仓库操作
aws 容器镜像仓库产品叫ECR,官方文档参考:Amazon Elastic Container Registry。 1)账号认证 # 配置aws命令 $ aws configure set aws_access_key_id ${ak} $ aws configure set aws_secret_access_key ${sk} 2)镜像仓库登陆 #…...

学习记录:js算法(四十一): 基于时间的键值存储
文章目录 基于时间的键值存储网上思路 总结 基于时间的键值存储 设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。 实现 TimeMap 类: TimeMap() 初始化数据结构对象void se…...

C语言 | Leetcode C语言题解之第424题替换后的最长重复字符
题目: 题解: int characterReplacement(char* s, int k) {int num[26];memset(num, 0, sizeof(num));int n strlen(s);int maxn 0;int left 0, right 0;while (right < n) {num[s[right] - A];maxn fmax(maxn, num[s[right] - A]);if (right - …...

大数据时代的PDF解析:技术与挑战
在大数据时代,海量信息以不同格式存储,其中 PDF 文件凭借其广泛应用成为了各种业务场景下的主要文档格式。无论是政府文件、企业报告,还是学术论文和技术文档,PDF 都是信息交流的重要媒介。然而,随着信息的爆炸式增长&…...

《nmap 命令全解析:网络探测与安全扫描的利器》
文章目录 一、引言二、nmap 命令概述三、nmap 基本用法(一)安装 nmap(二)简单扫描示例 四、nmap 常见参数(一)-sS(TCP SYN 扫描)(二)-sT(TCP 连接…...

2024年华为OD机试真题-斗地主之顺子-Python-OD统一考试(E卷)
最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精选c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,持续跟新。 题目描述 在斗地主只扑克牌游戏中,…...

亲测有效,长期有效的RTSP流地址公网RTSP地址,各种类型的视频源
我们经常需要做一些实时视频流的测试,但是手边又没有办法及时弄到一个摄像机,我们经常会去搜索一下“公网RTSP地址”,但是大部分现在都失效了,有什么办法能够让我们快速构建一个RTSP流,点几下就能直接用? …...

Excel常用函数大全
Excel常用函数介绍与示例应用 在Excel中,函数是进行数据处理和分析的强大工具。对于新手来说,掌握一些基本的函数使用方法能够大大提升工作效率。以下是一份通俗易懂、适合新手的Excel函数使用方法总结: 1. 求和函数(SUM&#x…...

领夹麦克风哪个品牌好,无线领夹麦克风品牌排名,麦克风品牌大全
无线领夹麦克风因其便携性和隐蔽性,越来越受到演讲者和表演者的青睐。但是,随着市场上品牌和型号的增多,质量也变得参差不齐。许多用户在选购时,会因为缺乏了解而选择到性能不佳的产品,影响声音的清晰度和稳定性。下面…...

【C语言零基础入门篇 - 15】:单链表
文章目录 单链表链表的基本概念单链表功能的实现单链表的初始化单链表新结点的创建单链表头插法单链表的输出单链表的查找单链表修改单链表的删除单链表所有数据结点释放源代码 单链表 链表的基本概念 一、什么是链表? 链表是数据结构中线性表的一种,其…...

Linux主流Web服务器:你选择哪一款?
在Linux环境下,选择Web服务器通常取决于特定需求、资源限制、以及对性能的期望。以下是对几款主流Linux Web服务器的详细分析: 1. Apache HTTP Server - 特点:Apache是功能最全面的Web服务器之一,支持模块化架构,拥…...

光耦知识分享:解读晶体管光耦主要性能指标
晶体管光耦是一种常用的光电耦合器,用于隔离和传输电信号,它包含有光电发射管和接收晶体管两个主要部分。解读晶体管光耦的主要指标有助于了解其性能和应用范围,主要指标包括: 最大工作电压(V_R_MAX)&…...

laravel public 目录获取
在Laravel框架中,public目录是用来存放公共资源的,如CSS、JS、图片等。你可以通过多种方式获取public目录的路径。 方法一:使用helper函数public_path() $path public_path(); 方法二:使用Request类 $path Request::root().…...

强化学习策略买卖股票的效果如何?
Github 项目: GitHub - daocodedao/stable-baselines-stock: 深度强化学习自动炒股 主体参考了 https://github.com/wangshub/RL-Stock,修改了一些 requirements 修改到新版本支持 macstable-baselines 改为 stable-baselines3 使用强化学习预测股价…...

Kotlin 基本介绍(一)
导读大纲 1.1.1 Kotlin 是安全的1.1.2 Kotlin 具有互操作性1.1.3 什么是 idiomatic Kotlin? 1.1.1 Kotlin 是安全的 一般来说,当我们说一种编程语言是安全的 我们指的是它的设计可以防止程序中出现某些类型的错误当然,这并不是绝对的;没有一种语言能防止所有可能出现…...

Cocos Creator发布Moloco平台试玩广告(PlayableAd)
官方文档 主要遇到了两点问题。 1.HTML文件内的body需要注入 <script>window.FBPlayableOnCTAClick () > {(typeof FbPlayableAd undefined) ? alert(FBPlayableAd.onCTAClick) : FbPlayableAd.onCTAClick()}</script> 2.跳转商店使用 window.parent.postM…...

七种修复错误:由于找不到msvcr110.dll 无法继续执行的方法
当你在运行某些程序时遇到“找不到msvcr110.dll”的错误提示,这通常意味着你的系统缺少了Microsoft Visual C 2012 Redistributable包中的一个重要文件。这个DLL文件是Microsoft Visual C Redistributable的一部分,用于支持许多使用Visual C编写的软件和…...

Python模拟鼠标轨迹[Python]
一.鼠标轨迹模拟简介 传统的鼠标轨迹模拟依赖于简单的数学模型,如直线或曲线路径。然而,这种方法难以捕捉到人类操作的复杂性和多样性。AI大模型的出现,能够通过深度学习技术,学习并模拟更自然的鼠标移动行为。 二.鼠标轨迹算法实…...

Ubuntu搭建java开发环境
一:Ubuntu安装 1、下载Ubuntu 24.04.1 LTS 官网下载地址:https://releases.ubuntu.com/24.04.1/ubuntu-24.04.1-desktop-amd64.iso 可以直接点击这里下载 2、使用VMware安装 新建虚拟机 之后一直下一步,到如下界面,选择 刚刚…...

新能源汽车知识点集萃
功能安全-->ISO26262/GB∕T 34590 2021 信息安全--->ISO21434 预期功能安全--->ISO21448 建模规范-->MAAB/JMAAB/MISAR C Codeing Standard; 开发流程--CMMI/IATF16949//ASPICE(Automotive SPICE)/产品规划/概念开发/设计开发/试制试验与…...

c++234继承
#include<iostream> using namespace std;//public 修饰的成员便俩个和方法都能使用 //protected:类的内部 在继承的子类中可使用 class Parents { public:int a;//名字 protected:int b;//密码 private:int c;//情人public:void printT(){cout << &quo…...

Axios 封装网络请求
1 简介 通过Axios的请求拦截器和响应拦截器实现登录拦截,参数封装。 注意:前提是你的vue已经安装了Axios。 附安装代码: npm install axios 2 封装代码 2.1 utils文件夹下创建 request.js // 网络请求方法 import axios from axios impor…...

LeetCode 面试经典150题 190.颠倒二进制位
复习知识:正数的原码、反码、补码相同,负数的反码在其原码的基础上, 符号位不变,其余各个位取反,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后1 (即在反码的基础上1)。 题目:颠倒给定的 32 位无符号…...

vulhub搭建漏洞环境docker-compose up -d命令执行报错以及解决方法汇总
在利用vulhub靶场搭建环境进行漏洞复现时,我们通常要使用这一步命令: docker-compose up -d 但是经常报错,今天我们来说几个常见的报错以及解决方法: 1.报错提示: ERROR: Couldnt connect to Docker daemon at httpdoc…...

C++ 简介
目录 面向对象程序设计 标准库 ANSI 标准 学习 C C 的使用 标准化 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程。 C 被认为是一种中级语言,它综合了高级语言和低级语言的特点…...

shardingjdbc分库分表原理
一 Mysql的瓶颈 二 解决方案 三 hash环算法 四 雪花算法...