C++学习之STL学习

news2025/5/12 16:38:03

        在经过前面的简单的C++入门语法的学习后,我们开始接触C++最重要的组成部分之一:STL

目录

STL的介绍

        什么是STL

        STL的历史

UTF-8编码原理(了解)

UTF-8编码原理

核心编码规则

规则解析

编码步骤示例

1. 确定码点范围

2. 转换为二进制

3. 按格式填充数据位

4. 合并字节序列

UTF-8编码示例表

UTF-8的核心优势

与其他编码的对比

实际应用场景

string类

        为什么要学习string类?

        标准库中的string类

        string类(了解)

        auto和范围for

        auto关键字

范围for 

        string类的常用接口说明

         string类对象的容量操作

string的遍历

一、[]运算符重载介绍

二、迭代器

三、范围for (C++11)

string类对象的修改操作

string类非成员函数

迭代器的介绍

迭代器的概念与分类

string中迭代器的获取方式

迭代器的基本操作

涉及迭代器的string成员函数

与STL算法结合使用

迭代器失效问题

实际应用示例

迭代器的意义:

一些string类的例题

        1.仅仅反转字母

        2.查找字符串中第一个唯一的字符


STL的介绍

        什么是STL

        STL是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个保罗数据结构和算法的软件框架

        STL的历史

C++ STL版本历史发展总览

