当前位置: 首页 > news >正文

C++中string库常用函数超详细解析与深度实践

目录

一、引言

二、基础准备:头文件与命名空间

三、string对象的创建与初始化(基础)

3.1 直接初始化

3.2 动态初始化(空字符串)

3.3 基于字符数组初始化

3.4 重复字符初始化

四、核心函数详解

4.1 字符串长度相关

4.1.1  length()  和  size() 

4.1.2  capacity()  和  reserve() 

4.2 字符串拼接

4.2.1  +  运算符与  +=  复合赋值

4.2.2  append()  函数(不咋好有,不推荐)

4.3 字符串查找

4.3.1  find()  系列函数

4.4 子串提取

4.5 字符串替换

4.5.1  replace()  函数

4.6 字符串比较

4.6.1  compare()  函数

4.6.2 关系运算符(推荐)

4.7 字符串插入(少用,效率太底)

4.8 字符串删除(不推荐,理由如上)

4.9 字符串清空

4.10 字符串遍历

4.10.1 迭代器遍历

4.10.2 范围-based for循环

4.11  getline() 函数

4.12  reverse() 函数

4.13  at() 函数(参考operator[ ])

4.14 数值与字符串转换相关函数

4.14.1  to_string() 函数

4.14.2  atoi() 函数

4.14.3  itoa() 函数(非标准库函数)

4.15  shrink_to_fit() 函数

4.16  assign() 函数(作用类似于覆盖)

五、高级应用与性能优化

5.1  stringstream  流处理

5.2 性能优化技巧

六、总结


一、引言

在C++编程体系中, string  类是处理文本数据的核心组件。相较于传统C风格以  \0  结尾的字符数组, string  类通过封装大量实用函数,不仅避免了手动内存管理的繁琐与安全隐患,还提供了丰富的操作方式,极大提升了字符串处理的便捷性和安全性。本文将对  string  库中常用函数进行深度剖析,结合大量代码示例与注意事项,帮助开发者全面掌握其使用技巧。

二、基础准备:头文件与命名空间

使用  string  类前,必须包含  <string>  头文件,并处理命名空间。常见方式有两种:

cpp

// 方式一:引入整个std命名空间#include <string>using namespace std;// 方式二:显式指定std命名空间#include <string>std::string str;

注意:引入整个  std  命名空间可能引发命名冲突(如自定义函数名与  std  中函数名重复),推荐在小型项目或明确无冲突风险时使用;显式指定命名空间更安全,适合大型项目。

