数据结构和算法(13):优先级队列

概述

按照事先约定的优先级,可以始终高效查找并访问优先级最高数据项的数据结构,也统称作优先级队列

优先级队列将操作对象限定于当前的全局极值者

根据数据对象之间相对优先级对其进行访问的方式,与此前的访问方式有着本质区别,称作 循优先级访问 (call-by-priority)。

“全局极值”本身就隐含了“所有元素可相互比较”这一性质。然而,优先级队列并不一定需要动态维护这个全序,却转而维护一个偏序(partial order)关系。
因此:优先级队列不仅足以高效地支持仅针对极值对象的接口操作,更可有效地控制整体计算成本。

词条(entry):优先级队列中的数据项;
关键码(key):与特定优先级相对应的数据属性;
作为确定词条优先级的依据,关键码之间必须可以比较大小.

基本实现

优先级队列作为一类独特数据结构的意义在于通过转而维护词条集的一个偏序关系。

操作接口

操作结构功能描述
size()报告优先级队列的规模,即其中词条的总数
insert()将指定词条插入优先级队列
getMax()返回优先级最大的词条(若优先级队列非空)
delMax()删除优先级最大的词条(若优先级队列非空)

接口定义

template <typename T> struct PQ { // 优先级队列 PQ 模板类virtual void insert ( T )= ; // 按照比较器确定的优先级次序插入词条virtual T getMax() = ; // 取出优先级最高的词条virtual T delMax() = ; // 删除优先级最高的词条
}

因为这一组基本的ADT接口可能有不同的实现方式,故这里均以虚函数形式统一描述这些接口,以便在不同的派生类中具体实现。
借助无序列表、有序列表、无序向量或有序向量,都难以同时兼顾insert()delMax()操作的高效率。

完全二叉堆:结构

结构性: 逻辑结构须等同于完全二叉树,如此,堆节点将与词条一一对应;
堆序性: 优先级而言,堆顶以外的每个节点都不高(大)于其父节点;

堆中优先级最高的词条必然始终处于堆顶位置。因此,堆结构的getMax()操作总是可以在O(1)时间内完成。
堆顶以外的每个节点都不低(小)于其父节点。
在这里插入图片描述
结构等同于完全二叉树:n 个词条组成的堆的高度 h = ⌊ log ⁡ 2 n ⌋ = O ( l o g n ) h = \lfloor \log_2 n \rfloor = \cal O(logn) h=log2n=O(logn)
insert()delMax()操作的时间复杂度将线性正比于堆的高度h,故它们均可在O(logn)的时间内完成。

完全二叉堆的拓扑联接结构,完全由其规模n确定。节点在物理上连续排列,故总共仅需O(n)空间,而且利用各节点的编号(或秩),也可便捷地判别父子关系。

实现

#include "../Vector/Vector.h" //借助多重继承机制,基于向量
#include "../PQ/PQ.h" //按照优先级队列ADT实现的
template <typename T> class PO ComplHeap : public POT>, public Vector<T>[ //完全二又堆
protected:Rank percolateDown ( Rank n,Rank i ); //下滤Rank percolateUp ( Rank i ); //上滤void heapify ( Rank n ); //Floyd建堆算法
public:PQ_ComplHeap()[}//默认构造PQ_ComplHeap ( T* A, Rank n )[ copyFrom ( A,,n ); heapify ( n );} //批量构造void insert ( T );//按照比较器确定的优先级次序,插入词条T getMax();//读取优先级最高的词条T delMax(); //删除优先级最高的词条}; //PO CompIHeap

全局优先级最高的词条总是位于堆顶:只需返回向量的首单元,即可在O(1)时间内完成getMax()操作。

template<typename T> Y PQ_ComplHeap<T>::getMax() {return _elem[0];	//取优先级最高的词条

完全二叉堆:插入与上滤

插入算法分为两个步骤:1. 首先将新词条接至向量末尾; 2.再对该词条实施上滤调整。
在这里插入图片描述

template <typename T> void PQ_ComplHeap<T>::insert (Te){ //将词条插入完全二叉堆中Vector<T>::insert ( e ); //首先将新词条接至向量未尾percolateUp ( _size - 1 ); //再对该词条实施上滤调整
}

尽管此时如图(a)所示,新词条的引入并未破坏堆的结构性,但只要新词条e不是堆顶,就有可能与其父亲违反堆序性。所以需要对新接入的词条做适当调整,在保持结构性的前提下恢复整体的堆序性。

上滤

假定原堆非空,于是新词条e的父亲p(深色节点)必然存在。
根据e在向量中对应的秩,可以简便地确定词条p对应的秩,即 i ( p ) = ⌈ i ( e ) − 1 ) ⌉ i(p) = \lceil i(e) - 1) \rceil i(p)=i(e)1)⌉
若经比较判定 e ≤ p e \leq p ep,则堆序性在此局部以至全堆均已满足,插入操作因此即告完成。反之,若 e > p e > p e>p,则可在向量中令 ep 互换位置。如图(b)所示,如此不仅全堆的结构性依然满足,而且ep之间的堆序性也得以恢复。
当然,此后e与其新的父亲,可能再次违背堆序性。若果真如此,继续套用以上方法,如图( c)所示令二者交换位置。