标准版本发布时间新增组件与特性关键特性与改进影响与意义
C++981998- 容器:vectorlistdequesetmap
- 算法:sortfindcopy
- 迭代器、函数对象、适配器
首次将STL纳入C++标准,确立泛型编程范式。奠定了现代C++标准库的基础,成为工业级开发的标配。
C++032003- 无新增组件技术性修订,修复C++98中的缺陷和模糊定义。提升跨平台一致性,稳定了STL的实现。
C++112011- 新容器:unordered_mapunordered_setarrayforward_list
- 智能指针:shared_ptrunique_ptr
- 移动语义支持
- 引入右值引用和移动语义
- 支持Lambda表达式
- 线程安全组件(如std::thread
现代化STL,显著提升性能和灵活性,推动多核编程。
C++142014- 泛型Lambda
std::exchangestd::quoted
优化C++11特性,增强泛型编程能力。简化代码,提升开发效率。
C++172017std::optionalstd::variantstd::string_view
std::filesystem
- 并行算法
- 文件系统标准化
- 并行执行算法(如std::sort支持多线程)
强化实用性和性能,支持现代硬件并行计算。
C++202020- 范围库(std::ranges
- 概念(Concepts)
std::spanstd::format
- 链式操作简化算法调用(如views::filter
- 约束模板参数,提升编译期类型安全。
革命性改进,代码更简洁、安全,支持函数式编程风格。
C++232023std::flat_mapstd::flat_set
std::ranges::to
- 网络库(提案中)
- 扁平化关联容器优化性能
- 网络编程接口标准化(进行中)
进一步优化数据结构和算法,扩展应用领域(如网络和嵌入式)。

各版本核心改进对比

特性分类C++98C++11C++17C++20
容器基础线性/关联容器哈希容器、固定数组类型安全联合体、文件系统范围视图、span
算法基础泛型算法支持Lambda和移动语义并行算法、随机抽样范围库链式操作
内存管理原始指针智能指针(shared_ptr内存资源管理(PMR)无重大更新
并发支持std::threadstd::mutex无重大更新无重大更新
元编程基础模板类型推导(auto结构化绑定、if constexpr概念(Concepts)
实用性工具std::functionstd::bindstd::optionalstd::anystd::formatstd::chrono

关键版本里程碑

  1. C++98:STL标准化,泛型编程成为主流。

  2. C++11:现代化改造,支持移动语义和多线程。

  3. C++17:实用工具扩展,文件系统和并行计算。

  4. C++20:范围库和概念,代码简洁性与安全性飞跃。

  5. C++23:扁平化容器和网络库,优化高性能场景。

主流STL实现对比

实现名称所属编译器特点
libstdc++GCC兼容性强,支持旧标准,广泛用于Linux系统。
libc++Clang/LLVM轻量高效,积极支持新标准(如C++20特性)。
MSVC STLMSVC深度集成Windows生态,优化调试模式,支持最新C++特性。

UTF-8编码原理(了解)

UTF-8编码原理

UTF-8(Unicode Transformation Format-8)是一种可变长度字符编码,用于将Unicode字符映射为字节序列。它兼容ASCII,支持所有Unicode字符(当前最长达21位),且无字节序(Endianness)问题,广泛应用于互联网和跨平台数据交换。


核心编码规则

UTF-8通过1到4个字节表示一个字符,编码规则如下:

Unicode码点范围(十六进制)UTF-8编码格式(二进制)字节数
U+0000 ~ U+007F0xxxxxxx1字节
U+0080 ~ U+07FF110xxxxx 10xxxxxx2字节
U+0800 ~ U+FFFF1110xxxx 10xxxxxx 10xxxxxx3字节
U+10000 ~ U+10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx4字节
规则解析
  1. 首字节前缀

    • 1字节:以0开头。

    • 2字节:以110开头。

    • 3字节:以1110开头。

    • 4字节:以11110开头。

  2. 后续字节前缀:所有后续字节均以10开头。

  3. 数据位填充x表示Unicode码点的二进制位,从高位到低位依次填充。


编码步骤示例

以字符 “€”(Unicode码点 U+20AC)为例,演示UTF-8编码过程:

1. 确定码点范围
  • U+20AC 属于 U+0800 ~ U+FFFF,需 3字节 编码。

2. 转换为二进制
  • 十六进制 20AC → 二进制 0010 0000 1010 1100(共16位)。

3. 按格式填充数据位
  • 3字节模板1110xxxx 10xxxxxx 10xxxxxx

  • 将16位码点拆分填充:

    • 首字节:取高4位 0010 → 填充到 1110xxxx → 11100010

    • 第二字节:取中间6位 000010 → 填充到 10xxxxxx → 10000010

    • 第三字节:取低6位 101100 → 填充到 10xxxxxx → 10101100

4. 合并字节序列
  • 最终UTF-8编码(十六进制):E2 82 AC


UTF-8编码示例表

字符Unicode码点UTF-8编码(十六进制)二进制格式
'A'U+00414101000001
'ç'U+00E7C3 A711000011 10100111
'中'U+4E2DE4 B8 AD11100100 10111000 10101101
'😂'U+1F602F0 9F 98 8211110000 10011111 10011000 10000010

UTF-8的核心优势

  1. 兼容ASCII

    • 所有ASCII字符(0x00-0x7F)的UTF-8编码与原ASCII编码一致,旧系统可无缝兼容。

  2. 空间高效

    • 常用字符(如拉丁字母、汉字)仅需2-3字节,比UTF-16/UTF-32更节省空间。

  3. 无字节序问题

    • 字节顺序固定(Big-Endian),无需BOM(Byte Order Mark)。

  4. 容错能力强

    • 通过前缀模式可检测编码错误(如无效的后续字节)。

    • 与其他编码的对比

      编码方式特点适用场景
      UTF-8可变长度(1-4字节),兼容ASCII,无字节序问题网络传输、存储、跨平台
      UTF-16固定2或4字节,存在大端(BE)和小端(LE)问题,需BOM标记Windows系统、部分旧协议
      UTF-32固定4字节,直接映射码点,空间占用大内存处理、内部计算

      实际应用场景

    • Web开发

      • HTML、JSON、XML默认使用UTF-8编码,确保多语言支持。

    • 文件存储

      • 文本文件(如.txt.csv)优先使用UTF-8,避免乱码。

    • 数据库

      • MySQL、PostgreSQL等数据库推荐UTF-8作为字符集。

    • 编程语言

      • Python、Java、JavaScript等均原生支持UTF-8字符串处理。

string类

        为什么要学习string类?

       C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

        标准库中的string类

        string类(了解)

        官方string类的介绍文档:

        <string> - C++ 参考

        string - C++ 参考

        在使用string类的时候,必须要包含头文件<string.h>以及

using namespace std

        auto和范围for

        auto关键字

        早期C/C++中auto的含义是:使用auto修饰的变量是具有自动储存器的局部变量,后来这个不重要了。在C++11 中auto有了全新的含义:auto不再是一个储存类型的指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

        用auto声明指针类型时,用auto和auto*没有任何区别,但是用auto声明引用类型时候必须加&,否则只是拷贝而无法通过它去改变指向的值

	int main()
    {
        int x = 10;
	    auto y = x;
	    auto *z= &x;
	    auto& m = x;
	    cout<<typeid(y).name()<<endl;
	    cout<<typeid(z).name()<<endl;
	    cout<<typeid(m).name()<<endl;
	    return 0;
    }

这么写也可以

auto p1=&x;
auto* p2=&x;

 但是不能这么写

auto *p2=x;

        当同一行声明多个变量的时候,这些变量必须是相同类型的,否则编译器会报错。因为编译器实际上只对第一个类型进行推导,然后用推导出来的类型去定义其他变量

        auto不能作为函数的参数,可以做返回值,但是建议谨慎使用

#include <iostream>
using namespace std;
int func1()
{
	return 10;
}
//不能做参数
void func2(auto a)
{}
//可以做返回值但是谨慎使用
auto func3()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = func1();
	//编译错误:“e”包含类型“auto”必须要有初始值
	auto e;
	cout<<typeid(b).name()<<endl;
	cout<<typeid(c).name()<<endl;
	cout<<typeid(d).name()<<endl;
	return 0;
}

        auto不能直接声明数组

int main()
{
    auto aa = 1, bb = 2;
	//编译错误:声明符列表中,“auto”必须始终推到为同一类型
	auto cc = 3, dd = 4.0;
	//编译错误:不能将“auto[]”用作函数参数类型
	auto arr[] ={4,5,6};
	return 0;
}

关于    typeid(b).name()    的解析

  • typeid(b)
    使用 typeid 运算符获取变量 b 的类型信息,返回一个 std::type_info 对象的常量引用。

    • 作用:在运行时(RTTI,Run-Time Type Information)或编译时获取类型信息。

    • 头文件:需包含 <typeinfo>

  • .name()
    std::type_info 的成员函数,返回一个表示类型名称的字符串(格式取决于编译器实现)。

    • 输出示例

      • GCC/Clang:i(表示 int

      • MSVC:int

  • cout << ... << endl
    输出 typeid(b).name() 返回的字符串,并换行。

auto真正的应用:

#include <iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
	std::map<std::string, std::string> dict = { {"apple","苹果"},{"orange","橘子"},{"pear","梨"}};
	//auto的应用
	//std::map<std::string, std::string>::iterator it = dict.begin();
	auto it =dict.begin();
	while (it != dict.end())
	{
		cout<<it->first<<" "<<it->second<<endl;
		++it;
	}
	return 0;
}

范围for 

        对于有范围的集合而言,程序员说明循环的范围是多余的,有时候还会容易犯错误。因此C++11引入了基于范围的for循环。for循环后括号由冒号“:”分为两部分:第一部分是范围用于迭代的变量,第二部分则表示被迭代的范围,自动迭代自动取数据,自动判断结束

        范围for可以作用到数组和容器对象上遍历。

        范围for的底层很简单,容器遍历实际上就是替换为迭代器,从汇编也可以看到

#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
	int arr[] = {1,2,3,4,5};
	C++98的遍历
	//for (int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++)
	//{
	//	cout<<arr[i]<<endl;
	//}
	//C++11的遍历
	for (auto& e : arr)
	{
		e *= 2;
	}
	for (auto&e : arr)
	{
		cout<<e<<" " << endl;
	}
	string str("hello world");
	for (auto ch : str)
	{
		cout<<ch<<" ";
	}
	cout<<endl;
	return 0;
}

        string类的常用接口说明

        string的构造方式

他们的特点分别为:

(constructor)函数名称功能说明
string(重点)构造空的string类,即空字符串
string(const char*s)(重点)用C-string来构造string类对象
string(size_t n,char c)string类对象包含n个字符c
string(const string &s)(重点)拷贝构造函数

        一个简单的string程序

#include <iostream>
#include<string>
using namespace std;
void test()
{
	//最常见的两种string构造方式
	string s1;                      //构造空字符串
	string s2 = "hello world";      //构造常量字符串
	string s3(s2);                  //拷贝构造
	string s4(s2, 1, 5);            //从s2中构造子串
	string s5(s2, 1, 50);
	string s6(s2, 1);
	const char* str = "hello world";//常量字符串
	string s7(str, 5);                  //从常量字符串构造
	string s8(100,'#');                    //从常量字符串构造
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	cout << s7 << endl;
	cout << s8 << endl;
}
int main()
{
	test();
	return 0;
}

结果为:

         string类对象的容量操作

        

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty(重点)检测字符串释放为空串,是返回true,否返回false
clear(重点)清空有效字符
reserve(重点)给字符串预留空间
resize(重点)讲有效字符的个数改成n个,多出的空间用字符c填充

注意:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

2. clear()只是将string中有效字符清空,不改变底层空间大小。

3. resize(size_t n) 与  resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, charc)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

参考文献:string - C++ 参考

以下是一些关键内容的截图:

 

string的遍历

函数名称功能说明
operator[](重点)返回pos的位置,const string类对象调用
begin+endbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器
rbegin+rendbegin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器
范围forC++11支持更简洁的范围for新遍历方式

一、[]运算符重载介绍

我们很明显地发现:s2是不能修改的 

因为它们的调用关系是这样的

void test()
{
	string s1("hello world");
	const string s2("hello world");
	//遍历+修改
	//下标+[]
	s1[0]++;
	/*s2[0]++;*/
	cout<<s1<<endl;
	for (size_t i = 0;i < s1.size();i++)
	{
		s1[i]++;
	}cout << s1 << endl;
}
int main()
{
	test();
	return 0;
}

结果为:

二、迭代器

迭代器是像指针一样的类型对象

void test()
{
	string s1("hello world");
	const string s2("hello world");
	//遍历+修改
	//下标+[]
	s1[0]++;
	/*s2[0]++;*/
	cout<<s1<<endl;
	for (size_t i = 0;i < s1.size();i++)
	{
		s1[i]++;
	}
	cout << s1 << endl;
	//begin() end()返回的是一段迭代器位置的区间,形式是这样的[        )
	//迭代器
	//s1--
	//iterator迭代器
	//迭代器使用起来像指针
	string::iterator it = s1.begin(); 
	while (it!= s1.end())
	{
		(*it)--;
		++it;
	}
	cout << s1 << endl;

}
int main()
{
	test();
	return 0;
}

结果为:

迭代器是所有容器的主流迭代方式,迭代器具有迁移性,掌握一个其他的也可以轻松上手

	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	vector<int>::iterator it2 = v.begin();
	while (it2 != v.end())
	{
		cout<<*it2<<" ";
		++it2;
	}

三、范围for (C++11)

        (这里需要结合前面的auto和范围for的拓展知识内容)

#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
	int arr[] = {1,2,3,4,5};
	//C++11的遍历
	for (auto& e : arr)
        //从:开始自动,特点是:
        //自动取范围中的数据赋值给e,
        //自动判断结束
        //自动迭代
	{
		e *= 2;
	}
	for (auto&e : arr)
	{
		cout<<e<<" " << endl;
	}
	string str("hello world");
	for (auto ch : str)
	{
		cout<<ch<<" ";
	}
	cout<<endl;
	return 0;
}

        范围for可以遍历vector,list等其他容器。 

        范围for本质上底层也会替换为新迭代器,即e=*迭代器

string类对象的修改操作

函数名称功能介绍
push  back在字符串中后尾插字符c
append在字符串后追加一个字符串
operator+=(重点)在字符串后追加字符串str
c_str(重点)返回C格式字符串
find+npos(重点)从字符串pos位置开始向后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中位置
substr在str中从pos位置开始,截取n个字符然后返回

注意:

1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

void test()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	vector<int>::iterator it2 = v.begin();
	while (it2 != v.end())
	{
		cout<<*it2<<" ";
		++it2;
	}
	reverse(v.begin(), v.end());

}

