C++从入门到实战(十六)String(中)String的常用接口(构造接口,析构接口,迭代器,遍历修改,容量管理与数据访问)
C++从入门到实战(十六)String(中)详细讲解String的常用接口
- 前言
- 一、std::string
- 二、string的构造接口
- 1. 默认构造函数:创建空字符串
- 2. 拷贝构造函数:复制已有字符串
- 3. 从已有字符串截取部分
- 4. 用C风格字符串构造
- 5. 用C风格字符串的前n个字符构造
- 6. 用重复字符构造
- 7. 用迭代器构造(了解即可)
- 三、string的赋值与析构
- 1. 析构函数 ~string()
- 2. 赋值运算符 operator=
- 2.1 用另一个 string 对象赋值(常用)
- 2.2 用 C 风格字符串赋值(了解即可)
- 2.3 用单个字符赋值
- 四、string::iterator迭代器(重点掌握)
- 1. 为什么需要迭代器?
- 2. 迭代器的基本使用(像指针一样操作)
- 3. 迭代器的4种类型
- 4. 迭代器的边界
- 5. 修改字符串(通过迭代器写操作)
- 6. 迭代器与STL算法结合
- 7. 安全注意事项
- 五、string的遍历与修改
- 1. string的遍历(逐个访问字符)
- 2. string的修改(增删改查)
- 3. string的底层(了解即可)
- 六、String里的Capacity(容量管理)
- 1. size() 和 length()(获取字符串长度)
- 2. max_size()(最大容量)
- 3. resize(n) 和 resize(n, c)(调整大小)
- 4. capacity()(当前分配的容量)
- 5. reserve(n)(预分配容量)
- 6. clear()(清空字符串)
- 7. empty()(判断是否为空)
- 8. shrink_to_fit()(缩容)
- 总结
- 底层原理(了解即可)
- 八、string数据访问
- 1. operator[](下标访问)
- 2. at() 方法(安全访问)
- 3. back()(访问最后一个字符)
- 4. front()(访问第一个字符)
前言
- 在上一篇博客中,我们深入探讨了 STL 与 String 的内在联系,解析了 string 类的设计初衷以及它在 C++ 编程中的重要价值。
- 通过剖析 string 类在内存管理、字符操作和 STL 容器适配等方面的独特优势,我们理解了它作为 C++ 标准字符串处理工具的核心地位。
- 本篇博客将进入 string 的实战环节,重点解析 string 类的常用接口
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
C++string的官方讲解网站
https://cplusplus.com/reference/string/string/?kw=string
一、std::string
typedef basic_string<char> string;
std::string
是 C++ 标准库中用于处理字符串的类,它让我们可以像操作普通变量一样方便地处理文本数据。
-
简单来说,string 就是 C++ 为程序员提供的「字符串神器」,不用再手动管理内存,也不用操心字符串长度,各种常用操作都已经帮你写好了。
-
string的接口有很多,我们先来看一看他的接口有哪些,后面会挨个详细讲
接口名 | 功能简述 |
---|---|
构造函数 | 创建字符串对象 |
析构函数 | 销毁字符串对象 |
operator= | 字符串赋值操作 |
迭代器 | |
begin() | 返回指向字符串起始位置的迭代器 |
end() | 返回指向字符串末尾(‘\0’ 之后)的迭代器 |
rbegin() | 返回反向迭代器,指向字符串末尾 |
rend() | 返回反向迭代器,指向字符串起始位置之前 |
cbegin() | 返回 const 迭代器,指向字符串起始位置 |
cend() | 返回 const 迭代器,指向字符串末尾 |
crbegin() | 返回 const 反向迭代器,指向字符串末尾 |
crend() | 返回 const 反向迭代器,指向字符串起始位置之前 |
容量操作 | |
size() / length() | 返回字符串长度(不包含终止符) |
max_size() | 返回字符串的最大可能长度 |
resize(n) | 调整字符串长度为 n ,超出部分截断,不足部分填充默认字符 |
capacity() | 返回当前分配的存储空间大小 |
reserve(n) | 请求至少能容纳 n 个字符的存储空间(可能扩大 capacity) |
clear() | 清空字符串内容 |
empty() | 判断字符串是否为空 |
shrink_to_fit() | 释放未使用的内存,使 capacity 等于 size |
元素访问 | |
operator[] | 通过下标访问字符(不检查越界) |
at() | 通过下标访问字符(越界时抛出异常) |
back() | 访问最后一个字符 |
front() | 访问第一个字符 |
修改操作 | |
operator+= | 追加内容到字符串末尾 |
append() | 追加内容到字符串末尾 |
push_back() | 追加单个字符到字符串末尾 |
assign() | 赋值新内容给字符串 |
insert() | 在指定位置插入内容 |
erase() | 删除指定位置的字符或子串 |
replace() | 替换指定位置的子串 |
swap() | 交换两个字符串的内容 |
pop_back() | 删除最后一个字符 |
字符串操作 | |
c_str() | 返回 C 风格字符串(以 ‘\0’ 结尾的 const char*) |
data() | 返回字符串数据的指针(C++11 起与 c_str() 相同) |
get_allocator() | 返回用于内存分配的 allocator 对象 |
copy() | 将字符串内容复制到字符数组中 |
find() | 查找子串或字符首次出现的位置 |
rfind() | 从后向前查找子串或字符首次出现的位置 |
find_first_of() | 查找字符串中第一个与指定字符集中任何字符匹配的位置 |
find_last_of() | 从后向前查找字符串中第一个与指定字符集中任何字符匹配的位置 |
find_first_not_of() | 查找字符串中第一个不与指定字符集中任何字符匹配的位置 |
find_last_not_of() | 从后向前查找字符串中第一个不与指定字符集中任何字符匹配的位置 |
substr() | 返回子串(从指定位置开始的指定长度的子串) |
compare() | 比较两个字符串的大小(字典序) |
二、string的构造接口
string
类提供了多种构造函数,让你可以用不同的方式创建字符串对象。下面是最常用的几种构造方式。
1. 默认构造函数:创建空字符串
string();
作用:创建一个空的字符串对象,不包含任何字符。
例子:
string s; // 创建空字符串
cout << s << endl; // 输出空行
2. 拷贝构造函数:复制已有字符串
string (const string& str);
作用:用一个已有的 string
对象创建新的字符串,内容完全相同。
例子:
string original = "hello";
string copy(original); // 拷贝构造
cout << copy << endl; // 输出: hello
3. 从已有字符串截取部分
string (const string& str, size_t pos, size_t len = npos);
作用:从 str
的 pos
位置开始,截取 len
个字符作为新字符串。
关键参数:
pos
:起始位置(从0开始)。len = npos
:npos
是一个特殊值,表示「直到字符串末尾」。
例子:
string original = "hello world";
string substr1(original, 6); // 从位置6开始到末尾,输出: world
string substr2(original, 0, 5); // 从位置0开始取5个字符,输出: hello
4. 用C风格字符串构造
string (const char* s);
作用:把 C 风格的字符串(以 '\0'
结尾的字符数组)转换为 string
对象。
例子:
const char* c_str = "hello";
string s(c_str); // 用C字符串构造
cout << s << endl; // 输出: hello
5. 用C风格字符串的前n个字符构造
string (const char* s, size_t n);
作用:取 C 风格字符串的前 n
个字符(不要求以 '\0'
结尾)。
例子:
const char* c_str = "abcdef";
string s(c_str, 3); // 取前3个字符
cout << s << endl; // 输出: abc
6. 用重复字符构造
string (size_t n, char c);
作用:创建包含 n
个重复字符 c
的字符串。
例子:
string s(5, 'a'); // 创建5个'a'的字符串
cout << s << endl; // 输出: aaaaa
7. 用迭代器构造(了解即可)
template <class InputIterator>
string (InputIterator first, InputIterator last);
作用:用迭代器范围内的字符构造字符串,常用于从其他容器(如 vector<char>
)创建字符串。
三、string的赋值与析构
1. 析构函数 ~string()
每个 string
对象在生命周期结束时,会自动调用析构函数,释放占用的内存。你不需要手动操作,C++ 会帮你搞定。
例子:
{string s = "hello"; // 创建对象
} // 离开作用域,s 自动销毁,内存自动释放
2. 赋值运算符 operator=
2.1 用另一个 string 对象赋值(常用)
string& operator= (const string& str);
作用:把一个 string
对象的内容复制到另一个 string
对象。
例子:
string s1 = "hello";
string s2 = "world";
s1 = s2; // s1 现在是 "world"
cout << s1 << endl; // 输出: world
2.2 用 C 风格字符串赋值(了解即可)
string& operator= (const char* s);
作用:把 C 风格字符串(如 "hello"
)赋值给 string
对象。
例子:
string s;
s = "hello"; // 等价于 string s = "hello";
cout << s << endl; // 输出: hello
2.3 用单个字符赋值
string& operator= (char c);
作用:让 string
对象只包含一个字符。
例子:
string s;
s = 'A'; // s 现在是 "A"
cout << s << endl; // 输出: A
四、string::iterator迭代器(重点掌握)
1. 为什么需要迭代器?
迭代器是C++中访问容器(如string、vector)元素的通用方式,它让我们可以:
- 统一语法:用相同的方式遍历不同类型的容器。
- 支持算法:STL算法(如
find
、sort
)依赖迭代器工作。 - 隐藏底层细节:无需关心容器内部如何存储数据。
类比:迭代器就像“容器的指针”,让你可以逐个访问元素。
2. 迭代器的基本使用(像指针一样操作)
定义迭代器:
string::iterator it; // 正向迭代器(从前往后)
string::reverse_iterator rit; // 反向迭代器(从后往前)
遍历字符串:
#include <iostream>
#include <string>
using namespace std;
int main()
{string s = "hello";// 正向遍历(从前往后)
for (string::iterator it = s.begin(); it != s.end(); ++it) {cout << *it; // *it 是当前字符,输出: hello
}cout << endl;
// 反向遍历(从后往前)
for (string::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit) {cout << *rit; // 输出: olleh
}return 0;
}
简化写法(用auto
自动推导类型):
for (auto it = s.begin(); it != s.end(); ++it) {cout << *it; // 效果同上
}
3. 迭代器的4种类型
类型 | 功能 | 例子 |
---|---|---|
iterator | 正向遍历,可读写 | auto it = s.begin(); |
const_iterator | 正向遍历,只读(用于常量字符串) | const string cs = "hi"; auto cit = cs.begin(); |
reverse_iterator | 反向遍历,可读写 | auto rit = s.rbegin(); |
const_reverse_iterator | 反向遍历,只读 | auto crit = cs.rbegin(); |
4. 迭代器的边界
s.begin()
:指向第一个字符(如'h'
in"hello"
)。s.end()
:指向最后一个字符的下一个位置(即字符串结束标记'\0'
的位置),不包含该字符。s.rbegin()
:指向最后一个字符(如'o'
in"hello"
)。s.rend()
:指向第一个字符的前一个位置(反向的结束标记)。
为什么不访问'\0'
?
因为迭代器设计为只访问有效字符,而 '\0'
是C风格字符串的结束标记,string
类用 size()
明确记录长度,不需要 '\0'
。
5. 修改字符串(通过迭代器写操作)
string s = "hello";
for (auto it = s.begin(); it != s.end(); ++it) {*it = toupper(*it); // 转为大写
}
cout << s; // 输出: HELLO
6. 迭代器与STL算法结合
例子1:查找字符
string s = "hello";
auto it = find(s.begin(), s.end(), 'l');
if (it != s.end()) {cout << "找到 'l' 在位置: " << it - s.begin() << endl; // 输出: 2
}
例子2:反转字符串
string s = "hello";
reverse(s.begin(), s.end()); // 直接反转
cout << s; // 输出: olleh
7. 安全注意事项
- 迭代器失效:修改字符串可能导致迭代器失效,例如:
正确做法:for (auto it = s.begin(); it != s.end(); ) {if (*it == 'l') {s.erase(it); // 错误!删除元素后迭代器失效} else {++it;} }
erase()
返回下一个有效迭代器:for (auto it = s.begin(); it != s.end(); ) {if (*it == 'l') {it = s.erase(it); // 正确!更新迭代器} else {++it;} }
五、string的遍历与修改
1. string的遍历(逐个访问字符)
方法1:用下标 []
(最常用)
类似数组,用 s[i]
访问第 i
个字符(索引从0开始)。
例子:
string s = "hello";
for (size_t i = 0; i < s.size(); i++) {cout << s[i] << " "; // 输出: h e l l o
}
方法2:用迭代器(适合STL算法)
迭代器像「指针」,指向字符串中的字符。
例子:
string s = "hello";
for (auto it = s.begin(); it != s.end(); ++it) {cout << *it << " "; // 输出: h e l l o
}
方法3:范围for循环(C++11起,最简单)
直接遍历每个字符,无需索引。
例子:
string s = "hello";
for (char c : s) {cout << c << " ";
}
2. string的修改(增删改查)
修改单个字符
用下标或迭代器直接修改。
例子:
string s = "hello";
s[0] = 'H'; // s 变为 "Hello"
s.back() = '!'; // 修改最后一个字符,s 变为 "Hello!"
追加内容
用 +=
或 append()
方法。
例子:
string s = "hello";
s += " world"; // s 变为 "hello world"
s.append("!"); // s 变为 "hello world!"
插入字符
用 insert()
方法在指定位置插入。
例子:
string s = "hello";
s.insert(1, "X"); // 在位置1插入 'X',s 变为 "hXello"
删除字符
用 erase()
方法删除指定位置或范围。
例子:
string s = "hello";
s.erase(1, 2); // 从位置1开始删除2个字符,s 变为 "heo"
替换内容
用 replace()
方法替换指定范围的字符。
例子:
string s = "hello";
s.replace(1, 3, "XXX"); // 替换位置1~3的字符,s 变为 "hXXXo"
3. string的底层(了解即可)
string
的底层是一个动态字符数组,类似 char*
,但会自动管理内存:
- 自动扩容:当字符串变长时,
string
会自动申请更大的内存,并复制原有内容。 - 内存优化:现代C++对短字符串有特殊优化(SSO,小字符串优化),直接存储在对象内部,避免堆内存分配。
例子(帮助理解底层):
string s = "a"; // 可能直接存对象内部(SSO)
s += "bcdef"; // 内容太长,转为堆内存存储
注意事项
- 索引越界:访问
s[i]
时,确保i < s.size()
,否则会导致未定义行为(比如崩溃)。 - 迭代器失效:修改字符串可能导致迭代器失效,比如:
for (auto it = s.begin(); it != s.end(); ++it) {s.erase(it); // 错误!删除元素后迭代器失效 }
- 性能提示:频繁插入/删除可能导致内存频繁重新分配,性能较低。
六、String里的Capacity(容量管理)
1. size() 和 length()(获取字符串长度)
- 作用:返回字符串中实际字符的数量(不包含结尾的
'\0'
)。 - 区别:
size()
是所有容器(如vector
)通用的接口,length()
是专门为字符串设计的,两者功能完全相同。
例子:
string s = "hello";
cout << s.size() << endl; // 输出: 5
cout << s.length() << endl; // 输出: 5(和size()一样)
2. max_size()(最大容量)
作用:返回当前系统中 string
对象能存储的最大字符数(理论上限)。
注意:实际中几乎不可能达到这个值,因为内存会先耗尽。
例子:
string s;
cout << s.max_size() << endl; // 输出一个很大的数
3. resize(n) 和 resize(n, c)(调整大小)
作用:调整字符串长度为 n
:
- 若
n
小于当前长度,截断多余字符。 - 若
n
大于当前长度,用字符c
填充(默认用'\0'
填充)。
例子:
string s = "hello";
s.resize(3); // s 变为 "hel"
s.resize(5, '!'); // s 变为 "hel!!"
4. capacity()(当前分配的容量)
作用:返回字符串当前分配的内存能容纳的最大字符数(不包含 '\0'
)。
特点:容量通常大于等于实际长度,避免频繁重新分配内存。
例子:
string s = "hello";
cout << s.size() << endl; // 输出: 5(实际长度)
cout << s.capacity() << endl; // 输出: 15(不同系统可能不同)
5. reserve(n)(预分配容量)
作用:提前分配至少能容纳 n
个字符的内存,减少后续扩容次数。
例子:
string s;
s.reserve(100); // 预先分配100个字符的空间
cout << s.capacity() << endl; // 输出: 100 或更大(取决于实现)
6. clear()(清空字符串)
作用:清空字符串内容,使其长度为0,但不释放内存(容量不变)。
例子:
string s = "hello";
s.clear();
cout << s.size() << endl; // 输出: 0
cout << s.capacity() << endl; // 输出: 15(和clear前一样)
7. empty()(判断是否为空)
作用:检查字符串是否为空(长度是否为0)。
例子:
string s = "hello";
cout << s.empty() << endl; // 输出: 0(false)s.clear();
cout << s.empty() << endl; // 输出: 1(true)
8. shrink_to_fit()(缩容)
作用:将容量调整为当前实际长度,释放多余内存。
注意:缩容需要重新分配内存并复制数据,代价较高,建议少用。
例子:
string s;
s.reserve(100); // 容量变为100
s = "hello"; // 长度变为5,但容量仍为100s.shrink_to_fit(); // 容量缩小到5(或略大于5)
总结
方法 | 作用 | 例子 |
---|---|---|
size() | 返回字符串实际长度 | string s = "a"; s.size(); |
capacity() | 返回当前分配的容量 | s.capacity(); |
reserve(n) | 预分配至少 n 个字符的空间 | s.reserve(100); |
clear() | 清空字符串(长度为0,但容量不变) | s.clear(); |
empty() | 判断字符串是否为空 | if (s.empty()) { ... } |
shrink_to_fit() | 释放多余内存(慎用,代价高) | s.shrink_to_fit(); |
底层原理(了解即可)
string
的内存管理策略:
- 动态扩容:当字符串长度超过容量时,自动申请更大的内存(通常翻倍),例如:
string s; s += 'a'; // 容量可能变为1 s += 'b'; // 容量可能变为2 s += 'c'; // 容量可能变为4(翻倍)
- 小字符串优化(SSO):短字符串(如
"hello"
)直接存储在对象内部,不使用堆内存,提高性能。
注意事项
- 容量 vs 长度:
- 长度:实际字符数(
size()
)。 - 容量:已分配的内存大小(
capacity()
)。
- 长度:实际字符数(
- 性能提示:
- 提前
reserve()
可避免频繁扩容。 - 少用
shrink_to_fit()
,除非确实需要释放大量内存。
- 提前
- 清空字符串:
clear()
比s = ""
效率更高,因为不涉及内存分配。
八、string数据访问
1. operator[](下标访问)
作用:通过索引访问字符串中的字符,类似数组。
重载版本:
char& operator[] (size_t pos);
// 用于非const字符串(可修改)const char& operator[] (size_t pos) const;
// 用于const字符串(只读)
为什么需要两个版本?
为了区分读写操作:
- 对非const字符串(如
string s = "hello";
),s[0] = 'H';
可以修改字符。 - 对const字符串(如
const string cs = "hi";
),cs[0]
只能读,不能修改。
例子:
string s = "hello";
s[0] = 'H'; // 修改第一个字符,s 变为 "Hello"
cout << s[1]; // 输出: econst string cs = "hi";
// cs[0] = 'H'; // 错误!const版本不允许修改
cout << cs[0]; // 输出: h
2. at() 方法(安全访问)
作用:同 []
,但会检查索引是否越界(若越界则抛出 out_of_range
异常)。
例子:
string s = "hello";
try {cout << s.at(10); // 越界,抛出异常
} catch (const out_of_range& e) {cout << "错误: " << e.what(); // 输出错误信息
}
对比 []
和 at()
:
方法 | 越界检查 | 性能 | 建议场景 |
---|---|---|---|
[] | 不检查 | 快 | 已知索引合法时 |
at() | 检查 | 稍慢 | 不确定索引是否合法时 |
3. back()(访问最后一个字符)
作用:返回字符串的最后一个字符的引用。
例子:
string s = "hello";
cout << s.back(); // 输出: o
s.back() = '!'; // 修改最后一个字符,s 变为 "hell!"
4. front()(访问第一个字符)
作用:返回字符串的第一个字符的引用。
例子:
string s = "hello";
cout << s.front(); // 输出: h
s.front() = 'H'; // 修改第一个字符,s 变为 "Hello"
注意事项
- 空字符串风险:对空字符串调用
back()
或front()
会导致未定义行为(如崩溃),需先检查s.empty()
。 - 性能取舍:
at()
更安全但稍慢,[]
更快但需自行确保索引合法。 - 引用返回:
[]
、at()
、back()
、front()
返回的都是引用,可直接修改字符。
以上就是这篇博客的全部内容,下一篇我们将继续探索STL中String里更多精彩内容。
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
非常感谢您的阅读,喜欢的话记得三连哦 |
相关文章:
C++从入门到实战(十六)String(中)String的常用接口(构造接口,析构接口,迭代器,遍历修改,容量管理与数据访问)
C从入门到实战(十六)String(中)详细讲解String的常用接口 前言一、std::string二、string的构造接口1. 默认构造函数:创建空字符串2. 拷贝构造函数:复制已有字符串3. 从已有字符串截取部分4. 用C风格字符串…...
RabbitMQ ⑤-顺序性保障 || 消息积压 || 幂等性
幂等性保障 幂等性(Idempotency) 是计算机科学和网络通信中的一个重要概念,指的是某个操作无论被执行多少次,所产生的效果与执行一次的效果相同。 应用程序的幂等性: 在应用程序中,幂等性就是指对一个系统…...
go.mod:5: unknown directive: toolchain
Go语言版本较旧,而项目使用了较新版本的Go语言特性。错误信息"unknown directive: toolchain"表明go.mod文件中使用了"toolchain"指令,这是在Go 1.21版本中新引入的特性,但您当前安装的Go版本不支持这个指令。 解决方法…...
分布式序列生成方案 : Redis Incr | 基于Redisson创建自增获取序号,每天更换一个key, key到期时间1天,用于创建订单号、快递单号
文章目录 引言I 在 Spring Boot 应用程序中集成 Redisson1. Maven2. 配置 Redisson 客户端3. 创建 Redisson 配置类4. 自动装配 RedissonClientII 应用: 基于Redisson创建自增获取序号生成每日自增序号创建订单号创建快递单号封装 :系统自动生成单号引言 应用: 创建订单号、…...
Android7 Input(八)App Input事件接收器InputEventReceiver
概述 上一个章节,我们讲解了App如何使用InputChannel通道与input系统服务建立通信的桥梁的过程,本章我们讲述App如何从input系统服务中获取上报的输入事件,也就是我们本章讲述的InputEventReceiver。 本文涉及的源码路径 frameworks/base/c…...
阿里云服务器Ubuntu的git clone失败问题解决方案
一、问题 我们再使用阿里云服务器或者别的服务器,git clone失败 二、解决方案 1. 确认SSH密钥是否存在并正确配置 检查密钥文件: ls -al ~/.ssh 确认存在 id_rsa(私钥)和 id_rsa.pub(公钥ÿ…...
Mujoco 学习系列(二)基础功能与xml使用
这篇文章是 Mujoco 学习系列第二篇,主要介绍一些基础功能与 xmI 使用,重点在于如何编写与读懂 xml 文件。 运行这篇博客前请先确保正确安装 Mujoco 并通过了基本功能与GUI的验证,即至少完整下面这个博客的 第二章节 内容: Mujoc…...
8 定时任务与周期性调度
在构建复杂的分布式系统时,我们经常会遇到需要“定时”或“周期性”执行的任务。比如,每天凌晨生成报表,每小时同步一次数据,或者在特定时间发送提醒邮件。这些任务如果都依赖人工触发,不仅效率低下,而且容…...
idea 插件开发自动发布到 nexus 私服中(脚本实例)
如下脚本内容为 idea 插件开发项目中的 build.gradle.kts 文件示例,其中自定了 updatePluginsXml 和 uploadPluginToNexus 两个任务,一个用来自动修改 nexus 中的配置文件,一个用来自动将当前插件打包后的 zip 文件上传到 nexus 私服中。 脚…...
关于 APK 反编译与重构工具集
一、apktool — APK 解包 / 重打包 apktool 是一款开源的 Android APK 工具,用于: 反编译 APK 查看资源和布局文件 生成 smali 文件(DEX 的反汇编) 对 APK 进行修改后重新打包 它不能还原 Java 源码,只能将 D…...
【课堂笔记】核方法和Mercer定理
文章目录 Kernal引入定义Mercer定理描述有限情形证明一般情形证明 Kernal 引入 在实际数据中常常遇到不可线性分割的情况,此时通常需要将其映射到高维空间中,使其变得线性可分。例如二维数据: 通过映射 ϕ ( x 1 , x 2 ) ( x 1 2 , 2 x 1…...
Cribl 中 Parser 扮演着重要的角色 + 例子
先看文档: Parser | Cribl Docs Parser The Parser Function can be used to extract fields out of events or reserialize (rewrite) events with a subset of fields. Reserialization will preserve the format of the events. For example, if an event contains comma…...
MVDR源码(可直接运行)
该代码可正常运行,信号使用的是模拟信号,可改为指定信号。 本代码使用了一个基于MVDR(最小方差无失真响应)算法的麦克风阵列声源定位方法。代码首先设置了麦克风阵列的参数,包括阵元数量、采样率、信号频率等ÿ…...
MyBatis实战指南(一)MyBatis入门基础与利用IDEA从零开始搭建你的第一个MyBatis系统
MyBatis实战指南(一)MyBatis入门基础与利用IDEA从零开始搭建你的第一个MyBatis系统 一、什么是MyBatis1. MyBatis 是什么?2. JDBC 的三大痛点3. MyBatis 的核心优势1. 告别重复代码,专注核心逻辑2. 灵活控制 SQL,适应各…...
React Flow 数据持久化:Django 后端存储与加载的最佳实践(含详细代码解析)
在构建 React Flow 应用时,前端呈现的节点与连线构成的可视化流程只是冰山一角,其背后的数据持久化与灵活调取才是确保应用稳定运行、支持用户数据回溯与协作的关键。因此,后端存储与加载 React Flow 信息的环节,就如同整个应用的…...
第32节:基于ImageNet预训练模型的迁移学习与微调
1. 引言 在深度学习领域,迁移学习(Transfer Learning)已经成为解决计算机视觉任务的重要方法,特别是在数据量有限的情况下。其中,基于ImageNet数据集预训练的模型因其强大的特征提取能力而被广泛应用于各种视觉任务。本文将详细介绍迁移学习的概念、ImageNet预训练模型的特…...
接口自动化可视化展示
目的将接口返回的实际对比返回 前端:使用Geeker-Admin二次开发使用 后端 flaskpythonrequests 实际实现展示 接口测试通过 接口测试不通过 接口数据的增删改查...
Hbuilder X4.65新建vue3项目存在的问题以及解决办法
有关Vue的多篇文章: 1.使用Vue创建前后端分离项目的过程:使用Vue创建前后端分离项目的过程(前端部分)_vue前端项目打包的dish-CSDN博客 2.vue3实现自定义导航菜单:vue3实现自定义导航菜单_vue3 导航栏-CSDN博客 3…...
SpringBoot 项目实现操作日志的记录(使用 AOP 注解模式)
本文是博主在做关于如何记录用户操作日志时做的记录,常见的项目中难免存在一些需要记录重要日志的部分,例如权限和角色设定,重要数据的操作等部分。 博主使用 Spring 中的 AOP 功能,结合注解的方式,对用户操作过的一些…...
C/C++ 整数类型的长度
参考 cppreference.cn 在某些语言中,整数类型的长度是固定的,如java中 char 8short 16int 32long 64 可是C/C 与机器相关,整数类型长度与平台有关 先可以记一个简单的 按照C标准: char > 8short > 16int > 16long &g…...
解决npm install报错:getaddrinfo ENOTFOUND registry.nlark.com
问题背景 在使用 npm install 安装依赖时,突然遇到以下错误: npm ERR! network request to https://registry.nlark.com/fsevents/download/fsevents-2.3.2.tgz failed, reason: getaddrinfo ENOTFOUND registry.nlark.com这表明 npm 在尝试从 registr…...
PostgreSQL简介安装
目录 一. PostgreSQL 1. 简介 2. 特点 3. 优势 4. 架构 5. 应用场景 二. 安装PostgerSQL 1. 编译安装 (1) 安装编译安装所需环境 (2) 编译安装 (3) 配置环境变量 (4) 登录数据库 2. DNF安装 (1) 安装postgreSQL (2) 初始化数据库 (3) 登录数据库 三. postgreSQ…...
vue3+elementPlus穿梭框拖拽
安装 npm install sortablejs --save <template><div class"transfer" ref"transfer"><div><el-transfer v-model"inputForm" :data"data" :titles"titles"><template #default"{ option }…...
牛客周赛 Round 93题解(个人向A-E)
牛客周赛 Round 93题解(个人向A-E) 题目链接:https://ac.nowcoder.com/acm/contest/109904 a题 签到题,直接按题意模拟即可 #include <bits/stdc.h> using namespace std; #define ll long long int main() {ios::sync_…...
MySQL高可用之ProxySQL + MGR 实现读写分离实战
部署MGR 1、MGR 前置介绍 阿里云RDS集群方案用的就是MGR模式! 1.1、什么是 MGR MGR(MySQL Group Replication)是MySQL 5.7.17版本诞生的,是MySQL自带的一个插件,可以灵活部署。保证数据一致性又可以自动切换&#x…...
React TS中如何化简DOM事件的定义
概要 我们在做TS开发时候,总要面对各种类型的定义。React使用自己的Sythetic Event机制管理DOM事件,不同于原生的DOM事件定义,所以在TS中,事件的类型定义更加繁琐。 本文提供一中简化定义的方法,在使用中,…...
BigemapPro蒙版使用技巧:精准导出地图范围
在地图制图过程中,我们常常会遇到需要按照特定边界裁剪地图,或者对指定范围以外的地图进行模糊处理等情况,这时"添加蒙版"功能就非常实用。 BigemapPro的蒙版功能,可满足用户按自定义形状裁剪地图、控制区域外显示效果&…...
CesiumEarth v1.15 更新
更新: CesiumEarth 更新至1.15.0版本,包含浏览器在线版、Desktop Windows版本、Desktop 安卓版本 界面优化: 项目列表已适配手机屏幕 功能 扩展模块更新 1、在底部工具栏区域,所有已生效(已勾选࿰…...
SOC-ESP32S3部分:2-2-VSCode进行编译烧录
飞书文档https://x509p6c8to.feishu.cn/wiki/CTzVw8p4LiaetykurbTciA42nBf?fromScenespaceOverview 无论是使用Window搭建IDF开发环境,还是使用Linux Ubuntu搭建IDF开发环境,我们都建议使用VSCode进行代码编写和编译,VSCode界面友好&#x…...
机器学习 day05
文章目录 前言一、模型选择与调优1.交叉验证2.超参数搜索 前言 通过今天的学习,我掌握了机器学习中模型的选择与调优,包括交叉验证,超参数搜索的概念与基本用法。 一、模型选择与调优 模型的选择与调优有许多方法,这里主要介绍较…...
关于element-ui的table type=“expand“ 嵌套表格展开异常问题解决方案
也许是很久没用这个库了 今天找这个问题还花了一会儿时间 也是蛮简单的一个问题 排查过程就不说了 直接说结果吧 记录一下 发现问题 展开第一列的时候表格没问题 收起的时候 莫名其妙多了一个展开的按钮 代码咋一看没什么问题 百思不解不得其解 甚至怀疑row-key的问题 检查了数…...
Pichome 开源网盘程序index.php 文件读取漏洞(CVE-2025-1743)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
[SpringBoot]Spring MVC(6.0)----图书管理系统(初)
图书管理系统 需求: 1. 登录: 用户输入账号,密码完成登录功能. 2. 列表展示: 展示图书. 准备工作 将前端代码复制到 static 目录下. 约定前后端交互接口 两个功能: 用户登录 和 图书列表展示. 需求分析: 1. 用户登录 url : /user/login param : userName 和 password return …...
C语言:基础篇之常见概念
文章目录 1.C语言是什么?2.C语言的历史和辉煌3.编译器的选择VS20223.1 编译和链接3.2 编译器的对比3.3 VS2022 的优缺点 4.VS项目和源文件、头文件介绍5.第一个C语言程序6.main函数7.printf和库函数8.关键字介绍9.字符和ASCII编码10.字符串和\011.转义字符12.语句和…...
Ansible模块——管理100台Linux的最佳实践
使用 Ansible 管理 100 台 Linux 服务器时,推荐遵循以下 最佳实践,以提升可维护性、可扩展性和安全性。以下内容结合实战经验进行总结,适用于中大型环境(如 100 台服务器): 一、基础架构设计 1. 分组与分层…...
算法与数据结构:质数、互质判定和裴蜀定理
文章目录 质数质数判定质数筛选质因数分解互质判定裴蜀定理 质数 首先回顾「质数」的定义:若一个正整数无法被除了 1 和它自身之外的任何自然数整除,则称该数为质数(或素数),否则称该正整数为合数。 根据上述定义&…...
基于C#的Modbus通信协议全面解析与实现指南
目录 1. Modbus协议概述 1.1 Modbus网络结构 1.2 Modbus功能码 2. Modbus RTU模式实现 2.1 RTU模式特点 2.2 CRC-16校验算法 2.3 使用NModbus4库实现RTU通信 3. Modbus TCP/IP模式实现 3.1 TCP模式特点 3.2 MBAP报文头结构 3.3 使用NModbus实现TCP通信 3.4 原生TCP套…...
IVX:重构 AI 原生开发范式,让模型调用成为指尖艺术
一、AI 原生开发的技术跃迁:从黑箱集成到白盒重构 在传统 AI 开发范式中,将 GPT-4o、Mediapipe 等模型集成到业务系统往往需要经历 "模型训练 - API 对接 - 前端适配" 的复杂流程。开发团队需同时掌握机器学习框架(如 TensorFlow&…...
源码分析之Leaflet中TileLayer
概述 TileLayer 是 Layer 的子类,继承自GridLayer基类,用于加载和显示瓦片地图。它提供了加载和显示瓦片地图的功能,支持自定义瓦片的 URL 格式和参数。 源码分析 源码实现 TileLayer的源码实现如下: export var TileLayer …...
Java虚拟机 - 程序计数器和虚拟机栈
运行时数据结构 Java运行时数据区程序计数器为什么需要程序计数器执行流程虚拟机栈虚拟机栈作用虚拟机栈核心结构运行机制 Java运行时数据区 首先介绍Java运行时数据之前,我们要了解,对于计算机来说,内存是非常重要的资源,因为内…...
大语言模型 15 - Manus 超强智能体 开源版本 OpenManus 案例与原理深入解析
写在前面 Manus 是由中国初创公司 Monica.im 于 2025 年 3 月推出的全球首款通用型 AI 智能体(AI Agent),旨在实现“知行合一”,即不仅具备强大的语言理解和推理能力,还能自主执行复杂任务,直接交付完整成…...
开源CMS系统中哪些常见的安全漏洞最需要注意?
在当今数字化时代,开源内容管理系统(CMS)因其灵活性和低成本广受欢迎。然而,开源CMS的安全漏洞也频频成为黑客攻击的突破口。本文将带大家全面了解下开源CMS中需要警惕的安全漏洞以及防护建议,以帮助开发者和管理员更好…...
文件包含靶场实现
文件包含漏洞(File Inclusion Vulnerability)是 Web 安全中常见的高危漏洞,主要分为 本地文件包含(LFI) 和 远程文件包含(RFI) 1、典型利用方式 利用方式示例 Payload说明路径遍历?page../../…...
在 JavaScript 中正确使用 Elasticsearch,第二部分
作者:来自 Elastic Jeffrey Rengifo 回顾生产环境中的最佳实践,并讲解如何在无服务器环境中运行 Elasticsearch Node.js 客户端。 想获得 Elastic 认证?查看下一期 Elasticsearch Engineer 培训的时间! Elasticsearch 拥有大量新…...
DataLight(V1.7.12)版本更新发布
DataLight(V1.7.12)版本更新发布 亲爱的 DataLight 用户们, DataLight 发布 V1.7.12 版本,此版本带来了新服务 DINKY 的支持,以及多项问题修复,进一步提升了平台的易用性和稳定性。 一. 更新日志 在此次…...
LeetCode-前缀和-和为K的子数组
LeetCode-前缀和-和为K的子数组 ✏️ 关于专栏:专栏用于记录 prepare for the coding test。 文章目录 LeetCode-前缀和-和为K的子数组📝 和为K的子数组🎯题目描述🔍 输入输出示例🧩题目提示🧪前缀和❓什么…...
MySQL基础关键_014_MySQL 练习题
目 录 一、有以下表,请用一条 SQL 语句查询出每门课程都大于 80 分的学生 二、综合题1(数据自行模拟) 1.查询身份证号为“440401430103082”的申请日期 2.查询同一个身份证号有两条及以上记录的身份证号码及记录个数 3.将身份证号码为“4…...
femap许可与云计算集成
随着云计算技术的迅猛发展,越来越多的企业开始将关键应用和服务迁移到云端,以享受其带来的弹性扩展、高效管理和成本优化等优势。Femap作为一款强大的电磁仿真工具,通过与云计算的集成,将为企业带来前所未有的许可管理和仿真分析体…...
uni-app项目从0-1基础架构搭建全流程
前情 最近新接了一个全新项目,我负责从0开始搭建小程序,我选用的技术栈是uni-app技术栈,UI库选择的是uview-plus,CSS引入现在流行的tainlwindcss,实现CSS原子化书写,实现小程序分包,分包中实现…...
轻量级高性能推理引擎MNN 学习笔记 04.线性回归
1. 线性回归 MNN 官方给的iOS Demo中,输入是图片,输出是分类结果,相对来讲,略微有些复杂,我们现在用一个最简单的线性回归模型,来说明MNN的用法。 该线性回归是yaxb (其中a2,b0.01)…...