数据结构和算法(2):向量

news2024/11/17 0:00:35

抽象数据类型

在这里插入图片描述

数组到向量

C/C++ 中,数组A[]中的元素与[0,n)内的编号一一对应,A[0],A[1],...,A[n-1];反之,每个元素均由(非负)编号唯一指代,并可直接访问A[i] 的物理地址 = A+i × ss 为单个元素占用的空间量,所以也叫作线性数组。

向量是数组的抽象与泛化,由一组元素按线性次数封装而成。各元素与[0,n)内的秩(rank)一一对应。
元素的类型不限于基本类型;
操作、管理维护更加简化、统一与安全;
可更为便捷地参与复杂数据结构的定制与实现
在这里插入图片描述

Vector 模板类

using Rank = unsigned int; //秩
#define DEFAULT_CAPACITY  3 //默认的初始容量(实际应用中可设置为更大)
template <typename T> class Vector { //向量模板类
private:Rank_size;int_capacity;T* _elem;//规模、容量、数据区
protected:
	/.../
public:
	//构造函数
	Vector ( Rank c = DEFAULT_CAPACITY, Rank s = 0, T v = 0 ) //容量为c、规模为s、所有元素初始为v
	{ _elem = new T[_capacity = c]; for ( _size = 0; _size < s; _elem[_size++] = v ); } //s<=c
	Vector ( T const* A, Rank n ) { copyFrom ( A, 0, n ); } //数组整体复制
	Vector ( T const* A, Rank lo, Rank hi ) { copyFrom ( A, lo, hi ); } //区间
	Vector ( Vector<T> const& V ) { copyFrom ( V._elem, 0, V._size ); } //向量整体复制
	Vector ( Vector<T> const& V, Rank lo, Rank hi ) { copyFrom ( V._elem, lo, hi ); } //区间
	// 析构函数
	~Vector() { delete [] _elem; } //释放内部空间
}; //Vector

可扩充向量

静态空间管理

开辟内部数组_elem[]并使用一段地址连续的物理空间
_capacity :总容量
_size:当前的实际规模n

若采用静态空间管理策略,容量_capacity固定,则有明显的不足
1.上溢( overf1ow ) : _elem[]不足以存放所有元素
尽管此时系统仍有足够的空间
2.下溢( underflow ) : _elem[]中的元素寥寥无几
装填因子(load factor) λ = _ s i z e / _ c a p a c i t y < < 50 % \lambda = \_size/\_capacity << 50\% λ=_size/_capacity<<50%

更糟糕的是,一般的应用环境中难以准确预测空间的需求量。

动态空间管理

在即将发生上溢时,适当地扩大内部数组的容量

template <typename T>
void Vector<T>::expand() { //向量空间不足时扩容
	if(_size < _capacity) return; //尚未满员时,不必扩容
	_capacity = max(_capacity, DEFAULT_CAPACITY); //不低于最小容量
	T* oldElem =_elem; _elem = new T[_capacity <<= 1];//容量加倍
	for (int i = 0; i <_size; i++) //复制原向量内容
		_elem[i] = oldElem[i]; //T为基本类型,或已重载赋值操作符'='
	delete [] oldElem; //释放原空间
}

得益于向量的封装,尽管扩容之后数据区的物理地址有所改变,却不致出现野指针。

容量加倍策略在时间复杂度上总体优于容量递增策略。

  \space  递增策略倍增策略
累计增容时间 O ( n 2 ) \mathcal O(n^2) O(n2) O ( n ) \mathcal O(n) O(n)
分摊增容时间 O ( n ) \mathcal O(n) O(n) O ( 1 ) \mathcal O(1) O(1)
装填因子 ≈ 100 % ≈100\% 100% > 50 % >50\% >50%

平均分析 vs 分摊分析

平均复杂度或期望复杂度(average/expected complexity)
根据数据结构各种操作出现概率的分布,将对应的成本加权平均
各种可能的操作,作为独立事件分别考查
割裂了操作之间的相关性和连贯性
往往不能准确地评判数据结构和算法的真实性能

分摊复杂度(amortized complexity)
对数据结构连续地实施足够多次操作,所需总体成本分摊至单次操作
从实际可行的角度,对一系列操作做整体的考量
更加忠实地刻画了可能出现的操作序列
可以更为精准地评判数据结构和算法的真实性能

分摊复杂度和平均复杂度的结果并没有必然联系。

无序向量

元素访问

通过V.get(r)V.put(r)接口,可以对元素进行读写。
可以重载下标操作符,增加其便捷性:

template<typename T>	//0 <= _size
T & Vector<T>::operator[](Rank(r)) const {return _elem[r];}

此后,对外的V[r]即对应内部的V._elem[r]可以使用下标进行操作:

//右值
T x = V[r] + U[s] + W[t];
//左值
V[r] = T(2*x + 3);

插入

template <typename T> //将e插入至[r]
Rank Vector<T>::insert ( Rank r, T const& e ) { //0 <= r <= size
	expand(); //如必要,先扩容
	for ( Rank i = _size; r < i; i-- ) //自后向前,后继元素
		_elem[i] = _elem[i-1]; //顺次后移一个单元
	_elem[r] = e; _size++; //置入新元素并更新容量
	return r; //返回秩
}

区间删除

template <typename T> int Vector<T>::remove( Rank lo, Rank hi ) { //0 <= lo <= hi <= n
	if ( lo == hi ) return 0; //出于效率考虑,单独处理退化情况
	while ( hi < _size ) _elem[lo++] = _elem[hi++]; //后缀[hi, _size)顺次前移 hi-lo 位
	_size = lo; shrink(); //更新规模,lo=_size之后的内容无需清零;如必要,则缩容
	//若有必要,则缩容
	return hi-lo;//返回被删除元素的数目
}

单元素删除

可以视作区间删除的特例:[r] = [r,r+1)

template <typename T> T Vector<T>::remove( Rank r ) { //删除向量中秩为r的元素,0 <= r < size
	T e = _elem[r]; //备份被删除元素
	remove( r, r + 1 ); //调用区间删除算法,等效于对区间[r, r + 1)的删除
	return e; //返回被删除元素
}

查找

template <typename T> //在无序向量中顺序查找e:成功则返回最靠后的出现位置,否则返回lo-1
Rank Vector<T>::find ( T const& e, Rank lo, Rank hi ) const { //0 <= lo < hi <= _size
   while ( ( lo < hi-- ) && ( e != _elem[hi] ) ); //从后向前,顺序查找
   return hi; //若hi < lo,则意味着失败;否则hi即命中元素的秩
}

输入敏感:最好: O ( 1 ) \mathcal O(1) O(1) ; 最差: O ( n ) \mathcal O(n) O(n)

实例:去重(删除重复元素)

template <typename T> Rank Vector<T>::dedup() { //删除无序向量中重复元素(高效版)
   Rank oldSize = _size; //记录原规模
   for ( Rank i = 1; i < _size; ) //自前向后逐个考查_elem[1,_size)
      if ( -1 == find(_elem[i], 0, i) ) //在前缀[0,i)中寻找与[i]雷同者(至多一个),O(i)
         i++; //若无雷同,则继续考查其后继
      else
         remove(i); //否则删除[i],O(_size-i)
	return oldSize - _size; //被删除元素总数
}

每轮迭代中 find()remove(累计耗费线性时间,总体为 O ( n 2 ) \mathcal O(n^2) O(n2)

有序向量:唯一化

有序/无序序列中,任意/总有一对相邻元素顺序/逆序因此,相邻逆序对的数目,可用以度量向量的逆序程度。

实例:有序向量去重

观察︰在有序向量中,重复的元素必然相互紧邻构成一个区间。因此,每一区间只需保留单个元素即可

低效算法

template <typename T> Rank Vector<T>::uniquify() { //有序向量重复元素剔除算法(低效版)
	Rank oldSize = _size, i = 1; //当前比对元素的秩,起始于首元素
	while ( i < _size ) //从前向后,逐一比对各对相邻元素
		_elem[i - 1] == _elem[i] ? remove ( i ) : i++; //若雷同,则删除后者;否则,转至后一元素
	return oldSize - _size; //向量规模变化量,即被删除元素总数
}

效率低,运行时间主要取决于 while 循环,次数共计:_size - 1 = n -1
最坏: O ( n 2 ) \mathcal O(n^2) O(n2)

高效算法
反思:低效的根源狂于,同一元素可作为被删除元素的后继多次前移
启示︰若能以重复区间为单位,成批删除雷同元素,性能必将改进

template <typename T> Rank Vector<T>::uniquify() { //有序向量重复元素剔除算法(高效版)
  Rank i = 0, j = 0; //各对互异“相邻”元素的秩
  while ( ++j < _size ) //逐一扫描,直至末元素
     if ( _elem[i] != _elem[j] ) //跳过雷同者
        _elem[++i] = _elem[j]; //发现不同元素时,向前移至紧邻于前者右侧
  _size = ++i; shrink(); //直接截除尾部多余元素
  return j - i; //向量规模变化量,即被删除元素总数
}

共计 n - 1 次迭代,每次常数时间,累计 O ( n ) \mathcal O(n) O(n) 时间。

有序向量:二分查找(A)

//二分查找算法(版本A)︰在有序向量的区间[lo,hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank binSearch( T* S, T const& e, Rank lo,Rank hi ) {
	while ( lo < hi ) {	//每步迭代可能要做两次比较判断,有三个分支
	Rank mi = ( lo + hi ) >>1;	//以中点为轴点(区间宽度折半,等效于其数值表示的右移一位)
	if( e < s[mi] ) hi = mi;	//深入前半	段[ 1o, mi)继续查找
	else if ( S[mi] < e ) lo = mi + 1;	//深入后半段(mi,hi)继续查找
	else
		return mi; 	//在mi处命中
	}	//成功查找可以提前终止
	return -1;	//查找失败
}	//有多个命中元素时,不能保证返回秩最大者;查找失败时,简单地返回-1,而不能指示失败的位置