​

string类非成员函数

        

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率降低
operator>>(重点)输入运算符重载
operator<<(重点)输出运算符重载
getline(重点)获取一行字符串
relation operators(重点)大小比较

         上面的几个接口大家了解一下,下面的OJ题目中会有一些体现他们的使用。string类中还有一些其他的操作,这里不一一列举,大家在需要用到时不明白了查文档即可。

迭代器的介绍

迭代器的概念与分类

迭代器是STL中访问容器元素的通用接口,行为类似指针,但抽象程度更高。

  1. 迭代器类别

    • 正向迭代器(Forward Iterator):单向遍历(如 std::string::iterator)。

    • 双向迭代器(Bidirectional Iterator):支持双向移动(如 std::list::iterator)。

    • 随机访问迭代器(Random Access Iterator):支持跳跃访问(如 std::vector::iterator)。

    • 反向迭代器(Reverse Iterator):逆序遍历容器(如 std::string::reverse_iterator)。

    • const迭代器:禁止修改元素(如 std::string::const_iterator)。

  2. string的迭代器类型

    • std::string::iterator:可修改的随机访问迭代器。

    • std::string::const_iterator:不可修改的随机访问迭代器。

    • std::string::reverse_iterator:可修改的反向迭代器。

    • std::string::const_reverse_iterator:不可修改的反向迭代器。