三、string对象的创建与初始化(基础

3.1 直接初始化

cpp

// 字面量初始化string str1 = "Hello, C++";string str2("This is a string");// 拷贝初始化string str3 = str1;

3.2 动态初始化(空字符串)

cpp

string emptyStr; // 长度为0的字符串

3.3 基于字符数组初始化

cpp

char cArray[] = {'H', 'e', 'l', 'l', 'o', '\0'};string strFromArray(cArray);

3.4 重复字符初始化

cpp

string repeated(5, 'a'); // 生成字符串 "aaaaa"

四、核心函数详解

4.1 字符串长度相关

4.1.1  length()  和  size() 

cppstring str = "Programming";size_t len1 = str.length(); // 11size_t len2 = str.size(); // 11

注意:

-  length()  和  size()  功能完全相同, size()  是为了与STL容器接口统一。

- 返回值类型  size_t  是无符号整数,与负数比较时需格外小心,例如:

cppstring str = "test";if (str.length() > -1) { // 永远为真,-1会隐式转换为超大无符号数// ...}

4.1.2  capacity()  和  reserve() 

 capacity()  返回当前字符串已分配的内存空间(以字符为单位); reserve()  用于预分配内存,减少动态扩容次数。

cppstring str;cout << "初始容量: " << str.capacity() << endl; // 可能是15或其他默认值str.reserve(100); // 预分配100个字符的空间cout << "调整后容量: " << str.capacity() << endl; // 至少为100

注意: reserve()  不改变字符串实际长度,仅影响内存分配;若传入参数小于当前容量, reserve()  通常不执行操作。

4.2 字符串拼接

4.2.1  +  运算符与  +=  复合赋值

cppstring str1 = "Hello";string str2 = "World";string result = str1 + ", " + str2; // "Hello, World"

str1 += ", C++"; // 等价于 str1 = str1 + ", C++"

4.2.2  append()  函数(不咋好有,不推荐

cppstring str = "Apple";// 追加字符串str.append(" and Banana"); // "Apple and Banana"// 追加子串(从源字符串第3个位置开始,取4个字符)str.append("Cherry", 3, 4); // "Apple and Bananarry"// 追加字符数组char arr[] = {'!', '\0'};str.append(arr); // "Apple and Bananarry!"

注意: append()  支持多种参数类型,使用时需确保索引和长度合法,避免越界。

4.3 字符串查找

4.3.1  find()  系列函数

cppstring str = "banana";// 查找子串首次出现位置size_t pos1 = str.find("na"); // 2// 查找字符最后出现位置size_t pos2 = str.rfind('a'); // 5// 查找字符集中任意字符首次出现位置size_t pos3 = str.find_first_of("aeiou"); // 1// 查找字符集中未出现的字符首次位置size_t pos4 = str.find_first_not_of("abn"); // string::npos

注意:

- 所有查找函数未找到时均返回  string::npos ,建议使用  if (pos != string::npos)  进行判断。

-  find_first_of()  和  find_last_of()  匹配字符集中任意字符,而非整个集合

4.4 子串提取

cppstring str = "Hello, World";// 提取从索引7开始,长度为5的子串string sub = str.substr(7, 5); // "World"// 若省略长度参数,提取到字符串末尾string subAll = str.substr(7); // "World"

注意:起始索引不能超过字符串长度,否则行为未定义;长度参数过大时,会截取到字符串末尾。

4.5 字符串替换

4.5.1  replace()  函数

cppstring str = "old text";// 从索引4开始,替换4个字符str.replace(4, 4, "new"); // "old new"// 按子串替换(替换所有匹配项)str = "apple apple";str.replace(str.find("apple"), 5, "banana"); // "banana apple"

注意:若要替换所有匹配项,需循环调用  replace() ;替换操作可能改变字符串容量和迭代器状态。

4.6 字符串比较

4.6.1  compare()  函数

cppstring str1 = "apple";string str2 = "banana";int cmp = str1.compare(str2); // cmp < 0

4.6.2 关系运算符(推荐

cppif (str1 < str2) {cout << "str1小于str2" << endl;}

注意:比较规则基于字典序(ASCII码顺序); compare()  可指定子串进行局部比较,如  str1.compare(0, 3, str2, 0, 3) 。

4.7 字符串插入(少用,效率太底

cppstring str = "Hello";// 在索引5处插入字符串str.insert(5, ", World"); // "Hello, World"// 插入多个重复字符str.insert(0, 3, '*'); // "***Hello, World"

注意:插入操作会改变字符串长度和内存布局,可能导致迭代器失效;插入位置需在合法范围内。

4.8 字符串删除(不推荐,理由如上

cppstring str = "Hello, World";// 删除从索引7开始的5个字符str.erase(7, 5); // "Hello, "// 删除单个字符(通过迭代器)str.erase(str.begin() + 5); // "Hello"

注意:使用迭代器删除时,需确保迭代器有效;删除操作后,后续迭代器会失效。

4.9 字符串清空

cppstring str = "data";str.clear(); // 长度变为0,容量可能保留

注意: clear()  仅清空内容,不释放内存;若需释放内存,可使用  str.shrink_to_fit() 。

4.10 字符串遍历

4.10.1 迭代器遍历

cppstring str = "abc";for (string::iterator it = str.begin(); it != str.end(); ++it) {*it = toupper(*it); // 转换为大写}

toupper为示例,以后会将。

4.10.2 范围-based for循环

cppstring str = "123";for (char c : str) {cout << c << endl;}

注意:修改字符串内容时,需使用非  const  迭代器;范围循环中修改元素需通过引用(如  for (char& c : str) )。

4.11  getline() 函数
 


 getline() 函数是C++中用于从输入流中读取整行数据的重要工具,它在处理包含空格或特殊字符的字符串输入时极为实用。(替换cin)该函数定义于 <string> 头文件中,通过指定输入流对象和目标 string 对象,将输入流中的字符按行读取并存储。
 
函数原型:
 
cpp
  

istream& getline(istream& is, string& str, char delim = '\n');


 
 
其中, is 表示输入流(如 cin 用于从控制台读取), str 是用于存储读取结果的 string 对象, delim 是可选参数,用于指定行结束的分隔符,默认值为换行符 \n 。
 
示例代码:
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {string userInput;cout << "请输入一行包含空格的内容(例如:Hello, World!): ";getline(cin, userInput);cout << "你输入的完整内容是: " << userInput << endl;// 指定其他分隔符的示例string data = "apple;banana;cherry";string token;size_t pos = 0;while ((pos = data.find(';')) != string::npos) {token = data.substr(0, pos);cout << "提取的子串: " << token << endl;data.erase(0, pos + 1);}if (!data.empty()) {cout << "最后一个子串: " << data << endl;}return 0;
}


 
 
运行结果:
 

plaintext请输入一行包含空格的内容(例如:Hello, World!): This is a test line.
你输入的完整内容是: This is a test line.
提取的子串: apple
提取的子串: banana
最后一个子串: cherry


注意事项:
 
1. 输入流状态检查:当输入流发生错误(如磁盘读取错误)或到达文件末尾(EOF)时, getline() 会停止读取并使输入流进入错误状态。可以通过 if (cin) 或 cin.good() 检查输入流是否处于有效状态。
 
2. 分隔符处理:若指定了非默认分隔符(如上述代码中的 ; ), getline() 会读取字符直至遇到该分隔符。分隔符本身会被读取但不会存储到目标 string 中。
 
3. 缓冲区残留问题:在使用 getline() 之前如果有其他输入操作(如 cin >> num 读取数字),可能会在输入缓冲区中残留换行符。此时可以先用 cin.ignore() 清除缓冲区残留字符,再调用 getline() ,避免读取到空字符串。
 
4. 性能考量: getline() 每次读取都会动态分配内存来存储字符串,频繁调用可能影响性能。在处理大量数据时,可以预先使用 reserve() 为目标 string 分配足够的空间。
 


4.12  reverse() 函数
 


 reverse() 函数用于反转字符串中字符的顺序,定义于 <algorithm> 头文件中,属于STL(标准模板库)算法的一部分。它通过操作迭代器范围来实现字符串反转,适用于需要快速颠倒字符串内容的场景。
 
函数原型:
 

cpptemplate<class BidirectionalIterator>
void reverse(BidirectionalIterator first, BidirectionalIterator last);


 
 
其中, first 和 last 是双向迭代器,指定要反转的字符范围(左闭右开区间,即包含 first 指向的字符,不包含 last 指向的字符)。
 
示例代码:
 

cpp#include <iostream>
#include <string>
#include <algorithm>
using namespace std;int main() {string original = "C++ is powerful";cout << "原始字符串: " << original << endl;reverse(original.begin(), original.end());cout << "反转后的字符串: " << original << endl;// 反转子串示例string subStr = "hello, world";reverse(subStr.begin() + 7, subStr.end());cout << "反转部分子串后的结果: " << subStr << endl;return 0;
}


 
运行结果:
 

plaintext原始字符串: C++ is powerful
反转后的字符串: lufrewop si ++C
反转部分子串后的结果: hello, dlrow


 注意事项:
 
1. 迭代器有效性:传递给 reverse() 的迭代器必须指向有效的内存位置,且 last 迭代器需在 first 迭代器之后(指向更大的地址),否则会导致未定义行为。
 
2. 对其他容器的适用性: reverse() 不仅适用于 string ,还可用于其他支持双向迭代器的容器(如 vector<char> ),但需确保容器类型兼容。
 
3. 性能与内存: reverse() 操作通常效率较高,因为它仅改变字符顺序,不涉及额外的内存分配。但对于大型字符串,操作过程中可能会占用一定的栈空间。
 


4.13  at() 函数(参考operator[ ])
 


 at() 函数是 string 类提供的成员函数,用于访问字符串中指定位置的字符。与通过 [] 运算符访问字符不同, at() 函数会进行严格的越界检查,若访问位置超出字符串长度,会抛出 std::out_of_range 异常。
 
函数原型:
 

cppchar& at(size_t pos);
const char& at(size_t pos) const;


 
 
其中, pos 是要访问的字符的索引位置(从0开始)。非 const 版本返回可修改的字符引用, const 版本用于常量字符串,返回常量字符引用。
 
示例代码:
 

cpp#include <iostream>
#include <string>
#include <exception>
using namespace std;int main() {string text = "example";try {char normalChar = text.at(3);cout << "正常访问索引3处的字符: " << normalChar << endl;char badChar = text.at(10);  // 触发越界异常} catch (const out_of_range& e) {cerr << "捕获到异常: " << e.what() << endl;}// 与[]运算符对比try {char safeChar = text[3];char riskyChar = text[10];  // 不会抛出异常,但结果未定义cout << "使用[]访问越界位置未触发异常,结果不可靠" << endl;} catch (...) {cerr << "使用[]访问未触发异常捕获" << endl;}return 0;
}


 
运行结果:
 
plaintext
  
正常访问索引3处的字符: a
捕获到异常: basic_string::at: __n (which is 10) >= this->size() (which is 7)
使用[]访问越界位置未触发异常,结果不可靠
 
 
注意事项:
 
1. 异常处理成本: at() 的越界检查和异常抛出机制增加了代码的安全性,但也带来了性能开销。在已知索引合法的场景下(如遍历字符串),使用 [] 运算符可能更高效。
 
2. 字符修改:通过 at() 返回的引用可以修改字符串中的字符,但需确保字符串本身是非 const 类型。
 
3. 索引类型: at() 的参数类型为 size_t (无符号整数),传入负数会导致编译错误或未定义行为。
 


4.14 数值与字符串转换相关函数
 


4.14.1  to_string() 函数
 


 to_string() 函数是C++11引入的标准库函数,用于将基本数值类(如 int 、 double 、 long 等)转换为对应的字符串表示。它极大简化了数值与文本之间的转换过程。
 
函数原型:
 

cppstring to_string(int val);
string to_string(long val);
string to_string(long long val);
string to_string(unsigned val);
string to_string(unsigned long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);


 
 
每个重载版本对应不同的数值类型,返回值为转换后的字符串。
 
示例代码:
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {int numInt = 123;double numDouble = 3.14159;string strInt = to_string(numInt);string strDouble = to_string(numDouble);cout << "整数 " << numInt << " 转换为字符串: " << strInt << endl;cout << "浮点数 " << numDouble << " 转换为字符串: " << strDouble << endl;// 拼接字符串示例string result = "The value is " + to_string(numDouble) + " and the count is " + to_string(numInt);cout << result << endl;return 0;
}


 
运行结果:
 

plaintext整数 123 转换为字符串: 123
浮点数 3.14159 转换为字符串: 3.141590
The value is 3.141590 and the count is 123


注意事项:
 
1. 精度控制:对于浮点数转换, to_string() 默认保留6位小数。如需自定义精度,可使用 stringstream 或 std::format (C++20)等工具。
 
2. 性能优化:虽然 to_string() 方便易用,但频繁调用可能产生大量临时字符串对象。在性能敏感场景下,可预先计算字符串长度并使用 std::snprintf 等C风格函数手动构建字符串。
 


4.14.2  atoi() 函数
 


 atoi() ( ASCII to Integer )函数用于将字符串转换为整数,其功能仅限于处理以数字开头的字符串,并在遇到非数字字符时停止转换。该函数定义于 <cstdlib> 头文件中,同时还有 atol() (转换为 long )、 atoll() (转换为 long long )等变体。
 
函数原型:
 

cppint atoi(const char* str);


 
 
参数 str 是指向以 \0 结尾的字符数组的指针,返回值为转换后的整数。若字符串无法转换(如开头非数字),返回0。
 
示例代码:
 

cpp#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;int main() {string numStr = "42abc";int result = atoi(numStr.c_str());cout << "字符串 \"" << numStr << "\" 转换为整数: " << result << endl;string badStr = "abc123";int badResult = atoi(badStr.c_str());cout << "无法转换的字符串 \"" << badStr << "\" 结果: " << badResult << endl;return 0;
}


 
运行结果:
 

plaintext字符串 "42abc" 转换为整数: 42
无法转换的字符串 "abc123" 结果: 0


注意事项:
 
1. 参数类型转换:由于 atoi() 接受 const char* 类型参数,使用 string 对象时需调用 c_str() 方法进行转换。
 
2. 错误处理: atoi() 无法区分输入错误(如非数字开头)和有效输入(如字符串 "0" ),需要额外逻辑判断输入合法性。
 
3. 溢出风险:若转换结果超出 int 类型的表示范围(如 2147483647 以上的正数), atoi() 的行为未定义。建议使用 std::stoi 等更安全的C++风格转换函数替代。
 


4.14.3  itoa() 函数(非标准库函数)
 


 itoa() ( Integer to ASCII )函数用于将整数转换为字符串,但其并非C++标准库的一部分,不同编译器和平台的实现存在差异。例如,在Windows平台的Visual C++中可直接使用,而在Linux的GCC中需通过 sprintf(C) 或 std::stringstream 等方式替代。
 
Windows平台示例代码:
 

cpp#include <iostream>
#include <string>
#include <stdlib.h>  // 包含itoa定义(Windows特定)
using namespace std;int main() {int number = -123;char buffer[20];itoa(number, buffer, 10);  // 第二个参数是目标字符数组,第三个参数是进制数(10表示十进制)string result(buffer);cout << "整数 " << number << " 转换为字符串: " << result << endl;return 0;
}


 
运行结果:
 

plaintext整数 -123 转换为字符串: -123


 
 
替代方案(GCC/Linux):
 

cpp#include <iostream>
#include <string>
#include <sstream>
using namespace std;string customItoa(int num) {stringstream ss;ss << num;return ss.str();
}int main() {int number = 456;string result = customItoa(number);cout << "整数 " << number << " 转换为字符串: " << result << endl;return 0;
}


注意事项:
 
1. 可移植性问题:由于 itoa() 不属于标准库,使用该函数会导致代码在不同平台间无法直接移植。为确保兼容性,推荐使用 to_string() 或 stringstream 等标准方法。
 
2. 缓冲区管理:在使用 itoa() 时,需手动指定目标字符数组的大小,若数组空间不足,可能导致缓冲区溢出。
 
3. 功能局限性: itoa() 仅支持有限的进制转换(如2、8、10、16),而 stringstream 等方式可更灵活地控制输出格式。

4.15  shrink_to_fit() 函数
 


 shrink_to_fit()  函数是  string  类的成员函数,用于释放字符串中未使用的额外内存,将字符串的容量( capacity )调整为当前实际使用的大小( size )。在对字符串进行了多次插入、删除操作后,字符串的容量可能会大于实际存储字符所需的空间(空间对齐), shrink_to_fit()  函数可以帮助优化内存使用。(如果数据没有clear,则shrink_to_fit不会删除空间)
 
函数原型:
 

cppvoid shrink_to_fit();


 
 
该函数没有参数,也没有返回值,直接对调用它的  string  对象进行内存调整操作。
 
示例代码:
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {string str = "initial string";cout << "初始容量: " << str.capacity() << endl;cout << "初始大小: " << str.size() << endl;// 进行一些操作,可能导致容量增加for (int i = 0; i < 100; ++i) {str += 'a';}cout << "操作后的容量: " << str.capacity() << endl;cout << "操作后的大小: " << str.size() << endl;str.shrink_to_fit();cout << "调用shrink_to_fit后的容量: " << str.capacity() << endl;cout << "调用shrink_to_fit后的大小: " << str.size() << endl;return 0;
}


 
运行结果(示例,实际结果可能因编译器和平台不同而有所差异):
 

plaintext初始容量: 31
初始大小: 14
操作后的容量: 127
操作后的大小: 114
调用shrink_to_fit后的容量: 114
调用shrink_to_fit后的大小: 114

注意事项:
 
1. 并非保证完全释放内存:虽然  shrink_to_fit()  的目的是释放未使用的内存,但具体的实现可能会因为编译器和标准库的不同而有所差异,有些情况下可能无法将容量精确地调整为大小,或者可能会保留一些额外的内存空间。
 
2. 可能导致迭代器失效:调用  shrink_to_fit()  函数会改变字符串的内存布局,因此在调用该函数之前获取的所有迭代器、引用和指针都将失效,使用它们会导致未定义行为。
 
3. 性能影响:执行  shrink_to_fit()  操作可能涉及重新分配内存和复制数据,对于大型字符串,这可能会带来一定的性能开销,因此在性能敏感的场景中,需要谨慎使用。
 


4.16  assign() 函数(作用类似于覆盖)
 

assign()  函数是  string  类的成员函数,用于将一个新的字符串值赋给当前  string  对象,它提供了多种重载形式,可以以不同的方式指定要赋值的内容。
 
函数原型及示例:
 
1. 赋值字符串字面量:
 

cppstring& assign(const char* s);


 
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {string str;str.assign("new string value");cout << "赋值后的字符串: " << str << endl;return 0;
}


 
 
运行结果:
 

plaintext赋值后的字符串: new string value


 
 
1. 赋值另一个  string  对象:
 

cppstring& assign(const string& s);cpp#include <iostream>
#include <string>
using namespace std;int main() {string str1 = "original";string str2;str2.assign(str1);cout << "str2赋值后的内容: " << str2 << endl;return 0;
}


 
运行结果:
 

plaintextstr2赋值后的内容: original


 
 
1. 赋值字符串的子串:
 

cppstring& assign(const char* s, size_t n);


 
其中  s  是字符指针, n  是要复制的字符个数。
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {string str;const char* source = "abcdefg";str.assign(source, 3);cout << "赋值子串后的字符串: " << str << endl;return 0;
}


 
运行结果:
 

plaintext赋值子串后的字符串: abc


 
 
1. 重复赋值字符:
 

cppstring& assign(size_t n, char c);


 
 
其中  n  是重复的次数, c  是要重复的字符。
 

cpp#include <iostream>
#include <string>
using namespace std;int main() {string str;str.assign(5, '*');cout << "重复赋值字符后的字符串: " << str << endl;return 0;
}


 
 
运行结果:
 

plaintext重复赋值字符后的字符串: *****

注意事项:
 
1. 覆盖原有内容: assign()  函数会完全覆盖当前  string  对象的原有内容,因此在调用该函数之前需要确保不再需要原有的字符串数据。
 
2. 内存管理:根据赋值的内容不同, assign()  可能会重新分配内存来存储新的字符串。如果新字符串比原字符串大,会进行内存扩容;如果新字符串比原字符串小,可能会导致内存释放或保留(取决于具体实现)。
 
3. 迭代器和引用失效:由于  assign()  会改变字符串的内容和长度,可能会导致之前获取的迭代器、引用和指针失效,使用它们会导致未定义行为。在调用  assign()  之后,如果需要使用迭代器等,应该重新获取。

五、高级应用与性能优化

5.1  stringstream  流处理

 stringstream  用于字符串与其他数据类型的转换,例如:

cpp#include <sstream>string numStr = "123";int num;stringstream ss(numStr);ss >> num; // num = 123

5.2 性能优化技巧

- 预分配内存:使用  reserve()  减少动态扩容次数。

- 避免频繁拷贝:优先使用  std::move()  转移字符串所有权,减少深拷贝开销。

- 临时对象复用:避免在循环中创建大量临时  string  对象。

六、总结

C++  string  库的函数体系覆盖了字符串处理的全生命周期,从基础创建、拼接、查找,到复杂的替换、性能优化,每个函数都有其独特的应用场景。开发者在使用时需注意边界条件、内存管理和迭代器有效性等问题,结合实际需求灵活运用,才能发挥  string  类的最大效能。通过不断实践和总结,能够更高效地处理文本数据,提升C++程序的稳定性与性能。

相关文章:

C++中string库常用函数超详细解析与深度实践

目录 一、引言 二、基础准备&#xff1a;头文件与命名空间 三、string对象的创建与初始化(基础&#xff09; 3.1 直接初始化 3.2 动态初始化&#xff08;空字符串&#xff09; 3.3 基于字符数组初始化 3.4 重复字符初始化 四、核心函数详解 4.1 字符串长度相关 4.1.1 …...

数据结构(3)

实验步骤&#xff1a; 任务&#xff1a;要求使用自定义函数来实现 输入一段文本&#xff0c;统计每个字符出现的次数&#xff0c;按照字符出现次数从多到少&#xff0c;依次输出&#xff0c;格式如下&#xff1a; 字符1-个数 字符2-个数 ...... 解题思路&#xff1a; 构建结构体…...

【C++教程】使用printf语句实现进制转换

在C语言中&#xff0c;printf 函数可以直接实现部分进制转换功能&#xff0c;通过格式说明符&#xff08;format specifier&#xff09;快速输出不同进制的数值。以下是详细使用方法及示例代码&#xff1a; 一、printf 原生支持的进制转换 1. 十进制、八进制、十六进制转换 #…...

el-dialog设置append-to不生效;el-dialog设置挂载层级

文章目录 一、场景二、注意点1. append-to-body何时为true2.设置层级&#xff0c;遮罩层大小不生效3.相关代码 三、ElMessageBox遮罩层 效果&#xff1a; 一、场景 正常情况下&#xff0c;el-dialog的弹框是挂载在body下的&#xff0c;导致我们会有修改样式或者修改弹框的遮罩…...

互联网软件开发自动化平台 的多维度对比分析,涵盖架构、功能、适用场景、成本等关键指标

以下是关于 互联网软件开发自动化平台 的详细解析&#xff0c;涵盖其核心概念、主流平台的功能、架构设计、适用场景及对比分析&#xff1a; 一、自动化平台的定义与核心目标 自动化平台&#xff08;如CI/CD平台&#xff09;是用于 持续集成&#xff08;CI&#xff09; 和 持续…...

UE5 制作方块边缘渐变边框效果

该效果基于之前做的&#xff08;https://blog.csdn.net/grayrail/article/details/144546427&#xff09;进行修改得到&#xff0c;思路也很简单&#xff1a; 1.打开实时预览 1.为了制作时每个细节调整方便&#xff0c;勾选Live Update中的三个选项&#xff0c;开启实时预览。…...

深入探究 GRU 模型:梯度爆炸问题剖析

在深度学习领域&#xff0c;循环神经网络&#xff08;RNN&#xff09;及其变体在处理序列数据时展现出了强大的威力。其中&#xff0c;门控循环单元&#xff08;GRU&#xff09;作为 RNN 的一种进阶架构&#xff0c;备受关注。今天&#xff0c;咱们就来深入聊聊 GRU 模型&#…...

生成对抗网络(GAN)原理详解

生成对抗网络&#xff08;GAN&#xff09;原理详解 1. 背景 生成对抗网络&#xff08;Generative Adversarial Network, GAN&#xff09;由 Ian Goodfellow 等人于 2014 年提出&#xff0c;是一种通过对抗训练生成高质量数据的框架。其核心思想是让两个神经网络&#xff08;生…...

CFD中的动量方程非守恒形式详解

在计算流体力学&#xff08;CFD&#xff09;中&#xff0c;动量方程可以写成守恒形式和非守恒形式&#xff0c;两者在数学上等价&#xff0c;但推导方式和应用场景不同。以下是对非守恒形式的详细解释&#xff1a; 1. 动量方程的守恒形式 首先回顾守恒形式的动量方程&#xff…...

AIoT 智变浪潮演讲实录 | 刘浩然:让硬件会思考:边缘大模型网关助力硬件智能革新

4 月 2 日&#xff0c;由火山引擎与英特尔联合主办的 AIoT “智变浪潮”技术沙龙在深圳成功举行&#xff0c;活动聚焦 AI 硬件产业的技术落地与生态协同&#xff0c;吸引了芯片厂商、技术方案商、品牌方及投资机构代表等 700 多位嘉宾参会。 会上&#xff0c;火山引擎边缘智能高…...

4.B-树

一、常见的查找方式 顺序查找 O(N) 二分查找 O(logN)(要求有序和随机访问) 二叉搜索树 O(N) 平衡二叉搜索树(AVL树和红黑树) O(logN) 哈希 O(1) 考虑效率和要求而言,正常选用 平衡二叉搜索树 和 哈希 作为查找方式。 但这两种结构适合用于数据量相对不是很大,能够一次性…...

怎么看英文论文 pdf沉浸式翻译

https://arxiv.org/pdf/2105.09492 Immersive Translate Xournal打开...

计算机三级第一章:信息安全保障概述(以时间节点推进的总结)

淡蓝色为必背内容 第一阶段:电讯技术的发明19世纪30年代:电报电话的发明 1835年:莫尔斯(Morse)发明了电报 1837年:莫尔斯电磁式有线电报问世 1878年:人工电话交换局出现 1886年:马可尼发明了无线电报机 1876年:贝尔(Bell)发明了电话机 1892年,史瑞桥自动交换…...

车载软件架构 ---单个ECU的AUTOSAR开发流程

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

【场景应用7】在TPU上使用Flax/JAX对Transformers模型进行语言模型预训练

在本笔记本中,我们将展示如何使用Flax在TPU上预训练一个🤗 Transformers模型。 这里将使用GPT2的因果语言建模目标进行预训练。 正如在这个基准测试中所看到的,使用Flax/JAX在GPU/TPU上的训练通常比使用PyTorch在GPU/TPU上的训练要快得多,而且也可以显著降低成本。 Fla…...

C++运算符重载全面总结

C运算符重载全面总结 运算符重载是C中一项强大的特性&#xff0c;它允许程序员为自定义类型定义运算符的行为。以下是关于C运算符重载的详细总结&#xff1a; 一、基本概念 1. 什么是运算符重载 运算符重载是指为自定义类型&#xff08;类或结构体&#xff09;重新定义或重…...

PTA | 实验室使用排期

目录 题目&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 样例解释&#xff1a; 代码&#xff1a; 无注释版&#xff1a; 有注释版&#xff1a; 题目&#xff1a; 受新冠疫情影响&#xff0c;当前大家的活动都…...

3.7 字符串基础

字符串 &#xff08;str&#xff09;&#xff1a;和列表用法基本一致 1.字符串的创建 -str转换(字符串&#xff0c;可用于将其他字符类型转换为字符串) -单引号 双引号 三引号 2.索引 3.字符串的切片 4.字符串的遍历 5.字符串的格式化 6.字符串的运算符 7.字符串的函数 #…...

《 C++ 点滴漫谈: 三十三 》当函数成为参数:解密 C++ 回调函数的全部姿势

一、前言 在现代软件开发中&#xff0c;“解耦” 与 “可扩展性” 已成为衡量一个系统架构优劣的重要标准。而在众多实现解耦机制的技术手段中&#xff0c;“回调函数” 无疑是一种高效且广泛使用的模式。你是否曾经在编写排序算法时&#xff0c;希望允许用户自定义排序规则&a…...

16bit转8bit的常见方法(图像归一化)

文章目录 16-bit转8-bit的常用方法一、数据类型转换&#xff1a;image.astype(np.uint8) —— 若数值 x 超出 0-255 范围&#xff0c;则取模运算。如&#xff1a;x 600 % 256 88二、截断函数&#xff1a;np.clip().astype(np.uint8) —— 若数值 x 超出 0-255 范围&#xff0…...

消息中间件kafka,rabbitMQ

在分布式系统中,消息中间件是实现不同组件之间异步通信的关键技术。Kafka 和 RabbitMQ 是两个非常流行的消息中间件系统,它们各自有着不同的特点和应用场景。下面将分别介绍 Kafka 和 RabbitMQ,并讨论它们在消息队列中的使用。 一、Kafka (Apache Kafka) 主要特点: 高吞吐…...

C语言编译预处理3

条件编译&#xff1a;是对源程序的一部分指定编译条件&#xff0c;满足条件进行编译否则不编译。 形式1 #indef 标识符 程序段1 #else 程序段2 #endif 标识符已经被定义用#ifdef #include <stdio.h>// 可以通过注释或取消注释下面这行来控制是否定义 DEBUG 宏 // …...

数据结构·树

树的特点 最小连通图 无环 有且只有 n − 1 n-1 n−1 条边 树的建立方式 顺序存储 只适用于满n叉树&#xff0c;完全n叉树 1<<n 表示结点 2 n 2^n 2nP4715 【深基16.例1】淘汰赛 void solve() {cin >> n;for (int i 0; i<(1<<n); i) {cin >&g…...

队列的各种操作实现(数据结构C语言多文件编写)

1.先创建queue.h声明文件(Linux命令&#xff1a;touch queue.h)。编写函数声明如下(打开文件 Linux 操作命令&#xff1a;vim queue.h): //头文件 #ifndef __QUEUE_H__ #define __QUEUE_H__ //队列 typedef struct queue{int* arr;int in;int out;int cap;int size; }queue_t;…...

48V/2kW储能电源纯正弦波逆变器详细设计方案-可量产

48V/2kW储能电源纯正弦波逆变器详细设计方案 1.后级驱动电路图 2.前级驱动电路图 3.功率表电路原理图 4.功率板BOM: 5.后级驱动BOM 6.前级驱动BOM...

[redis进阶二]分布式系统之主从复制结构(2)

目录 一 redis的拓扑结构 (1)什么是拓扑 (2)⼀主⼀从结构 (3)⼀主多从结构 (4)树形主从结构 (5)三种拓扑结构的优缺点,以及适用场景 二 redis的复制原理 (1)复制过程 (2)数据同步psync replicationid/replid (复制id)(标注同步的数据来自哪里:数据来源) offset (偏移…...

Playwright多语言生态:跨Python_Java_.NET的统一采集方案

一、问题背景&#xff1a;爬虫多语言割裂的旧时代 在大规模数据采集中&#xff0c;尤其是学术数据库如 Scopus&#xff0c;开发者常遇到两个经典问题&#xff1a; 技术语言割裂&#xff1a;Python开发人员使用Selenium、requests-html等库&#xff1b;Java阵营使用Jsoup或Htm…...

day30 第八章 贪心算法 part04

452. 用最少数量的箭引爆气球 先排序&#xff0c;再算重叠区间 class Solution:def findMinArrowShots(self, points: List[List[int]]) -> int:if len(points)0:return 0points.sort(keylambda x:x[0])result 1for i in range(1, len(points)):if points[i][0] > point…...

java操作redis库,开箱即用

application.yml spring:application:name: demo#Redis相关配置redis:data:# 地址host: localhost# 端口&#xff0c;默认为6379port: 6379# 数据库索引database: 0# 密码password:# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最…...

clickhouse中的窗口函数

窗口函数 边界核心参数 窗口边界通过 ROWS、RANGE 或 GROUPS 模式定义,语法为: ROWS BETWEEN AND 基于 ​物理行位置 定义窗口,与排序键的实际值无关,适用于精确控制窗口行数 – 或 RANGE BETWEEN AND 基于 ​排序键的数值范围 定义窗口,适用于时间序列或连续数值的场景(…...

YZ系列工具之YZ02:字典的多功能应用

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套一部VBA手册&#xff0c;教程分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的…...

金山科技在第91届中国国际医疗器械博览会CMEF 首发新品 展现智慧装备+AI

4月8日—11日&#xff0c;国家会展中心&#xff08;上海&#xff09;&#xff0c;第91届中国国际医疗器械&#xff08;春季&#xff09;博览会&#xff08;以下简称“CMEF 2025”&#xff09;举办。金山科技在盛会上隆重推出年度新品——全高清电子内镜光学放大镜与肛肠测压系统…...

STM32 BOOT设置,bootloader,死锁使用方法

目录 BOOT0 BOOT1的配置含义 bootloader使用方法 芯片死锁解决方法开发调试过程中&#xff0c;由于某种原因导致内部Flash锁死&#xff0c;无法连接SWD以及JTAG调试&#xff0c;无法读到设备&#xff0c;可以通过修改BOOT模式重新刷写代码。修改为BOOT01&#xff0c;BOOT10…...

机器学习:让数据开口说话的科技魔法

在人工智能飞速发展的今天&#xff0c;「机器学习」已成为推动数字化转型的核心引擎。无论是手机的人脸解锁、网购平台的推荐系统&#xff0c;还是自动驾驶汽车的决策能力&#xff0c;背后都离不开机器学习的技术支撑。那么&#xff0c;机器学习究竟是什么&#xff1f;它又有哪…...

PDF解析示例代码学习

以下是结合多种技术实现的PDF解析详细示例&#xff08;Python实现&#xff09;&#xff0c;涵盖文本、表格和扫描件处理场景&#xff1a; 一、环境准备与依赖安装 # 核心依赖库 pip install pdfplumber tabula-py pytesseract opencv-python mysql-connector-python 二、完整…...

【云平台监控】安装应用Ansible服务

安装应用Ansible服务 文章目录 安装应用Ansible服务资源列表基础环境一、安装Ansible1.1、部署Ansible1.2、配置主机清单1.2.1、方法11.2.2、方法2 二、Ansible命令应用基础2.1、ping模块2.2、command模块2.3、user模块2.4、group模块2.5、cron模块2.6、copy模块2.7、file模块2…...

项目执行中的目标管理:从战略到落地的闭环实践

——如何让目标不“跑偏”、团队不“掉队”&#xff1f; 引言&#xff1a;为什么目标管理决定项目成败&#xff1f; 根据PMI研究&#xff0c;47%的项目失败源于目标模糊或频繁变更。在复杂多变的项目环境中&#xff0c;目标管理不仅是制定KPI&#xff0c;更是构建“方向感-执行…...

如何优雅地处理 API 版本控制?

API 会不断发展&#xff0c;而用户的需求也会随之变化。那么&#xff0c;如何确保你的 API 在升级时不会影响现有用户&#xff1f;答案就是&#xff1a;API 版本控制。就像你更新了一个应用程序&#xff0c;引入了新功能&#xff0c;但旧功能仍然保留&#xff0c;让老用户继续愉…...

如何通过Radius认证服务器实现虚拟云桌面安全登录认证:安当ASP身份认证系统解决方案

引言&#xff1a;虚拟化时代的安全挑战 随着云计算和远程办公的普及&#xff0c;虚拟云桌面&#xff08;如VMware Horizon、Citrix&#xff09;已成为企业数字化办公的核心基础设施。然而&#xff0c;传统的用户名密码认证方式暴露了诸多安全隐患&#xff1a;弱密码易被暴力破…...

自然语言处理spaCy

spaCy 是一个流行的开源 自然语言处理&#xff08;NLP&#xff09; 库&#xff0c;专注于 高效、易用和工业化应用。它由 Explosion AI 开发&#xff0c;广泛应用于文本处理、信息提取、机器翻译等领域。 zh_core_web_sm 是 spaCy 提供的一个小型中文预训练语言模型&#xff0…...

大语言模型(LLMs)中的强化学习(Reinforcement Learning, RL)

第一部分&#xff1a;强化学习基础回顾 在深入探讨LLMs中的强化学习之前&#xff0c;我们先快速回顾一下强化学习的核心概念&#xff0c;确保基础扎实。 1. 强化学习是什么&#xff1f; 强化学习是一种机器学习范式&#xff0c;目标是让智能体&#xff08;Agent&#xff09;…...

数字后端实现Innovus DRC Violation之如何利用脚本批量解决G4:M7i DRC Violation

大家在跑完物理验证calibre DRC之后&#xff0c;会发现DRC里面存在一种G4:M7i的DRC违例&#xff0c;这种违例一般都是出现在memory的边界。今天教大家如何利用脚本来批量处理这一类DRC问题的解决。 首先&#xff0c;我们需要把calibre的DRC结果读取到innovus里面来&#xff0c…...

Java版企业电子招标采购系统源业码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…...

CTF web入门之文件上传

知识点 产生文件上传漏洞的原因 原因: 对于上传文件的后缀名(扩展名)没有做较为严格的限制 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件) 对于web server对于上传…...

ArmSoM Sige5 CM5:RK3576 上 Ultralytics YOLOv11 边缘计算新标杆

在计算机视觉技术加速落地的今天&#xff0c;ArmSoM 正式宣布其基于 ​​Rockchip RK3576​​ 的旗舰产品 ​​Sige5 开发板​​ 和 ​​CM5 核心板​​ 全面支持 Ultralytics YOLOv11 模型的 RKNN 部署。这一突破标志着边缘计算领域迎来新一代高性能、低功耗的 AI 解决方案&am…...

游戏引擎学习第224天

回顾游戏运行并指出一个明显的图像问题。 回顾一下之前那个算法 我们今天要做一点预加载的处理。上周刚完成了游戏序章部分的所有剪辑内容。在运行这一部分时&#xff0c;如果观察得足够仔细&#xff0c;就会注意到一个问题。虽然因为视频流压缩质量较低&#xff0c;很难清楚…...

PN1-S25系列ProfiNet网关模组产品方案

PN1-S25系列ProfiNet网关模组是一款专为工业通信环境设计的先进设备&#xff0c;旨在实现ProfiNet与Modbus RTU协议之间的无缝转换&#xff0c;从而优化工业自动化系统中的数据传输效率。以下是对该系列ProfiNet网关模组产品的详细介绍&#xff1a; 一、ProfiNet网关模组功能特…...

提示工程指南学习记录(三)

提示词示例 文本概括 Explain the above in one sentence&#xff08;用一句话解释上面的信息&#xff09;&#xff1a; 提示词工程是一种用于自然语言处理的任务&#xff0c;目的是通过给定的文本或语音输入来生成相应的输出。它基于预训练的大型语言模型&#xff0c;例如通…...

04 GE - 钳制属性,等级

1.PostGameplayEffectExecute 1.作用&#xff1a;在这里对生命值进行最后的钳制防止越界。 2.参数中有什么&#xff1a; FGameplayEffectModCallbackData //传进来的值 {EffectSpec; //GESpecTargetASC //目标ASCFGameplayModifierEvaluatedData& EvaluatedData{Magni…...

【机器学习】机器学习笔记

1 机器学习定义 计算机程序从经验E中学习&#xff0c;解决某一任务T&#xff0c;进行某一性能P&#xff0c;通过P测定在T上的表现因经验E而提高。 eg&#xff1a;跳棋程序 E&#xff1a; 程序自身下的上万盘棋局 T&#xff1a; 下跳棋 P&#xff1a; 与新对手下跳棋时赢的概率…...