转向左、右分支前的关键码比较次数不等,而递归深度却相同

有序向量:Fib 查找

若能通过递归深度的不均衡,对转向成本的不均衡进行补偿平均查找长度应能进一步缩短…

#include "fibonacci/Fib.h" //引入Fib数列类
//Fibonacci查找算法(版本A):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank fibSearch( T* S, T const& e, Rank lo, Rank hi ) {
   //用O(log_phi(n = hi - lo)时间创建Fib数列
   for ( Fib fib( hi - lo ); lo < hi; ) { //Fib制表备查;此后每步迭代仅一次比较、两个分支
      while ( hi - lo < fib.get() ) fib.prev(); //自后向前顺序查找(分摊O(1))
      Rank mi = lo + fib.get() - 1; //确定形如Fib(k)-1的轴点
      if      ( e < S[mi] ) hi = mi; //深入前半段[lo, mi)继续查找
      else if ( S[mi] < e ) lo = mi + 1; //深入后半段(mi, hi)继续查找
      else                  return mi; //在mi处命中
   } //一旦找到,随即终止
   return -1; //查找失败
} //有多个命中元素时,不能保证返回秩最大者;失败时,简单地返回-1,而不能指示失败的位置

通用策略:对于任何的 A [ 0 , n ) A[0,n) A[0n),总是选取 A [ λ n ] A[\lambda n] A[λn] 作为轴点, 0 ≤ λ < 1 0\leq \lambda<1 0λ<1
[ 0 , 1 ) [0,1) [01)内, λ \lambda λ 如何取值才能达到最优 ? 设平均查找长度为 α ( λ ) ⋅ l o g 2 n α(\lambda)· log_2n α(λ)log2n,何时 α ( λ ) α(\lambda) α(λ) 最小?
二分查找: λ = 0.5 \lambda = 0.5 λ=0.5 Fib 查找: 0.6180339... 0.6180339... 0.6180339...

有序向量:二分查找(B)

二分查找中左、右分支转向代价不平衡的问题,也可直接解决。将中间点包含在了右边。

//二分查找算法(版本B):在有序向量的区间[lo, hi)内查找元素e,0 <= lo < hi <= _size
template <typename T> static Rank binSearch( T* S, T const& e, Rank lo, Rank hi ) {
	while ( 1 < hi - lo ) { //每步迭代仅需做一次比较判断,有两个分支;成功查找不能提前终止
      Rank mi = ( lo + hi ) >> 1; //以中点为轴点(区间宽度折半,等效于其数值表示的右移一位)
      ( e < S[mi] ) ? hi = mi : lo = mi; //经比较后确定深入[lo, mi)或[mi, hi)
   } //出口时hi = lo + 1,查找区间仅含一个元素A[lo]
   return e < S[lo] ? lo - 1 : lo; //返回位置,总是不超过e的最大者
} //有多个命中元素时,返回秩最大者;查找失败时,简单地返回-1,而不能指示失败的位置

有序向量:二分查找(C)