string中迭代器的获取方式

通过成员函数获取不同类别的迭代器:

正向迭代器

std::string str = "Hello";
auto begin = str.begin();   // 指向第一个字符的迭代器
auto end = str.end();       // 指向末尾(最后一个字符的下一位)

反向迭代器

auto rbegin = str.rbegin(); // 指向最后一个字符的反向迭代器
auto rend = str.rend();     // 指向头部前一位的反向迭代器

const迭代器

auto cbegin = str.cbegin(); // 常量正向迭代器
auto crbegin = str.crbegin(); // 常量反向迭代器

迭代器的基本操作

遍历字符串

for (auto it = str.begin(); it != str.end(); ++it) {
    std::cout << *it;  // 解引用访问字符
}

反向遍历

for (auto rit = str.rbegin(); rit != str.rend(); ++rit) {
    std::cout << *rit;  // 输出逆序字符
}

随机访问

auto it = str.begin() + 3;  // 跳转到第4个字符('l')
std::cout << *it;           // 输出 'l'

涉及迭代器的string成员函数

构造与赋值

std::string s4(str.begin(), str.begin() + 3); // 构造子串 "Hel"
str.assign(s4.rbegin(), s4.rend());           // 赋值逆序子串 "leH"

插入与删除

str.insert(str.begin() + 2, 'X');    // 在位置2插入'X' → "HeXllo"
str.erase(str.begin() + 1);          // 删除位置1的字符 → "HXllo"