每交换一次,新词条e都向上攀升一层,故这一过程也形象地称作上滤(percolate up)。一旦上滤完成,则如图(d)所示,全堆的堆序性必将恢复。

//对向量中的第i个词条实施上滤操作,i < _size
template <typename T> Rank PQ ComplHeap<T>::percolateUp ( Rank i ){while ( ParentValid ( i ) ) //只要i有父亲( 尚未抵达堆顶),则Rank j = Parent (i); //将i之父记作jif ( lt ( _elem[i], _elem[j] ) ) break; //一旦当前父子不再逆序,上滤旋即完成swap ( _elem[i], _elem[j] );i = j; //否则,父子交换位置,并继续考查上一层}//whilereturn i; //返回上滤最终抵达的位置
}

上滤调整过程中交换操作的累计次数,不致超过全堆的高度 log2 n。而在向量中,每次交换操作只需常数时间,故上滤调整乃至整个词条插入算法整体的时间复杂度,均为 O(logn)

实例
在这里插入图片描述
在如图(a)所示由5个元素组成的初始完全堆中,现拟插入关键码为5的新元素。为此,首先如图(b)所示,将该元素置于向量的末尾。此时,新元素5与其父节点0逆序,故如图©所示,经一次交换之后,新元素5上升一层。此后,新元素5与其新的父节点4依然逆序,故如图(d)所示,经一次交换后再上升一层。此时因已抵达堆顶,插入操作完毕,故算法终止。