//二分查找算法(版本C):在有序向量的区间[lo, hi)内查找元素e,0 <= lo <= hi <= _size
template <typename T> static Rank binSearch( T* S, T const& e, Rank lo, Rank hi ) {
  while ( lo < hi ) { //每步迭代仅需做一次比较判断,有两个分支
     Rank mi = ( lo + hi ) >> 1; //以中点为轴点(区间宽度折半,等效于其数值表示的右移一位)
     ( e < S[mi] ) ? hi = mi : lo = mi + 1; //经比较后确定深入[lo, mi)或(mi, hi)
  } //成功查找不能提前终止
  return lo - 1; //至此,[lo]为大于e的最小者,故[lo-1]即为不大于e的最大者
} //有多个命中元素时,返回最靠后者;查找失败时,返回失败的位置

与版本B的差异
1)待查找区间宽度缩短至e而非1时,算法才结束
2)转入右侧子向量时,左边界取作mi + 1而非mi——A[mi]会被遗漏?
3)无论成功与否,返回的秩严格符合接口的语义约定…

冒泡排序

向量元素若有序排列,计算效率将大大提升

template <typename T> void vector<T>::bubbleSort(Rank lo,Rank h1)
{ while (!bubble(lo,hi--)); }	//逐趟做扫描交换,直至全序

template <typename T> bool Vector<T>::bubble(Rank lo,Rank hi) {
	bool sorted = true;	//整体有序标志
	while (++lo < hi)	//自左向右,逐一检查各对相邻元素
		if (_elem[lo - 1] > _elem[lo]) {	//若逆序,则
			sorted = false;//意味着尚未整体有序,并需要
			swap(_elem[lo - 1],_elem[lo]);//交换
		}
	return sorted; l/返回有序标志
}//乱序限于[0,√n)时,仍需O(n^{3/2})时间——按理,O(n)应已足矣

改进:

template <typename T> void vector<1>::bubbleSort(Rank lo,Rank h1)
{ while (lo < (hi = bubble(lo,hi)));}//逐趟扫描交换,直至全序
template <typename T> Rank Vector<T> : :bubble(Rank lo,Rank hi) {
	Rank last = lo;//最右侧的逆序对初始化为[lo - 1,1o]
	while (++lo < hi)//自左向右,逐一检查各对相邻元素
		if(_elem[lo - 1] > _elem[lo])//若逆序,则
			last = lo;//更新最右侧逆序对位置记录,并
			swap(_elem[lo - 1],_elem[lo]);//交换
		}
	return last;//返回最右侧的逆序对位置
}//前一版本中的逻辑型标志sorted,改为秩last

三种冒泡排序算法效率相同,最好o(n),最坏o(n^2)
在冒泡排序中,元素 a 和 b 的相对位置发生变化,只有一种可能;
1.经分别与其它元素的交换,二者相互接近直至相邻
2.在接下来一轮扫描交换中,二者因逆序而交换位置

归并排序

分治策略,向量与列表通用
序列一分为二 ( O ( 1 ) ) (\mathcal O(1)) (O(1)),子序列递归排序 ( 2 × T ( n / 2 ) ) (2 \times T(n/2)) (2×T(n/2)),合并有序子序列 ( O ( n ) ) (\mathcal O(n)) (O(n))
总体复杂度为 ( O ( n log ⁡ n ) ) (\mathcal O(n\log n)) (O(nlogn))

template <typename T> //向量归并排序
void Vector<T>::mergeSort( Rank lo, Rank hi ) { // 0 <= lo < hi <= size
   if ( hi - lo < 2 ) return; //单元素区间自然有序,否则...
   Rank mi = ( lo + hi ) / 2; //以中点为界
   mergeSort( lo, mi ); mergeSort( mi, hi ); //前缀、后缀分别排序
   merge( lo, mi, hi ); //归并
}

template <typename T> //对各自有序的[lo, mi)和[mi, hi)做归并
void Vector<T>::merge( Rank lo, Rank mi, Rank hi ) { // lo < mi < hi
   Rank i = 0; T* A = _elem + lo; //合并后的有序向量A[0, hi - lo) = _elem[lo, hi)
   Rank j = 0, lb = mi - lo; T* B = new T[lb]; //前子向量B[0, lb) <-- _elem[lo, mi)
   for ( Rank i = 0; i < lb; i++ ) B[i] = A[i]; //复制出A的前缀
   Rank k = 0, lc = hi - mi; T* C = _elem + mi; //后缀C[0, lc) = _elem[mi, hi)就地
   while ( ( j < lb ) && ( k < lc ) ) //反复地比较B、C的首元素
      A[i++] = ( B[j] <= C[k] ) ? B[j++] : C[k++]; //将更小者归入A中
   while ( j < lb ) //若C先耗尽,则
      A[i++] = B[j++]; //将B残余的后缀归入A中——若B先耗尽呢?
   delete[] B; //释放临时空间:mergeSort()过程中,如何避免此类反复的new/delete?
}