查找与替换

auto pos = std::find(str.begin(), str.end(), 'X');
if (pos != str.end()) {
    *pos = 'Y';  // 替换找到的字符
}

与STL算法结合使用

利用标准算法处理字符串:

排序字符串字符

std::sort(str.begin(), str.end()); // 升序排列字符

统计字符出现次数

int count = std::count(str.begin(), str.end(), 'l');

条件查找

auto it = std::find_if(str.begin(), str.end(), [](char c) {
    return c >= 'A' && c <= 'Z';
});

迭代器失效问题

  1. 导致失效的操作

    • 修改字符串长度(如append()insert()erase())。

    • 重新分配内存(如reserve()不足时扩容)。

  2. 安全实践

    • 在修改操作后,避免使用旧的迭代器。

    • 使用索引或重新获取迭代器。

实际应用示例

逆序输出字符串

for (auto rit = str.rbegin(); rit != str.rend(); ++rit) {
    std::cout << *rit;
}

删除所有空格

str.erase(std::remove(str.begin(), str.end(), ' '), str.end());

转换为大写

std::transform(str.begin(), str.end(), str.begin(), ::toupper);

迭代器的意义:

1.统一类似的方式遍历修改容器

2.算法脱离了具体的底层结构,与底层结构解耦(降低耦合,降低关联关系)

算法独立模板实现,针对多个容器处理

下图就是相关的代码示例:(使用前要包含头文件<algorithm>)

一些string类的例题

        1.仅仅反转字母

题目:

       这道题本质上是类似于快速排序算法

        这道题不适合用范围for,也不适合迭代器。用下标法求解这道题:

class Solution
{
public:
    string reverseOnlyLetters(string s) 
    {
        if(s.empty())
        return s;
        size_t begin=0,end=s.size()-1;
        while(begin<end)
        {
            while(begin<end&&!isalpha(s[begin]))
            {
                ++begin;
            }
            while(begin<end&&!isalpha(s[end]))
            {
                --end;
            }
            swap(s[begin],s[end]);
            ++begin;
            --end;
        }
        return s;
    }
};

