c++学习笔记(5)

devtools/2024/11/9 16:45:40/

151、模板类的示例-栈
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// typedef string DataType; // 定义栈元素的数据类型。
template <class DataType>
class Stack // 栈类
{
private:
DataType* items; // 栈数组。
int stacksize; // 栈实际的大小。
int top; // 栈顶指针。
public:
// 构造函数:1)分配栈数组内存;2)把栈顶指针初始化为 0。
Stack(int size) :stacksize(size), top(0) {
items = new DataType[stacksize];
}~Stack() {
delete [] items; items = nullptr;
}
bool isempty() const { // 判断栈是否为空。
return top == 0;
}
bool isfull() const { // 判断栈是否已满。
return top == stacksize;
}
bool push(const DataType& item) { // 元素入栈。
if (top < stacksize) { items[top++] = item; return true; }
return false;
}
bool pop(DataType& item) { // 元素出栈。
if (top > 0) { item = items[--top]; return true; }
return false;
}
};
int main()
{
Stack<string> ss(5); // 创建栈对象,大小是 5。
// 元素入栈。
// ss.push(1); ss.push(2); ss.push(3); ss.push(4); ss.push(5);
ss.push("西施"); ss.push("冰冰"); ss.push("幂幂"); ss.push("金莲");
// 元素出栈。
string item;
while (ss.isempty() == false)
{
ss.pop(item); cout << "item = " << item << endl;
}
}
152、模板类的示例-数组
类模板可以有非通用类型参数:1)通常是整型(C++20 标准可以用其它的类型);2)实例化模板
时必须用常量表达式;3)模板中不能修改参数的值;4)可以为非通用类型参数提供默认值。
优点:在栈上分配内存,易维护,执行速度快,合适小型数组。
缺点:在程序中,不同的非通用类型参数将导致编译器生成不同的类。
构造函数的方法更通用,因为数据的大小是类的成员(而不是硬编码),可以创建数组大小可变的类。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template <class T,int len=10>
class Array
{
private:
T items[len]; // 数组元素。
public:
Array() {} // 默认构造函数。
~Array() {} // 析构函数
T& operator[](int ii) { return items[ii]; } // 重载操作符[],可以修改数组中的元素。
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
template <class T>
class Vector
{
private:
int len; // 数组元素的个数。
T* items; // 数组元素。
public:
// 默认构造函数,分配内存。
Vector(int size=10):len(size) {
items = new T[len];
}~Vector() { // 析构函数
delete[] items; items = nullptr;
}
void resize(int size) { // 护展数组的内存空间。
if (size <= len) return; // 只能往更大扩展。
T* tmp = new T[size]; // 分配更大的内存空间。
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii]; // 把原来数组中的元素复制到新数组。
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
int size() const { return len; } // 获取数组长度。
T& operator[](int ii) { // 重载操作符[],可以修改数组中的元素。
if (ii >= len) resize(ii + 1); // 扩展数组。
return items[ii];
}
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
int main()
{
// Array<string,10> aa; // 创建模板类 Array 的对象。
Vector<int> aa(1); // 创建模板类 Vector 的对象。
aa[0] = 5; aa[1] = 8; aa[2] = 3; aa[3] = 2; aa[4] = 7;
// aa[0] = "西施"; aa[1] = "冰冰"; aa[2] = "幂幂"; aa[3] = "金莲"; aa[4] = "小乔";
for (int ii=0; ii<5;ii++) cout << "aa[" << ii << "]=" << aa[ii] << endl;
}
153、嵌套和递归使用模板类
在 C++11 之前,嵌套使用模板类的时候,> >之间要加空格。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template <class DataType>
class Stack // 栈类
{
private:
DataType* items; // 栈数组。
int stacksize; // 栈实际的大小。
int top; // 栈顶指针。
public:
// 构造函数:1)分配栈数组内存;2)把栈顶指针初始化为 0。
Stack(int size = 3) :stacksize(size), top(0) {
items = new DataType[stacksize];
}~Stack() {
delete[] items; items = nullptr;
}
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
delete[] items; // 释放原内存。
stacksize = v.stacksize; // 栈实际的大小。
items = new DataType[stacksize]; // 重新分配数组。
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
top = v.top; // 栈顶指针。
return *this;
}
bool isempty() const { // 判断栈是否为空。
return top == 0;
}
bool isfull() const { // 判断栈是否已满。
return top == stacksize;
}
bool push(const DataType& item) { // 元素入栈。
if (top < stacksize) { items[top++] = item; return true; }
return false;
}
bool pop(DataType& item) { // 元素出栈。
if (top > 0) { item = items[--top]; return true; }
return false;
}
};
template <class T>
class Vector // 动态数组。
{
private:
int len; // 数组元素的个数。
T* items; // 数组元素。
public:
// 默认构造函数,分配内存。
Vector(int size = 2) :len(size) {
items = new T[len];
}~Vector() { // 析构函数
delete[] items; items = nullptr;
}
Vector& operator=(const Vector& v) // 重载赋值运算符函数,实现深拷贝。
{
delete[] items; // 释放原内存。
len = v.len; // 数组实际的大小。
items = new T[len]; // 重新分配数组。
for (int ii = 0; ii < len; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
return *this;
}
void resize(int size) { // 护展数组的内存空间。
if (size <= len) return; // 只能往更大扩展。
T* tmp = new T[size]; // 分配更大的内存空间。
for (int ii = 0; ii < len; ii++) tmp[ii] = items[ii]; // 把原来数组中的元素复制到新数组。
delete[] items; // 释放原来的数组。
items = tmp; // 让数组指针指向新数组。
len = size; // 扩展后的数组长度。
}
int size() const { return len; } // 获取数组长度。
T& operator[](int ii) { // 重载操作符[],可以修改数组中的元素。
if (ii >= len) resize(ii + 1); // 扩展数组。
return items[ii];
}
const T& operator[](int ii) const { return items[ii]; } // 重载操作符[],不能修改数组中的元
素。
};
int main()
{
// Vector 容器的大小缺省值是 2,Stack 容器的大小缺省值是 3。
// 创建 Vector 容器,容器中的元素用 Stack<string>。
Vector<Stack<string>> vs; // C++11 之前,>>之间要加空格。
// 手工的往容器中插入数据。
vs[0].push("西施 1"); vs[0].push("西施 2"); vs[0].push("西施 3"); // vs 容器中的第 0
个栈。
vs[1].push("西瓜 1"); vs[1].push("西瓜 2"); vs[1].push("西瓜 3"); // vs 容器中的第 1
个栈。
vs[2].push("冰冰"); vs[2].push("幂幂"); //
vs 容器中的第 2 个栈。
// 用嵌套的循环,把 vs 容器中的数据显示出来。
for (int ii = 0; ii < vs.size(); ii++) // 遍历 Vector 容器。
{
while (vs[ii].isempty() == false) // 遍历 Stack 容器。
{
string item; vs[ii].pop(item); cout << "item = " << item << endl;
}
}
// 创建 Stack 容器,容器中的元素用 Vector<string>。
Stack<Vector<string>> sv;
Vector<string> tmp; // 栈的元素,临时 Vector<string>容器。
// 第一个入栈的元素。
tmp[0] = "西施 1"; tmp[1] = "西施 2"; sv.push(tmp);
// 第二个入栈的元素。
tmp[0] = "西瓜 1"; tmp[1] = "西瓜 2"; sv.push(tmp);
// 第三个入栈的元素。
tmp[0] = " 冰 冰 1"; tmp[1] = " 冰 冰 2"; tmp[2] = " 冰 冰 3"; tmp[3] = " 冰 冰 4";
sv.push(tmp);
// 用嵌套的循环,把 sv 容器中的数据显示出来。
while (sv.isempty() == false)
{
sv.pop(tmp); // 出栈一个元素,放在临时容器中。
for (int ii = 0; ii < tmp.size(); ii++) // 遍历临时 Vector<string>容器,显示容器中每个
元素的值。
cout << " vs[" << ii << "] = " << tmp[ii] << endl;
}
// 创建 Vector 容器,容器中的元素用 Vector<string>。
Vector<Vector<string>> vv; // 递归使用模板类。
vv[0][0] = "西施 1"; vv[0][1] = "西施 2"; vv[0][2] = "西施 3";
vv[1][0] = "西瓜 1"; vv[1][1] = "西瓜 2";
vv[2][0] = "冰冰 1"; vv[2][1] = "冰冰 2"; vv[2][2] = "冰冰 3"; vv[2][3] = "冰冰 4";
// 用嵌套的循环,把 vv 容器中的数据显示出来。
for (int ii = 0; ii < vv.size(); ii++)
{
for (int jj = 0; jj < vv[ii].size(); jj++)
// cout << " vv[" << ii << "][" << jj << "] = " << vv[ii][jj] << endl;
cout << vv[ii][jj] << " ";
cout << endl;
}
}
154、模板类具体化
模板类具体化(特化、特例化)有两种:完全具体化和部分具体化。
语法请见示例程序。
具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。
具体化的模板类,成员函数类外实现的代码应该放在源文件中。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 类模板
template<class T1, class T2>
class AA { // 类模板。
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) :m_x(x), m_y(y) { cout << "类模板:构造函数。\n"; }
void show() const;
};
template<class T1, class T2>
void AA<T1, T2>::show() const { // 成员函数类外实现。
cout << "类模板:x = " << m_x << ", y = " << m_y << endl;
}
/
// 类模板完全具体化
template<>
class AA<int, string> {
public:
int m_x;
string m_y;
AA(const int x, const string y) :m_x(x), m_y(y) { cout << "完全具体化:构造函数。\n"; }
void show() const;
};
void AA<int, string>::show() const { // 成员函数类外实现。
cout << "完全具体化:x = " << m_x << ", y = " << m_y << endl;
}
/
// 类模板部分具体化
template<class T1>
class AA<T1, string> {
public:
T1 m_x;
string m_y;
AA(const T1 x, const string y) :m_x(x), m_y(y) { cout << "部分具体化:构造函数。\n"; }
void show() const;
};
template<class T1>
void AA<T1, string>::show() const { // 成员函数类外实现。
cout << "部分具体化:x = " << m_x << ", y = " << m_y << endl;
}
/
int main()
{
// 具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。
AA<int, string> aa1(8, "我是一只傻傻鸟。"); // 将使用完全具体化的类。
AA<char, string> aa2(8, "我是一只傻傻鸟。"); // 将使用部分具体化的类。
AA<int, double> aa3(8, 999999); // 将使用模板类。
}
156、模板类与继承
1)模板类继承普通类(常见)。
2)普通类继承模板类的实例化版本。
3)普通类继承模板类。(常见)
4)模板类继承模板类。
5)模板类继承模板参数给出的基类(不能是模板类)。
示例:
1)模板类继承普通类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
class AA // 普通类 AA。
{
public:
int m_a;
AA(int a) :m_a(a) { cout << "调用了 AA 的构造函数。\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
template<class T1, class T2>
class BB:public AA // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y,int a) : AA(a) , m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。
\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
int main()
{
BB<int, string> bb(8, "我是一只傻傻鸟。",3);
bb.func2();
bb.func1();
}
2)普通类继承模板类的实例化版本
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
class AA:public BB<int,string> // 普通类 AA。
{
public:
int m_a;
AA(int a,int x,string y) : BB(x,y),m_a(a) { cout << "调用了 AA 的构造函数。\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
int main()
{
AA aa(3,8, "我是一只傻傻鸟。");
aa.func1();
aa.func2();
}
3)普通类继承模板类。
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类 AA 变成了模板类,才能继承模板类。
{
public:
int m_a;
AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了 AA 的构造函数。
\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
int main()
{
AA<int,string> aa(3,8, "我是一只傻傻鸟。");
aa.func1();
aa.func2();
}
4)模板类继承模板类。
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class BB // 模板类 BB。
{
public:
T1 m_x;
T2 m_y;
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { cout << "调用了 BB 的构造函数。\n"; }
void func2() const { cout << "调用了 func2()函数:x = " << m_x << ", y = " << m_y <<
endl; }
};
template<class T1, class T2>
class AA:public BB<T1,T2> // 普通类 AA 变成了模板类,才能继承模板类。
{
public:
int m_a;
AA(int a, const T1 x, const T2 y) : BB<T1,T2>(x,y),m_a(a) { cout << "调用了 AA 的构造函数。
\n"; }
void func1() { cout << "调用了 func1()函数:m_a=" << m_a << endl;; }
};
template<class T, class T1, class T2>
class CC :public BB<T1, T2> // 模板类继承模板类。
{
public:
T m_a;
CC(const T a, const T1 x, const T2 y) : BB<T1, T2>(x, y), m_a(a) { cout << "调用了 CC 的构
造函数。\n"; }
void func3() { cout << "调用了 func3()函数:m_a=" << m_a << endl;; }
};
int main()
{
CC<int,int,string> cc(3,8, "我是一只傻傻鸟。");
cc.func3();
cc.func2();
}
5)模板类继承模板参数给出的基类
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
class AA {
public:
AA() { cout << "调用了 AA 的构造函数 AA()。\n"; }
AA(int a) { cout << "调用了 AA 的构造函数 AA(int a)。\n"; }
};
class BB {
public:
BB() { cout << "调用了 BB 的构造函数 BB()。\n"; }
BB(int a) { cout << "调用了 BB 的构造函数 BB(int a)。\n"; }
};
class CC {
public:
CC() { cout << "调用了 CC 的构造函数 CC()。\n"; }
CC(int a) { cout << "调用了 CC 的构造函数 CC(int a)。\n"; }
};
template<class T>
class DD {
public:
DD() { cout << "调用了 DD 的构造函数 DD()。\n"; }
DD(int a) { cout << "调用了 DD 的构造函数 DD(int a)。\n"; }
};
template<class T>
class EE : public T { // 模板类继承模板参数给出的基类。
public:
EE() :T() { cout << "调用了 EE 的构造函数 EE()。\n"; }
EE(int a) :T(a) { cout << "调用了 EE 的构造函数 EE(int a)。\n"; }
};
int main()
{
EE<AA> ea1; // AA 作为基类。
EE<BB> eb1; // BB 作为基类。
EE<CC> ec1; // CC 作为基类。
EE<DD<int>> ed1; // EE<int>作为基类。
// EE<DD> ed1; // DD 作为基类,错误。
}
157、模板类与函数
模板类可以用于函数的参数和返回值,有三种形式:
1)普通函数,参数和返回值是模板类的实例化版本。
2)函数模板,参数和返回值是某种的模板类。
3)函数模板,参数和返回值是任意类型(支持普通类和模板类和其它类型)。
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA // 模板类 AA。
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
void show() const { cout << "show() x = " << m_x << ", y = " << m_y << endl; }
};
// 采用普通函数,参数和返回值是模板类 AA 的实例化版本。
AA<int, string> func(AA<int, string>& aa)
{
aa.show();
cout << "调用了 func(AA<int, string> &aa)函数。\n";
return aa;
}
// 函数模板,参数和返回值是的模板类 AA。
template <typename T1,typename T2>
AA<T1, T2> func(AA<T1, T2>& aa)
{
aa.show();
cout << "调用了 func(AA<T1, T2> &aa)函数。\n";
return aa;
}
// 函数模板,参数和返回值是任意类型。
template <typename T>
T func(T &aa)
{
aa.show();
cout << "调用了 func(AA<T> &aa)函数。\n";
return aa;
}
int main()
{
AA<int, string> aa(3, "我是一只傻傻鸟。");
func(aa);
}
158、模板类与友元
模板类的友元函数有三类:
1)非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数。
2)约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
3)非约束模板友元:模板类实例化时,如果实例化了 n 个类,也会实例化 n 个友元函数,每个实例
化的类都拥有 n 个友元函数。
1)非模板友元示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA
{
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
// 非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数,只能在类内实现。
friend void show(const AA<T1, T2>& a)
{
cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
}
/* friend void show(const AA<int, string>& a);
friend void show(const AA<char, string>& a);*/
};
//void show(const AA<int, string>& a)
//{
// cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
//
//void show(const AA<char, string>& a)
//{
// cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
show(a);
AA<char, string> b(88, "我是一只傻傻鸟。");
show(b);
}
2)约束模板友元示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
template <typename T>
void show(T& a); // 第一步:在模板类的定
义前面,声明友元函数模板。
template<class T1, class T2>
class AA // 模板类 AA。
{
friend void show<>(AA<T1, T2>& a); // 第二步:在模板类中,再次声明友元函
数模板。
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template<class T1, class T2>
class BB // 模板类 BB。
{
friend void show<>(BB<T1, T2>& a); // 第二步:在模板类中,再次声明友元函数
模板。
T1 m_x;
T2 m_y;
public:
BB(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template <typename T> // 第三步:友元函数模板的定义。
void show(T& a)
{
cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <> // 第三步:具体化版本。
void show(AA<int, string>& a)
{
cout << "具体 AA<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <> // 第三步:具体化版本。
void show(BB<int, string>& a)
{
cout << "具体 BB<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
int main()
{
AA<int, string> a1(88, "我是一只傻傻鸟。");
show(a1); // 将使用具体化的版本。
AA<char, string> a2(88, "我是一只傻傻鸟。");
show(a2); // 将使用通用的版本。
BB<int, string> b1(88, "我是一只傻傻鸟。");
show(b1); // 将使用具体化的版本。
BB<char, string> b2(88, "我是一只傻傻鸟。");
show(b2); // 将使用通用的版本。
}
3)非约束模板友元
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
// 非类模板约束的友元函数,实例化后,每个函数都是每个每个类的友元。
template<class T1, class T2>
class AA
{
template <typename T> friend void show(T& a); // 把函数模板设置为友元。
T1 m_x;
T2 m_y;
public:
AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};
template <typename T> void show(T& a) // 通用的函数模板。
{
cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}
template <>void show(AA<int, string>& a) // 函数模板的具体版本。
{
cout << "具体<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
show(a); // 将使用具体化的版本。
AA<char, string> b(88, "我是一只傻傻鸟。");
show(b); // 将使用通用的版本。
}
159、成员模板类
示例:
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
template<class T1, class T2>
class AA // 类模板 AA。
{
public:
T1 m_x;
T2 m_y;
AA(const T1 x, const T2 y) : m_x(x), m_y(y) {}
void show() { cout << "m_x=" << m_x << ",m_y=" << m_y << endl; }
template<class T>
class BB
{
public:
T m_a;
T1 m_b;
BB() {}
void show();
};
BB<string> m_bb;
template<typename T>
void show(T tt);
};
template<class T1, class T2>
template<class T>
void AA<T1,T2>::BB<T>::show() {
cout << "m_a=" << m_a << ",m_b=" << m_b << endl;
}
template<class T1, class T2>
template<typename T>
void AA<T1,T2>::show(T tt) {
cout << "tt=" << tt << endl;
cout << "m_x=" << m_x << ",m_y=" << m_y << endl;
m_bb.show();
}
int main()
{
AA<int, string> a(88, "我是一只傻傻鸟。");
a.show();
a.m_bb.m_a = "我有一只小小鸟。";
a.m_bb.show();
a.show("你是一只什么鸟?");
}
 


http://www.ppmy.cn/devtools/107523.html

相关文章

【王树森】RNN模型与NLP应用(8/9):Attention(个人向笔记)

前言 基于RNN的Seq2Seq模型无法记住长序列Attentnion机制可以大幅度提升Seq2Seq模型 Seq2Seq Model with Attention Attention可以让句子在逐步变长的时候不忘记前面的输入信息Attention还可以告诉Decoder应该关注哪一个状态优点&#xff1a;Attention可以大幅度提高准确率缺…

ArcGIS栅格裁剪与合并,制作等高线

1、下载高程数据&#xff08;DEM&#xff09; https://mp.weixin.qq.com/s/ewlUUVV0PwdcspPGtSdCog 项目区域对应的卫片&#xff0c;也可以在谷歌地图里看大致经纬度范围 2、项目区域 确定项目区域&#xff0c;例如某个县区范围 3、栅格裁剪与合并 将DEM多个栅格数据合并&#…

IP/TCP/UDP协议的关键知识点

导语&#xff1a;网络协议是理解网络情况的基础&#xff0c;当遇到网络问题时&#xff0c;首先可以从网络协议入手&#xff0c;熟悉的网络协议可以有效帮助小伙伴们排查或者说定位大概的问题方面。本文整理了目前最常用的网络通信协议&#xff0c;相信对小伙伴们肯定都有帮助。…

ElementUI实现el-table组件的合并行功能

前言 有时遇到一些需求&#xff0c;需要实现ElementUI中&#xff0c;el-tabled组件合并单元格的功能&#xff0c;稍微了解一下它的数据格式&#xff0c;不难可以写出比合并方法。但是在鼠标经过单元行时&#xff0c;会出现高亮的行与鼠标经过的行不一致的BUG。因此还需要实现c…

高中生现身头部量化私募大厂竞赛,从大学生抢到高中生

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…

算法——K-means算法和算法改进

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 一、什么是K-means算法&#xff1f; K-means算法是一种无监督的聚类算法&#xff0c;用于将一组数据点分为K个簇&#xff08;cluster&#xff09;。其核心目标是将数据点划分到K个不同的簇中&…

国庆出行必备!南卡Pro5骨传导耳机,享受音乐无界限

国庆长假即将来临&#xff0c;许多人计划出游放松心情&#xff0c;探索新的地方。在这样的旅途中&#xff0c;音乐和舒适的体验是不可或缺的。而南卡Runner Pro5骨传导蓝牙耳机&#xff0c;以其独特的设计和功能&#xff0c;成为了国庆出行的理想搭档。下面&#xff0c;我将从骨…

在Jenkinsfile中,自定义environment相关参数

在Jenkinsfile中&#xff0c;environment定义VER&#xff0c;若BRANCH_NAME是master&#xff0c;则VER为master&#xff0c;其他为latest pipeline {agent anyenvironment {CURTIME sh(returnStdout: true, script: date "%Y%m%d%H%M%S").trim()VER sh(returnStdo…