算法的运行时间主要在于 for 循环,merge() 总体迭代不超过 O ( n ) \mathcal O(n) O(n) 次,累计只需线性时间。 T ( n ) = 2 T ( n / 2 ) + O ( n ) T(n) = 2T(n/2)+\mathcal O(n) T(n)=2T(n/2)+O(n)

位图

位图(Bitmap)是一种数据结构,用于表示一组位或二进制值的集合。在计算机科学中,位图通常用于存储和操作大量的二进制数据,其中每个位都表示某种状态或信息。
位图中的每个位(或者可以理解为数组的元素)代表一个元素是否存在于集合中。当元素存在时,对应位的值为1;不存在时,对应位的值为0。

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

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

相关文章

vue-elementPlus自动按需导入和主题定制

elementPlus自动按需导入 装包 -> 配置 1. 装包&#xff08;主包和两个插件包&#xff09; $ npm install element-plus --save npm install -D unplugin-vue-components unplugin-auto-import 2. 配置 在vite.config.js文件中配置&#xff0c;配置完重启&#xff08;n…

SM5202 是一款完整的采用恒定电流/恒定电压的单节锂电池线性充电器

简介&#xff1a; SM5202 是一款完整的采用恒定电流/恒定电压的单节锂电池线性充电器&#xff0c;并带有锂电池正负极反接保护功能&#xff0c;可以保护芯片和用户安全。由于采用了内部 PMOSFET 架构&#xff0c;加上防倒充电路&#xff0c;所以不需要外部检测电阻和隔离二极管…

Java之包装类的算法小题的练习

算法小题 练习一&#xff1a; 需求&#xff1a; 键盘录入一些1~10日之间的整数&#xff0c;并添加到集合中。直到集合中所有数据和超过200为止。 代码示例&#xff1a; public class Test1 {public static void main(String[] args) {/*键盘录入一些1~10日之间的整数&…

产业大数据应用:洞察区域产业实况,把握区域经济脉搏

​ 随着新一代信息技术的崛起&#xff0c;我们进入了大数据时代。在这个时代&#xff0c;数据作为基本生产要素不仅改变着我们的日常生活&#xff0c;更是在区域产业经济发展中扮演着重要角色&#xff0c;它赋予了政府、企业和投资者敏锐的洞察力。 一、摸清区域经济现状 基于…

智慧公厕如何实现系统管理、运行数据、业务流程的高度耦合

随着城市发展和人口增长&#xff0c;公共厕所成为城市更新与发展的重要环节。然而&#xff0c;传统的公共厕所管理方式面临诸多问题&#xff0c;如运营成本高、环境污染、人员管理等。为了解决这些问题&#xff0c;智慧公厕应运而生。智慧公厕是指利用现代科技手段&#xff0c;…

RPC接口测试-两种方法(Jmeter和代码)

相信很多同学在测试RPC接口时会遇到很多困难&#xff0c;博主前段时间在测试时也一样&#xff0c;算是提前踩坑啦&#xff0c;下面就来介绍一下测试RPC接口的方法 1.什么是RPC接口 RPC&#xff08;Remote Procedure Call&#xff09;是一种通信协议和模式&#xff0c;用于在分…

Linux之权限

目录 一、shell运行原理 二、权限 1、对人操作 2、对角色和文件操作 修改权限&#xff08;改属性&#xff09;&#xff1a; ①ugo- ②二进制数的表示 修改权限&#xff08;改人&#xff09;&#xff1a; 三、权限的相关问题 1、目录的权限 2、umask 3、粘滞位 一、s…

一百七十一、Flume——Flume1.9.0单机版安装(亲测有效)

一、目的 以防万一&#xff0c;为了避免kettle从Kafka同步数据到HDFS有问题&#xff0c;因此也测试了用Flume去采集Kafka中的数据然后同步到HDFS&#xff0c;算是一套备用方案 二、安装包版本 &#xff08;一&#xff09;Hadoop版本 hadoop-3.1.3.tar.gz &#xff08;二&a…

JS中执行上下文和执行栈是什么?

一&#xff1a;执行上下文 执行上下文是一种对js执行代码的环境的一种抽象&#xff0c;只要js在执行中&#xff0c;那它一定是运行在执行上下文中 执行上下文的类型 全局执行上下文&#xff1a;全局执行上下文是在程序启动时创建的&#xff0c;它包含全局范围定义的变量和函数…