或者

class Solution
{
public:
    bool isletter(char ch)
    {
        if(ch>='a'&&ch<='z')
        {
            return true;
        }
        else if(ch>='A'&&ch<='Z')
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
    string reverseOnlyLetters(string s) 
    {
        if(s.empty())
        return s;
        size_t begin=0,end=s.size()-1;
        while(begin<end)
        {
            while(begin<end&&!isletter(s[begin]))
            {
                ++begin;
            }
            while(begin<end&&!isletter(s[end]))
            {
                --end;
            }
            swap(s[begin],s[end]);
            ++begin;
            --end;
        }
        return s;
    }
};

        2.查找字符串中第一个唯一的字符

        题目:

         思路:哈希

        哈希就是映射,即建立数字与位置的映射,就像下图这样

class Solution
{
public:
    int firstUniqChar(string s) 
    {
        int count[26]={0};
        //每个字符出现的次数
        for(auto e:s)
        {
            count[e-'a']++;
        }
        for(size_t i=0;i<s.size();++i)
        {
            if(count[s[i]-'a']==1)
            {
                return i;
            }
            
        }
        return -1;
    }
};

         本期博客就到这里了,string的内容还没有结束,后续我们会进一步了解string的应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3. 仓颉 CEF 库封装

文章目录 1. capi 使用说明2. Cangjie CEF2. 1实现目标 3. 实现示例 1. capi 使用说明 根据上一节 https://blog.csdn.net/qq_51355375/article/details/147880718?spm1011.2415.3001.5331 所述&#xff0c; cefcapi 是libcef 共享库导出一个 C API, 而以源代码形式分发的 li…

LabVIEW多通道并行数据存储系统

在工业自动化监测、航空航天测试、生物医学信号采集等领域&#xff0c;常常需要对多个传感器通道的数据进行同步采集&#xff0c;并根据后续分析需求以不同采样率保存特定通道组合。传统单线程数据存储方案难以满足实时性和资源利用效率的要求&#xff0c;因此设计一个高效的多…

谷歌在即将举行的I/O大会之前,意外泄露了其全新设计语言“Material 3 Expressive”的细节

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

十三、基于大模型的在线搜索平台——整合function calling流程

基于大模型的在线搜索平台——整合function calling流程 一、function calling调用总结 上篇文章已经实现了信息抓取能力&#xff0c;并封装成了函数。现在最后一步将能力转换为大模型可以调用的能力&#xff0c;实现搜索功能就可以了。这篇主要实现大模型的function calling能…

力扣70题解

记录 2025.5.8 题目: 思路&#xff1a; 1.初始化&#xff1a;p 和 q 初始化为 0&#xff0c;表示到达第 0 级和第 1 级前的方法数。r 初始化为 1&#xff0c;表示到达第 1 级台阶有 1 种方法。 2.循环迭代&#xff1a;从第 1 级到第 n 级台阶进行迭代&#xff1a; p 更新为前…

电商双11美妆数据分析

1、初步了解 2.2 缺失值处理 通过上面观察数据发现sale_count,comment_count 存在缺失值,先观察存在缺失值的行的基本情况 2.3 数据挖掘寻找新的特征 给出各个关键词的分类类别 由title新生成两列类别 对是否是男性专用进行分析并新增一列 对每个产品总销量新增销售额这一列

24、TypeScript:预言家之书——React 19 类型系统

一、预言家的本质 "TypeScript是魔法世界的预言家之书&#xff0c;用静态类型编织代码的命运轨迹&#xff01;" 霍格沃茨符文研究院的巫师挥动魔杖&#xff0c;类型注解与泛型的星轨在空中交织成防护矩阵。 ——基于《国际魔法联合会》第12号类型协议&#xff0c;Ty…

第8章-1 查询性能优化-优化数据访问

上一篇&#xff1a;《第7章-3 维护索引和表》 在前面的章节中&#xff0c;我们介绍了如何设计最优的库表结构、如何建立最好的索引&#xff0c;这些对于提高性能来说是必不可少的。但这些还不够——还需要合理地设计查询。如果查询写得很糟糕&#xff0c;即使库表结构再合理、索…

PCL点云按指定方向进行聚类(指定类的宽度)

需指定方向和类的宽度。测试代码如下&#xff1a; #include <iostream> #include <fstream> #include <vector> #include <string> #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/visualization/pcl_visu…

C#对SQLServer增删改查

1.创建数据库 2.SqlServerHelper using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks;namespace WindowsFormsApp1 {internal class SqlServerHelper{//…

模拟太阳系(C#编写的maui跨平台项目源码)

源码下载地址&#xff1a;https://download.csdn.net/download/wgxds/90789056 本资源为用C#编写的maui跨平台项目源码&#xff0c;使用Visual Studio 2022开发环境&#xff0c;基于.net8.0框架&#xff0c;生成的程序为“模拟太阳系运行”。经测试&#xff0c;生成的程序可运行…

蓝桥杯14届 数三角

问题描述 小明在二维坐标系中放置了 n 个点&#xff0c;他想在其中选出一个包含三个点的子集&#xff0c;这三个点能组成三角形。然而这样的方案太多了&#xff0c;他决定只选择那些可以组成等腰三角形的方案。请帮他计算出一共有多少种选法可以组成等腰三角形&#xff1f; 输…

HTML12:文本框和单选框

表单元素格式 属性说明type指定元素的类型。text、password、 checkbox、 radio、submit、reset、file、hidden、image 和button&#xff0c;默认为textname指定表单元素的名称value元素的初始值。type为radio时必须指定一个值size指定表单元素的初始宽度。当type为text 或pas…

机器人厨师上岗!AI在餐饮界掀起新风潮!

想要了解人工智能在其他各个领域的应用&#xff0c;可以查看下面一篇文章 《AI在各领域的应用》 餐饮业是与我们日常生活息息相关的行业&#xff0c;而人工智能&#xff08;AI&#xff09;正在迅速改变这个传统行业的面貌。从智能点餐到食材管理&#xff0c;再到个性化推荐&a…

MySQL开篇

文章目录 一、前置知识1. MySQL的安装2. 前置一些概念知识 二、MySQL数据库操作2.1 概念2.2 数据库的操作2.2.1创建数据库命令2.2.2 查看数据库2.2.3 选中数据库2.2.4 删除数据库 三、MySQL数据表操作3.1 概念3.2 数据表的操作3.2.1 创建表 一、前置知识 1. MySQL的安装 MySQ…

Linux电脑本机使用小皮面板集成环境开发调试WEB项目

开发调试WEB项目&#xff0c;有时开发环境配置繁琐&#xff0c;可以使用小皮面板集成环境。 小皮面板官网&#xff1a; https://www.xp.cn/1.可以使用小皮面板安装脚本一键安装。登陆小皮面板管理后台 2.在“软件商店”使用LNMP一键部署集成环境。 3.添加网站&#xff0c;本…

问题及解决01-面板无法随着窗口的放大而放大

在MATLAB的App Designer中&#xff0c;默认情况下&#xff0c;组件的位置是固定的&#xff0c;不会随着父容器的大小变化而改变。问题图如下图所示。 解决&#xff1a; 为了让Panel面板能够随着UIFigure父容器一起缩放&#xff0c;需要使用布局管理器&#xff0c;我利用 MATLA…

操作系统原理实验报告

操作系统原理课程的实验报告汇总 实验三&#xff1a;线程的创建与撤销 实验环境&#xff1a;计算机一台&#xff0c;内装有VC、office等软件 实验日期&#xff1a;2024.4.11 实验要求&#xff1a; 1.理解&#xff1a;Windows系统调用的基本概念&#xff0c;进程与线程的基…

《Linux命令行大全(第2版)》PDF下载

内容简介 本书对Linux命令行进行详细的介绍&#xff0c;全书内容包括4个部分&#xff0c;第一部分由Shell的介绍开启命令行基础知识的学习之旅&#xff1b;第二部分讲述配置文件的编辑&#xff0c;如何通过命令行控制计算机&#xff1b;第三部分探讨常见的任务与必备工具&…

Java高频面试之并发编程-15

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天又来报道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面试官&#xff1a;as-if-serial 是什么&#xff1f;单线程的程序一定是顺序执行的吗&#xff1f; as-if-serial 规则 定义&#xff1a; …