//对向量中的第i个词条实施上滤操作,i < _size
template <typename T> Rank PQ_ComplHeap<T> :: percolateUp ( Rank i ) {while ( Parentvalid ( i ) ) { //只要i有父亲(尚未抵达堆顶),则Rank j = Parent ( i );	//将i之父记作jif ( lt ( _elem[i],_elem[j] ) ) break; //一旦当前父子不再逆序,上滤旋即完成swap (_elem[i],_elem[j]); i = j; //否则,父子交换位置,并继续考查上一层}	//whilereturn i;	//返回上滤最终抵达的位置
}

完全二叉堆:删除与下滤

删除算法也分为两个步骤:1.待删除词条r总是位于堆顶,可直接将其取出并备份;2.摘除堆顶(首词条),代之以末词条,对新堆顶实施下滤,将最末尾的词条e转移至堆顶。

template <typename T> T PQ_ComplHeap<T>::delMax() {	//删除非空完全二叉堆中优先级最高的词条T maxElem = _elem[0]; _elem[0] = _elem[ --_size ];	//摘除堆顶(首词条),代之以末词条percolateDown ( _size, 0 );	//对新堆顶实施下滤
return maxElem;	//返回此前备份的最大词条

实例
在这里插入图片描述

若新堆顶e不满足堆序性,则可如图(c )所示,将e与其(至多)两个孩子中的大者(图中深色节点)交换位置。与上滤一样,由于使用了向量来实现堆,根据词条e的秩可便捷地确定其孩子的秩。
此后,堆中可能的缺陷依然只能来自于词条e——它与新孩子可能再次违背堆序性。若果真如此,继续套用以上方法,将e与新孩子中的大者交换,结果如图(d)所示。实际上,只要有必要,此后可如图(e)和(f)不断重复这种交换操作。

因每经过一次交换,词条e都会下降一层,故这一调整过程也称作下滤(percolate down)。
下滤乃至整个删除算法的时间复杂度也为O(logn)

//对向量前 n 个词条中的第 i 个实施下滤,i < n
template <typename T> Rank PQ_ComplHeap<T> :: percolateDown ( Rank n,Rank i ) {Rank j; //i及其(至多两个)孩子中,堪为父者while ( i != ( j = ProperParent ( _elem,n, i ) ))	//只要 i 非 j,则{ swap ( _elem[i],_elem[j] ); i = j; }	//二者换位,并继续考查下降后的 ireturn i;	//返回下滤抵达的位置(亦 i 亦 j)
}

完全二叉堆:批量建堆

建堆:给定一组词条,高效地将它们组织成一个堆。

蛮力算法

从空堆起反复调用标准insert()接口,即可将输入词条逐一插入其中,并最终完成建堆任务。
具体地,若共有n个词条,则共需迭代n次。第k轮迭代耗时O(logk),故累计耗时间量应为:O(log1 + log2 + ... + logn) = O(logn!) = O(nlogn)

自上而下的上滤:对任何一棵完全二叉树,只需自顶而下、自左向右地针对其中每个节点实施一次上滤,即可使之成为完全二叉堆。在此过程中,为将每个节点纳入堆中,所需消耗的时间量将线性正比于该节点的深度:O(nlogn)

Floyd 算法

任给堆 H 0 H_0 H0 H 1 H_1 H1 ,以及另一独立节点 p p p ,如何高效地将 H 0 ∪ { P } ∪ H 1 H_0 \cup \{P\} \cup H_1 H0{P}H1 转化为堆?
在这里插入图片描述
首先为满足结构性,可将这两个堆当作 p p p 的左、右子树,联接成一棵完整的二叉树。此时若 p p p 与孩子 r 0 r_0 r0 r 1 r_1 r1 满足堆序性,则该二叉树已经就是一个不折不扣的堆。
此时的场景完全等效于,在delMax()操作中摘除堆顶,再将末位词条 ( p ) (p) (p) 转移至堆顶。
自底而上地反复套用可不断地将处于下层的堆捉对地合并成更高一层的堆,并最终得到一个完整的堆。
按照这一构思,即可实现 Floyd 建堆算法:

template <typename T> void PQ_ComplHeap<T>::heapify ( Rank n ) { //Floyd建堆算法,O(n)时间for ( int i = LastInternal ( n ); InHeap ( n, i ); i-- )	//自底而上,依次percolateDown ( n, i );	//下滤各内部节点
}

只需自下而上、由深而浅地遍历所有内部节点,并对每个内部节点分别调用一次下滤算法percolateDown()

实例

在这里插入图片描述

复杂度
算法依然需做n步迭代,以对所有节点各做一次下滤。这里,每个节点的下滤所需的时间线性正比于其高度,故总体运行时间取决于各节点的高度总和

不妨仍以高度为h、规模为 n = 2 h + 1 − 1 n = 2^{h+1} - 1 n=2h+11 的满二叉树为例做一大致估计,运行时间应为:O(n)
由于在遍历所有词条之前,绝不可能确定堆的结构,故以上已是建堆操作的最优算法。
各节点所消耗的时间线性正比于其深度——而在完全二叉树中,深度小的节点,远远少于高度小的节点。

堆排序

堆排序算法: 对于向量中的 n 个词条,借助堆的相关算法,实现高效的排序。
将所有词条分成未排序和已排序两类,不断从前一类中取出最大者,顺序加至后一类中。算法启动之初,所有词条均属于前
一类;此后,后一类不断增长;当所有词条都已转入后一类时,即完成排序。

将其划分为前缀H和与之互补的后缀S,分别对应于上述未排序和已排序部分。
与常规选择排序算法一样,在算法启动之初H覆盖所有词条,而S为空。新算法的不同之处在于,整个排序过程中,无论H包含多少词条,始终都组织为一个堆。
H中的最大词条不会大于S中的最小词条——除非二者之一为空,比如算法的初始和终止时刻。

在这里插入图片描述
首先如图(a),取出首单元词条M,将其与末单元词条x交换。M既是当前堆中的最大者,同时根据不变性也不大于S中的任何词条,故如此交换之后M必处于正确的排序位置。
如图(b),此时可等效地认为S向前扩大了一个单元,H相应地缩小了一个单元。请注意,如此重新分界之后的HS依然满足以上不变性。至此,唯一尚未解决的问题是,词条x通常不能“胜任”堆顶的角色。
最后如图(c ),对X实施一次下滤调整,即可使H整体的堆序性重新恢复。

复杂度
在每一步迭代中,交换MX只需常数时间,对x的下滤调整不超过O(logn)时间。因此,全部n步迭代累计耗时不超过O(nlogn)。即便使用蛮力算法而不是Floyd算法来完成H的初始化,整个算法的运行时间也不超过O(nlogn)

实现

template ctypename T〉 void Vector<T>::heapSort ( Rank lo,Rank hi ) { //0 <= lo < hi 〈= sizePQ_ComplHeap<T> H ( _elem + lo , hi - lo );	//将待排序区间建成一个完全二叉堆,O(n)while ( !H.empty() )	//反复地摘除最大元并归入已排序的后缀,直至堆空_elem[--hi] = H.delMax( );	//等效于堆顶与末元素对换后下滤
}

左式堆:结构

堆合并:任给堆A和堆B,将二者所含的词条组织为一个堆。
在这里插入图片描述

简单方法1:反复取出堆 B 的最大词条并插入堆 A 中;当堆 B 为空时,堆 A 即为所需的堆 H。

while ( ! B.empty() )A.insert( B.delMax() );

将两个堆的规模分别记作 n n n m m m ,且 n ≥ m n \geq m nm。每一步迭代均需做一次删除操作和一次插入操作,分别耗时 O ( log ⁡ m ) \mathcal O(\log m) O(logm) O ( log ⁡ ( n + m ) ) \mathcal O(\log(n + m)) O(log(n+m))。因共需做 m m m 步迭代,故总体运行时间应为:
m × [ O ( log ⁡ m ) + O ( log ⁡ ( n + m ) ) ] = O ( m log ⁡ ( n + m ) ) = O ( m log ⁡ n ) m \times [ \mathcal O( \log m) + \mathcal O(\log (n + m))] = \mathcal O(m \log(n + m)) = \mathcal O(m \log n) m×[O(logm)+O(log(n+m))]=O(mlog(n+m))=O(mlogn)

简单方法2:将两个堆中的词条视作彼此独立的对象,从而可以直接借助 Floyd 算法,将它们组织为一个新的堆 H。该方法的运行时间应为: O ( n + m ) = O ( n ) \mathcal O(n + m) = \mathcal O(n) O(n+m)=O(n).

左式堆(leftist heap)是优先级队列的另一实现方式,可高效地支持堆合并操作
基本思路在保持堆序性的前提下附加新的条件,使得在堆的合并过程中,只需调整很少量的节点。
具体地,需参与调整的节点不超过O(logn)个,故可达到极高的效率。
在这里插入图片描述
左式堆的整体结构呈单侧倾斜状;依照惯例,其中节点的分布均偏向左侧。也就是说,左式堆将不再如完全二叉堆那样满足结构性。

#include "../PQ/PQ.h"	//引入优先级队列ADT
#include "../BinTree/BinTree.h"	//引入二叉树节点模板类
template <typename T>
class PQ_LeftHeap : public PQ<T>, public BinTree<T>{	//基于二叉树,以左式堆形式实现的PQ
public:PO_LeftHeap() { }//默认构造Po_LeftHeap ( T* E, int n )	//批量构造:可改进为Floyd建堆算法{ for ( int i = 0; i < n; i++ ) insert (E[i]);	}void insert ( T );	//按照比较器确定的优先级次序插入元素T getMax();	//取出优先级最高的元素T delMax();	//删除优先级最高的元素
}; //Po_LeftHeap

PQ_LeftHeap首先继承了优先级队列对外的标准ADT接口。另外,既然左式堆的逻辑结构已不再等价于完全二叉树,改用紧凑性稍差、灵活性更强的二叉树结构,将更具针对性。其中蛮力式批量构造方法耗时O(nlogn),利用Floyd算法可改进至O(n)

空节点路径长度

节点x的空节点路径长度(null path length),记作npl(x)。若x为外部节点,则约定npl(x) = npl(null) = 0。反之若x为内部节点,则npl(x)可递归地定义为:npl(x) = 1 + min( npl(lc(x)), npl(rc(x)) )
节点xnpl值取决于其左、右孩子npl值中的小者。
npl(x)既等于x到外部节点的最近距离,同时也等于以x为根的最大满子树的高度。

左倾性与左式堆

左式堆是处处满足“左倾性”的二叉堆,即任一内部节点x都满足: npl ( l c ( x ) ) ≥ npl ( r c ( x ) ) \text{npl}(lc(x)) \geq \text{npl}(rc(x)) npl(lc(x))npl(rc(x))
在这里插入图片描述
左式堆:左孩子的npl值不小于右孩子,而前者的高度却可能小于后者。

左式堆中任一内节点x都应满足:npl(x) = 1 + npl(rc(x))
左式堆中每个节点的npl值,仅取决于其右孩子。

最右侧通路

x出发沿右侧分支一直前行直至空节点,经过的通路称作其最右侧通路,记作rPath(x)
在这里插入图片描述
每个节点的npl值,应恰好等于其最右侧通路的长度。

rPath(r)的终点必为全堆中深度最小的外部节点。
若记: n p l ( r ) = ∣ r P a t h ( r ) ∣ = d npl(r) = |rPath(r)| = d npl(r)=rPath(r)=d,则该堆应包含一棵以 r r r 为根、高度为 d d d 的满二叉树(黑色部分),且该满二叉树至少应包含 2 d + 1 − 1 2^{d+1} -1 2d+11 个节点、 2 d − 1 个 2^d - 1个 2d1 内部节点——这也是堆的规模下限。反之,在包含 n n n 个节点的左式堆中,最右侧通路必然不会长于:log2(n+1)-1 = O(logn)

左式堆:合并算法

在这里插入图片描述
递归地将 a a a 的右子堆 a R a_R aR 与堆 b b b合并,然后作为节点 a a a 的右孩子替换原先的 a R a_R aR。最后比较a左、右孩子的 npl 值——如有必要还需将二者交换,以保证左孩子的 npl 值不低于右孩子

实现

template <typename T>	//根据相对优先级确定适宜的方式,合并以a和b为根节点的两个左式堆
static BinNodePosi(T) merge ( BinNodePosi(T) a,BinNodePosi(T) b ) {if ( ! a ) return b;//退化情况if ( ! b ) return a;//退化情况if ( lt ( a->data,b->data ) ) swap ( a, b );//一般情况∶首先确保b不大a->rc = merge ( a->rc, b );	//将a的右子堆,与 b 合并a->rc->parent = a;//并更新父子关系if ( !a->lc || a->lc->npl < a->rc->npl )	//若有必要swap ( a->lc,a->rc );	//交换a的左、右子堆,以确保右子堆的npl不大a->npl = a->rc ? a->rc->npl + 1 : 1;	//更新a的nplreturn a;//返回合并后的堆顶
}	//算法只实现结构上的合并

首先判断并处理待合并子堆为空的平凡情况。然后再通过一次比较,以及在必要时所做的一次交换,以保证堆顶a的优先级总是不低于另一堆顶b
递归地将a的右子堆与堆b合并,并作为a的右子堆重新接入。递归返回之后,还需比较此时a左、右孩子的npl值,如有必要还需令其互换,以保证前者不小于后者。此后,只需在右孩子npl值的基础上加一,即可得到堆顶a的新npl值。至此,合并方告完成。

复杂度
递归只可能发生于两个待合并堆的最右侧通路上。
若待合并堆的规模分别为nm,则其两条最右侧通路的长度分别不会超过O(logn)O(logm),因此合并算法总体运行时间应不超过:O(logn) + O(logm) = O( logn + logm ) = O(log(max(n, m)))

左式堆:插入和删除

基于堆合并操作实现删除接口

在这里插入图片描述
在摘除x之后,HLHR 即可被视作为两个彼此独立的待合并的堆。
于是,只要通过merge()操作将它们合并起来,则其效果完全等同于一次常规的delMax()删除操作。

template <typename T> T PQ_LeftHeap<T>::delMax(){	//基于合并操作的词条删除算法(当前队列非空)BinNodePosi(T) lHeap = _root->lc; 	//左子堆BinNodePosi(T) rHeap = _root->rc;	//右子堆T e = _root->data; delete _root; _size--;	//删除根节点_root = merge ( lHeap,rHeap );		//原左右子堆合并if ( _root ) _root->parent = NULL;//若堆非空,还需相应设置父子链接return e;//返回原根节点的数据项
}

时间成本主要消耗于对merge()的调用,总体依然不超过O(logn)。

基于堆合并操作实现词条插入算法

在这里插入图片描述
只要将x也视作(仅含单个节点的)堆,则通过调用merge()操作将该堆与堆H合并之后,其效果即完全等同于完成了一次词条插入操作。

template <typename T> void PQ_LeftHeap<T>::insert ( T e ) {	//基于合并操作的词条插入算法BinNodePosi(T) v = new BinNode<T> ( e ); //为e创建一个二叉树节点_root = merge ( _root,v );	//通过合并完成新节点的插入_root->parent = NULL;	//既然此时堆非空,还需相应设置父子链接_size++;	//更新规模
}

时间成本主要也是消耗于对merge()的调用,总体依然不超过O(logn)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springBoot--web--静态资源规则

规则一&#xff1a; 访问&#xff1a;/webjars/** 路径就去 classpath:/META-INF/resources/webjars/下载资源 a.maven导入依赖 规则二&#xff1a; 访问&#xff1a;/** 路径就去 静态资源默认的四个位置找资源 a. classpath:/META-INF/resources/ b.classpath:/resourc…

【UE5】 ListView使用DataTable数据的蓝图方法

【UE5】 ListView使用DataTable数据的蓝图方法 ListView 是虚幻引擎中的一种用户界面控件&#xff0c;用于显示可滚动的列表。它可以用于显示大量的数据&#xff0c;并提供了各种功能和自定义选项来满足不同的需求。 DataTable是虚幻引擎中的一种数据表格结构&#xff0c;用于存…

Flink学习笔记(三):Flink四种执行图

文章目录 1、Graph 的概念2、Graph 的演变过程2.1、StreamGraph (数据流图)2.2、JobGraph (作业图)2.3、ExecutionGraph (执行图)2.4、Physical Graph (物理图) 1、Graph 的概念 Flink 中的执行图可以分成四层&#xff1a;StreamGraph -> JobGraph -> ExecutionGraph -&g…

1811_spacemacs从v.0.200.13升级到v.0.200.14的几点变化感受

全部学习汇总&#xff1a; GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 安装了全新的spacemacs的配置&#xff0c;查看了一下版本是v.0.200.14。在此之前&#xff0c;我使用的版本是v.0.200.13。现在还没有在这个配置上完成我所有的…

[opencv]图像和特征点旋转

本来说这是很简单的一个内容&#xff0c;图像旋转只需要使用opencv中自带的旋转函数即可完成&#xff0c;但是最近在做特征点旋转的时候发现使用内置rotate函数给图像旋转90度&#xff0c;再用getRotationMatrix2D得出的旋转矩阵对特征点旋转&#xff0c;画出来的特征点位置全部…

Nginx+keepalived 高可用双机热备—双主模式

双机高可用方法目前分为两种&#xff1a; 1&#xff09;Nginxkeepalived 双机主从模式&#xff1a;即前端使用两台服务器&#xff0c;一台主服务器和一台热备服务器&#xff0c;正常情况下&#xff0c;主服务器绑定一个公网虚拟IP&#xff0c;提供负载均衡服务&#xff0c;热备…

中文编程工具开发软件实际案例:酒店饭店餐饮点餐管理系统软件编程实例

中文编程工具开发软件实际案例&#xff1a;酒店饭店餐饮点餐管理系统软件编程实例图片如下 软件的安装方法&#xff1a; 软件绿色免安装&#xff0c;压缩包文件解压后&#xff0c;将文件夹复制到电脑的D或E盘里&#xff0c;将软件目录下的红色程序图标按右键发送到桌面快捷方式…

Pinia学习-存储数据、修改数据以及持久化实现

Pinia是什么&#xff1f; Pinia 是 Vue 的存储库&#xff0c;实现全局变量的定义 这里定义的变量信息&#xff0c;任何页面都可以使用&#xff0c;代替原来的VueX 官网&#xff1a;https://pinia.web3doc.top/ 4.2 Pinia存储数据 4.2.1获取存储数据 实现步骤&#xff1a;…

ubuntu 20.04 使用systemback自定义系统镜像和系统备份

ubuntu 20.04 使用systemback自定义系统镜像和系统备份 Systemback简介1. 安装 systemback16.0418.04 查看 2. 使用 systemback创建自定义镜像制作镜像制作中制作完成将镜像写入U盘 Systemback简介 Systemback是一个简单的系统备份和恢复应用程序&#xff0c;根据GPLv3许可条款…

工业企业网络推广解决方案 | 网络营销专家分享 | 上海添力

在国内&#xff0c;工业企业如果想在线上做推广&#xff0c;其主要途径就是做搜索引擎推广&#xff0c;在几个常用的搜索引擎&#xff08;百度、360、搜狗、必应&#xff09;中&#xff0c;一般都是从百度开始做起。但不少工厂做百度广告&#xff0c;钱花了不少&#xff0c;就是…

iOS上架App Store的全攻略

​ 第一步&#xff1a;申请开发者账号 在开始将应用上架到App Store之前&#xff0c;你需要申请一个开发者账号。 1.1 打开苹果开发者中心网站&#xff1a;Apple Developer 1.2 使用Apple ID和密码登录&#xff08;如果没有账号则需要注册&#xff09;&#xff0c;要确保使用…

AWS Lambda – 函数版本,别名,API网关,CodeDeploy协同

Hello大家好&#xff0c;我们今天继续讨论AWS Lambda的内容。 Lambda函数的版本 Lambda函数的版本和别名是辅助资源&#xff0c;我们可以通过创建这些资源管理函数的部署和调用。 首先&#xff0c;让我们来看一下Lambda 函数版本的概念。您可以使用版本来管理函数的部署。例…

Win10系统开机启动文件夹在哪里找?

Win10系统开机启动文件夹在哪里找&#xff1f;Win10系统开机启动文件夹是一个非常重要的目录&#xff0c;它决定了电脑在开机的时候&#xff0c;会有哪些应用程序是自动启动。但是&#xff0c;很多新手用户不知道Win10电脑内开机启动文件夹的具体位置&#xff0c;下面小编介绍开…

paddlenlp:社交网络中多模态虚假媒体内容核查(特征篇)

初赛之特征构造 写在前面一、安装paddleOCR二、代码部分三、模型优缺点四、写在最后 写在前面 通过前面两篇文章的介绍&#xff0c;我们可以大致的知道模型用到的特征分为四块&#xff1a;qCap&#xff0c;qImg&#xff0c;captions&#xff0c;imgs。根据这些特征&#xff0c…

人工智能(pytorch)搭建模型20-基于pytorch搭建文本生成视频的生成对抗网络,技术创新点介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型20-基于pytorch搭建文本生成视频的生成对抗网络&#xff0c;技术创新点介绍&#xff0c;随着人工智能和深度学习技术的飞速发展&#xff0c;文本到视频生成已经成为计算机视觉领域中一个重…

pragma once与ifndef的区别

概要 代码编译过程中&#xff0c;为了防止同一份代码被重复引用&#xff0c;通常有两种实现方式 方式一 #pragma once 方式二 #ifndef _TEST_H_ #define _TEST_H_ #endif // !TEST_H 通常情况下&#xff0c;使用上述两种方式中的任意一种都是可以的。最近工作中&#xff0c;代…

055:mapboxGL中加载geojson,导出为CSV格式文件

vue+mapbox 第055个 点击查看专栏目录 本示例介绍演示如何在vue+mapbox中加载geojson,导出为CSV格式文件。 通过一个插件,将geojson转化为csv,同时通过file-saver将文件下载下来。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果导出后的…

智能电表的功率计算方式是一样的吗?

随着科技的发展&#xff0c;智能电表已经成为了家庭和企业用电的必备设备。智能电表不仅可以实现用电量的监测和控制&#xff0c;还可以对用电负荷进行管理和优化。在智能电表的使用过程中&#xff0c;功率计算是一个重要的环节。那么&#xff0c;智能电表的功率计算方式是一样…

跨境电商自养号测评:如何配置安全可靠的网络环境?

随着全球化的加速和互联网的普及&#xff0c;跨境电商已经逐渐成为全球电子商务的主流形式。越来越多的企业开始涉足跨境电商领域&#xff0c;希望通过跨越国界的贸易活动来扩大市场份额、提高品牌影响力&#xff0c;以及增加企业收益。 然而跨境电商是一个充满机遇和挑战的领…

NSSCTF做题(10)

叫10好听一点&#xff0c;就是补9的 第7页的内容 [SWPUCTF 2022 新生赛]ez_sql get传参说是不安全&#xff0c;那就只能用post了 有回显了&#xff0c;两个假的flag 发现万能密码 1 or 11#变成了 11# 11# 1 11#1# 11# 11# 发现or和空格都无了&#xff0c;union也过滤 …