UltraISO做u盘镜像启动盘

1、工具—刻录光盘映像 2、刻录机选择盘 选择centos镜像 刻录

索尼 toio™应用创意开发征文|一步两步三步模拟浇花系统

目录 1.toio™介绍 2、创意分析 2.1 创意设计 2.2 创意落地 3、创意实现 3.1 环境安装 3.2 核心玩法 总结 1.toio™介绍 索尼的toio™是一款启发创意的机器人产品&#xff0c;旨在通过与真实世界的互动&#xff0c;为各年龄段的用户提供娱乐体验。这款产品具有高度的灵…

【已解决】pyqt5的打包exe软件图标菜单栏/任务栏/小图标/窗口图标未显示

1.起因&#xff1a; 希望&#xff1a;pyqt5 项目&#xff0c;pyinstaller main.spec 打包&#xff0c;我想要 main.exe 就像一个普通的应用软件一样显示我自定义的图标。 结果&#xff1a; main.exe 左侧图标还是老土的样子&#xff0c;并没有成为我的图标。独立运行是&#…

API接口与电商平台之间的联系,采集京东平台数据按关键字搜索商品接口示例

关键字搜索商品的重要性&#xff1a; 1.引入精准流量 关键词第一个也是最重要的作用就是为我们宝贝引进精准的流量&#xff0c;这一作用无论是在自然搜索中还是直通车中都是一样的。 第一步关乎的是我们宝贝的展现&#xff0c;而第二步用户是否会点进我们的宝贝&#xff0c;…

爬虫爬取mp3文件例子

相信训练模型时数据集的获取也是一个很头疼的事情&#xff0c;搞cv领域的可以扛着摄像头架起三脚架拍摄获取&#xff08;以前干过&#xff09;&#xff0c;但是如果是nlp领域的呢&#xff0c;特别是chatgpt等大模型出来后对这类文本等数据的需求更大&#xff0c;如果没有现成的…

攻防世界-WEB-Web_php_include

打开靶机 通过代码审计可以知道&#xff0c;存在文件包含漏洞&#xff0c;并且对伪协议php://进行了过滤。 发现根目录下存在phpinfo 观察phpinfo发现如下&#xff1a; 这两个都为on 所以我们就可以使用data://伪协议 payload如下&#xff1a; - ?pagedata://text/plain,…

测试可用的淘宝API(商品详情数据、买家信息、卖家信息、店铺信息、订单信息)

什么是API? API全称Application Programming Interface&#xff0c;即应用程序编程接口&#xff0c;是一些预先定义的函数&#xff0c;或指软件系统不同组成部分衔接的约定&#xff0c;用于传输数据和指令&#xff0c;使应用程序之间可以集成和共享数据资源。 简单来说&#…

SQL语言的分类:DDL(数据库、表的增、删、改)、DML(数据的增、删、改)

数据库管理系统&#xff08;数据库软件&#xff09;功能非常多&#xff0c;不仅仅是存储数据&#xff0c;还要包含&#xff1a;数据的管理、表的管理、库的管理、账户管理、权限管理等。 操作数据库的SQL语言&#xff0c;基于功能&#xff0c;划分为4类&#xff1a; 1、数据定…

64位Office API声明语句第110讲

【分享成果&#xff0c;随喜正能量】以大慈为所住&#xff0c;给一切众生快乐&#xff0c;观众生心与菩萨心平等平等。以大悲为住处&#xff0c;不轻末学&#xff0c;善根成熟了他会发心&#xff0c;将来也能成佛。舍有为而不执著无为&#xff0c;住无为而不舍有为&#xff0c;…

正方实践系统打卡

Use HTTP (已完成) &#x1f4dc; 使用指南 &#x1f6d6; 项目结构 log 日志文件 use 使用情况 (待) data.py 数据 log.py 日志 main.py 主函数 只需要修改data.py文件内容即可&#xff1a; header ——> 头文件 User-AgentCookieAccept user ——> 用户信息 ZFT…

Kafka3.0.0版本——消费者(消费者组详细消费流程图解及消费者重要参数)

目录 一、消费者组详细消费流程图解二、消费者的重要参数 一、消费者组详细消费流程图解 创建一个消费者网络连接客户端&#xff0c;主要用于与kafka集群进行交互&#xff0c;如下图所示&#xff1a; 调用sendFetches发送消费请求&#xff0c;如下图所示&#xff1a; (1)、Fet…