算法设计与分析实验报告c++实现(TSP问题、哈夫曼编码问题、顾客安排问题、最小生成树问题、图着色问题)

一、实验目的

1.加深学生对贪心算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

用贪心算法实现:
1、TSP问题
TSP问题(Travelling Salesman Problem)即旅行商问题,又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。
2、哈夫曼编码问题
a.写一个程序,为给定的英文文本构造一套哈夫曼编码,并对该文本编码。
b.写一个程序,对一段用哈夫曼编码的英文文本进行解码。
c.做一个实验,测试对包含1000个词左右的一段英文文本进行哈夫曼编码时,典型的压缩率位于什么样的区间。
3、设有n个顾客同时等待一项服务,顾客i 需要的服务时间为ti ,i=1,2,3,…,n 。从时刻0开始计时,若在时刻t开始对顾客i服务,那么i的等待时间为t,应该怎么安排n个顾客的服务次序使得总的等待时间(每个顾客等待时间的总和)最少?
假设服务时间分别为{1,3,2,15,10,6,12},用贪心算法给出这个问题的解。
4、最小生成树问题(Prim算法和Kruskal算法)
设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价,在G的所有生成树中,代价最小的生成树称为最小生成树(Minimal Spanning Trees)。
5、图着色问题
给定无向连通图G=(V, E),求图G的最小色数k,使得用k种颜色对G中的顶点着色,可使任意两个相邻顶点着色不同。

三、实验设备及编程开发工具

编程开发工具:Microsoft Visual c++

四、实验过程设计(算法设计过程)

(一)TSP问题

1、基本算法思想
贪心算法:又称贪婪算法(greedy algorithm),该算法是指:在对问题求解时,总是做出当前情况下的最好选择,否则将来可能会后悔,故名“贪心”。这是一种算法策略,每次选择得到的都是局部最优解。选择的策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
针对TSP问题,使用贪心算法的求解的过程为:
1.从某一个城市开始,每次选择一个城市,直到所有的城市被走完。
2.每次在选择下一个城市的时候,只考虑当前情况,保证迄今为止经过的路径总距离最小。
2、源程序

#include<iostream> 
using namespace std; 
#define n 4 
int main() 
{   int i,j,k,l; 
	int S[n];//用于存储已访问过的城市 
	int D[n][n];//用于存储两个城市之间的距离 
	int sum = 0;//用于记算已访问过的城市的最小路径长度 
	int Dtemp;//保证Dtemp比任意两个城市之间的距离都大(其实在算法描述中更准确的应为无穷大) 
	int flag;最为访问的标志,若被访问过则为1,从未被访问过则为0 /*初始化*/ 
	i = 1;//i是至今已访问过的城市 
	S[0] = 0; 
	D[0][1] = 2;
	D[0][2] = 6;
	D[0][3] = 5;
	D[1][0] = 2;
	D[1][2] = 4; 
	D[1][3] = 4;
	D[2][0] = 6;
	D[2][1] = 4;
	D[2][3] = 2;
	D[3][0] = 5; 
	D[3][1] = 4;
	D[3][2] = 2; 
	do{ 
		k = 1;
		Dtemp = 10000; 
		do{ 
			l = 0;
			flag = 0; 
			do{ 
				if(S[l] == k){//判断该城市是否已被访问过,若被访问过, 
				flag = 1;//则flag为1 
				break;//跳出循环,不参与距离的比较 
				}else 
					l++; 
			}while(l < i); 
			if(flag == 0&&D[k][S[i - 1]] < Dtemp){/*D[k][S[i - 1]]表示当前未被访问的城市k与上一个已访问过的城市i-1之间的距离*/ 
				j = k;//j用于存储已访问过的城市k 
				Dtemp = D[k][S[i - 1]];//Dtemp用于暂时存储当前最小路径的值 
			} 
			k++; 
		}while(k < n);
		S[i] = j;//将已访问过的城市j存入到S[i]中 
		i++; 
		sum += Dtemp;//求出各城市之间的最短距离,注意:在结束循环时,该旅行商尚未回到原出发的城市 
	}while(i < n); 
	sum += D[0][j];//D[0][j]为旅行商所在的最后一个城市与原出发的城市之间的距离 
	cout<<"经过的城市的路径:";
	for(j = 0; j < n; j++){ //输出经过的城市的路径 
		cout<<j<<" "; 
	} 
	cout<<"\n访问过的城市的最小路径长度:"<<sum<<"\n";//求出最短路径的值
	
}

(二)哈夫曼编码问题

1、基本算法思想
哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。其构造步骤如下:
(1)哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。
(2)算法以|C|个叶结点开始,执行|C|-1次的“合并”运算后产生最终所要求的树T。
(3)假设编码字符集中每一字符c的频率是f©。
以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树。
一旦2棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的2棵树的频率之和,并将新树插入优先队列Q。
经过n-1次的合并后,优先队列中只剩下一棵树,即所要求的树T。.
2、源程序

#include<iostream>  
#include<string>  
using namespace std;
struct Node
{
    double weight;  
    string ch;  
    string code; 
    int lchild, rchild, parent;
};

void Select(Node huffTree[], int *a, int *b, int n)//找权值最小的两个a和b  
{
    int i;
    double weight = 0; //找最小的数
    for (i = 0; i <n; i++)
    {
        if (huffTree[i].parent != -1)     //判断节点是否已经选过
            continue;
        else
        {
            if (weight == 0)
            {
                weight = huffTree[i].weight;
                *a = i;
            }
            else
            {
                if (huffTree[i].weight < weight)
                {
                    weight = huffTree[i].weight;
                    *a = i;
                }
            }
        }
    }
    weight = 0; //找第二小的数
    for (i = 0; i < n; i++)
    {
        if (huffTree[i].parent != -1 || (i == *a))//排除已选过的数
            continue;
        else
        {
            if (weight == 0)
            {
                weight = huffTree[i].weight;
                *b = i;
            }
            else
            {
                if (huffTree[i].weight  < weight)
                {
                    weight = huffTree[i].weight;
                    *b = i;
                }
            }
        }
    }
    int temp;
    if (huffTree[*a].lchild < huffTree[*b].lchild)  //小的数放左边
    {
        temp = *a;
        *a = *b;
        *b = temp;
    }
}

void Huff_Tree(Node huffTree[], int w[], string ch[], int n)
{
    for (int i = 0; i < 2 * n - 1; i++) //初始过程
    {
        huffTree[i].parent = -1;    
        huffTree[i].lchild = -1;    
        huffTree[i].rchild = -1;  
        huffTree[i].code = "";
    }
    for (int i = 0; i < n; i++)       
    {
        huffTree[i].weight = w[i];  
        huffTree[i].ch = ch[i];     
    }
    for (int k = n; k < 2 * n - 1; k++)
    {
        int i1 = 0;
        int i2 = 0;
        Select(huffTree, &i1, &i2, k); //将i1,i2节点合成节点k
        huffTree[i1].parent = k;   
        huffTree[i2].parent = k;
        huffTree[k].weight = huffTree[i1].weight + huffTree[i2].weight;
        huffTree[k].lchild = i1;
        huffTree[k].rchild = i2;
    }
}
 
void Huff_Code(Node huffTree[], int n)
{
    int i, j, k;
    string s = "";
    for (i = 0; i < n; i++)  
    {
        s = "";         
        j = i;                
        while (huffTree[j].parent != -1) //从叶子往上找到根节点
        {
            k = huffTree[j].parent;
            if (j == huffTree[k].lchild) //如果是根的左孩子,则记为0
            {
                s = s + "0";
            }
            else               
            {
                s = s + "1";
            }
            j = huffTree[j].parent; 
        }
        cout << "字符 " << huffTree[i].ch << " 的编码:";
        for (int l = s.size() - 1; l >= 0; l--)    
        {
            cout << s[l];
            huffTree[i].code += s[l]; //保存编码
        }
        cout << endl;
    }
}
string Huff_Decode(Node huffTree[], int n,string s)
{
    cout << "解码后为:";
    string temp = "",str="";//保存解码后的字符串
    for (int i = 0; i < s.size(); i++)
    {
        temp = temp + s[i];
        for (int j = 0; j < n; j++)
        {    
            if (temp == huffTree[j].code)
            {
                str=str+ huffTree[j].ch;
                temp = "";
                break;
            }    
            else if (i == s.size()-1&&j==n-1&&temp!="")//全部遍历后没有
            {
                str= "解码错误!";
            }
        }
    }
    return str;
}

int main()
{
    //编码过程
    const int n=5;
    Node huffTree[2 * n];
    string str[] = { "A", "B", "C", "D", "E"};
    int w[] = { 30, 30, 5, 20, 15 };
    Huff_Tree(huffTree, w, str, n);
    Huff_Code(huffTree, n);
    //解码过程
    string s;
    cout << "输入编码:";
    cin >> s;
    cout << Huff_Decode(huffTree, n, s)<< endl;;
    system("pause");
    return 0;
} 

(三)动态服务问题

1、基本算法思想
如果f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
2、源程序

#include <iostream>
#include<cstdio>
#define N 100
#define MAX(a,b) a < b ? b : a
using namespace std;

struct goods{
int sign;//物品序号
int wight;//物品重量
int value;//物品价值
};

int n,bestValue,cv,cw,C;//物品数量,价值最大,当前价值,当前重量,背包容量
int X[N],cx[N];//最终存储状态,当前存储状态
struct goods goods[N];

int KnapSack(int n,struct goods a[],int C,int x[]){
    int V[N][10*N];
    for(int i = 0; i <= n; i++)//初始化第0列
        V[i][0] = 0;
    for(int j = 0; j <= C; j++)//初始化第0行
        V[0][j] = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= C; j++)
        if(j < a[i-1].wight)
            V[i][j] = V[i-1][j];
        else
            V[i][j] = MAX(V[i-1][j],V[i-1][j-a[i-1].wight] + a[i-1].value);

    for(int i = n,j = C; i > 0; i--){
        if(V[i][j] > V[i-1][j]){
            x[i-1] = 1;
            j = j - a[i-1].wight;
        }
        else
            x[i-1] = 0;
    }
    return V[n][C];
}
int main()
{
    printf("物品种类n:");
    scanf("%d",&n);
    printf("背包容量C:");
    scanf("%d",&C);
    for(int i = 0; i < n; i++){
        printf("物品%d的重量w[%d]及其价值v[%d]:",i+1,i+1,i+1);
        scanf("%d%d",&goods[i].wight,&goods[i].value);
    }
    int sum2 = KnapSack(n,goods,C,X);
     printf("动态规划法求解0/1背包问题:\nX=[");
     for(int i = 0; i < n; i++)
        cout<<X[i]<<" ";//输出所求X[n]矩阵
     printf("]   装入总价值%d\n", sum2);
     return 0;
}

(四)最小生成树问题

1、基本算法思想
Prim算法
1.概览
普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现;并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现;1959年,艾兹格·迪科斯彻再次发现了该算法。因此,在某些场合,普里姆算法又被称为DJP算法、亚尔尼克算法或普里姆-亚尔尼克算法。

2.算法简单描述
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。

Kruskal算法是一种用来寻找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪婪算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

2.算法简单描述
1).记Graph中有v个顶点,e个边
2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边
3).将原图Graph中所有e个边按权值从小到大排序
4).循环:从权值最小的边开始遍历每条边 直至图Graph中所有的节点都在同一个连通分量中 if 这条边连接的两个节点于图Graphnew中不在同一个连通分量中添加这条边到图Graphnew中
2、源程序

Prim算法

#include <iostream>
#include <vector>
using namespace std;

//Prim算法实现
void prim_test()
{
    int n;
    cin >> n;
    vector<vector<int> > A(n, vector<int>(n));
    for(int i = 0; i < n ; ++i) {
        for(int j = 0; j < n; ++j) {
            cin >> A[i][j];
        }
    }

    int pos, minimum;
    int min_tree = 0;
    //lowcost数组记录每2个点间最小权值,visited数组标记某点是否已访问
    vector<int> visited, lowcost;
    for (int i = 0; i < n; ++i) {
        visited.push_back(0);    //初始化为0,表示都没加入
    }
    visited[0] = 1;   //最小生成树从第一个顶点开始
    for (int i = 0; i < n; ++i) {
        lowcost.push_back(A[0][i]);    //权值初始化为0
    }

    for (int i = 0; i < n; ++i) {    //枚举n个顶点
        minimum = max_int;
        for (int j = 0; j < n; ++j) {    //找到最小权边对应顶点
            if(!visited[j] && minimum > lowcost[j]) {
                minimum = lowcost[j];
                pos = j;
            }
        }
        if (minimum == max_int)    //如果min = max_int表示已经不再有点可以加入最小生成树中
            break;
        min_tree += minimum;
        visited[pos] = 1;     //加入最小生成树中
        for (int j = 0; j < n; ++j) {
            if(!visited[j] && lowcost[j] > A[pos][j]) lowcost[j] = A[pos][j];   //更新可更新边的权值
        }
    }

    cout << min_tree << endl;
}

int main(void)
{
    prim_test();

    return 0;
}

Kruskal算法

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//并查集实现最小生成树
vector<int> u, v, weights, w_r, father;
int mycmp(int i, int j)
{
    return weights[i] < weights[j];
}
int find(int x)
{
    return father[x] == x ? x : father[x] = find(father[x]);
}
void kruskal_test()
{
    int n;
    cin >> n;
    vector<vector<int> > A(n, vector<int>(n));
    for(int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> A[i][j];
        }
    }

    int edges = 0;
    // 共计n*(n - 1)/2条边
    for (int i = 0; i < n - 1; ++i) {
        for (int j = i + 1; j < n; ++j) {
            u.push_back(i);
            v.push_back(j);
            weights.push_back(A[i][j]);
            w_r.push_back(edges++);
        }
    }
    for (int i = 0; i < n; ++i) {
        father.push_back(i);    // 记录n个节点的根节点,初始化为各自本身
    }

    sort(w_r.begin(), w_r.end(), mycmp); //以weight的大小来对索引值进行排序

    int min_tree = 0, cnt = 0;
    for (int i = 0; i < edges; ++i) {
        int e = w_r[i];    //e代表排序后的权值的索引
        int x = find(u[e]), y = find(v[e]);
        //x不等于y表示u[e]和v[e]两个节点没有公共根节点,可以合并
        if (x != y) {
            min_tree += weights[e];
            father[x] = y;
            ++cnt;
        }
    }
    if (cnt < n - 1) min_tree = 0;
    cout << min_tree << endl;
}

int main(void)
{

    kruskal_test();

    return 0;
}

(五)图着色问题

1、基本算法思想
图的m色优化问题:给定无向连通图G,为图G的各顶点着色, 使图中任2邻接点着不同颜色,问最少需要几种颜色。所需的最少颜色的数目m称为该图的色数。
若图G是可平面图,则它的色数不超过4色(4色定理).
4色定理的应用:在一个平面或球面上的任何地图能够只用4种
颜色来着色使得相邻的国家在地图上着有不同颜色
2、源程序

#include<stdio.h>

int color[100];
//int c[100][100];
bool ok(int k ,int c[][100])//判断顶点k的着色是否发生冲突
{
    int i,j;
    for(i=1;i<k;i++)
        if(c[k][i]==1&&color[i]==color[k])
            return false;
        return true;
}

void graphcolor(int n,int m,int c[][100])
{
    int i,k;
    for(i=1;i<=n;i++)
        color[i]=0;//初始化
    k=1;
    while(k>=1)
    {
        color[k]=color[k]+1;
        while(color[k]<=m)
            if (ok(k,c)) break;
            else color[k]=color[k]+1;//搜索下一个颜色

        if(color[k]<=m&&k==n)//求解完毕,输出解
            {
                for(i=1;i<=n;i++)
                    printf("%d ",color[i]);
                printf("\n");
                //return;//return表示之求解其中一种解
            }
            else if(color[k]<=m&&k<n)
                k=k+1;    //处理下一个顶点
            else
            {
                color[k]=0;
                k=k-1;//回溯
            }
    }
}
void main()
{
    int i,j,n,m;
    int c[100][100];//存储n个顶点的无向图的数组
    printf("输入顶点数n和着色数m:\n");
    scanf("%d %d",&n,&m);
    printf("输入无向图的邻接矩阵:\n");
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%d",&c[i][j]);
    printf("着色所有可能的解:\n");
    graphcolor(n,m,c);
}

五、实验结果及算法复杂度分析
(一)TSP问题
1、实验结果

img

2、时间复杂度
时间复杂度为O(n)
(二)哈夫曼编码问题
1、实验结果

img

2、时间复杂度
时间复杂度为 O ( n m 2 ) O(nm^2) O(nm2)
(三)动态服务问题

img

2、时间复杂度
时间复杂度为O(n)
(四)最小生成树问题
时间复杂度
Prim算法时间复杂度为邻接矩阵: O ( v 2 ) O(v^2) O(v2)邻接表: O ( e l o g 2 v ) O(elog2v) O(elog2v)

Kruskal算法时间复杂度为 O ( e l o g 2 e ) O(elog2e) O(elog2e)

(五)图着色问题
1、实验结果

img

2、时间复杂度
时间复杂度为 O ( n 2 ) O(n^2) O(n2)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 两种方法截取活动窗口屏幕,实现窗体截图

方法1&#xff0c;截屏内容仅包括活动窗口界面&#xff0c;而方法2是从屏幕范围取图&#xff0c;截屏内容会包括屏幕上所有内容。例如有一些程序在桌面顶层显示半透明的悬浮窗&#xff0c;用方法2截屏就会包括这些内容&#xff0c;并不是单纯的活动窗口内容。 方法1&#xff0c…

开源代码分享(19)-配电网孤岛优化划分方法

参考文献&#xff1a; DING Tao, LIN Yanling, LI Gengfeng, et al. A new model for resilient distribution systems by microgrids formation[J]. IEEE Transactions on Power Systems, 2017, 32(5): 4145-4147. 1.基本原理 通过分布式电源&#xff08;DGs&#xff09;形…

蓝桥杯 前一晚总结 模板 新手版

《准备实足&#xff0c;冲冲冲 省一》https://www.yuque.com/lenyan-svokd/hi7hp2/hfka297matrtsxy2?singleDoc# 《准备实足&#xff0c;冲冲冲 省一》 #include<bits/stdc.h> // 包含标准库头文件using namespace std; using ll long long; // 定义 long long 数据类…

218基于matlab的有限差分法求解泊松方程

基于matlab的有限差分法求解泊松方程&#xff0c;采用SOR超松弛迭代法。模型采用方形区域&#xff0c;划分网格数为100*100&#xff0c;网格数可以很方便的更改。程序已调通&#xff0c;可直接运行。 218有限差分法 泊松方程 SOR超松弛迭代法 - 小红书 (xiaohongshu.com)

基于React封装Handsontable并兼容antd

背景 其实Handsontable官方也提供了React的版本&#xff0c;但是官方的版本再编辑和渲染的时候并不能够很好的嵌入第三方的组件库。这就导致了&#xff0c;使用了Handsontable就没有办和普通的react项目一样轻松引用其他第三方组件。因此对其react的版本进行了二次的封装&#…

定制个性化的 openEuler 系统镜像:打造独特的安装体验

前言 标准的操作系统镜像可能无法完全满足特定用户群体或特定应用场景的需求。通过定制化&#xff0c;可以根据具体需求预装特定软件、配置特定网络设置&#xff0c;甚至设置特定的用户权限&#xff0c;以确保系统能够满足用户的需求。定制化系统镜像可以优化安装流程&#xf…

PandasAI的应用与实战解析(二):PandasAI使用流程与功能介绍

文章目录 1.使用PandasAI进行开发的流程2.配置文件解析3.支持的数据库类型4.支持的LLMs5.其他 PandasAI这个工具最突出的优点就是通过结合了Pandas和生成式LLMs&#xff0c;极大地为开发人员降低了工作量。 传统的开发调用流程&#xff08;数据分析相关&#xff09;&#xff1a…

(UDP)其他信息: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

“System.Net.Sockets.SocketException”类型的异常在 mscorlib.dll 中发生&#xff0c;但未在用户代码中进行处理其他信息: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。这个异常表示端口已经被占用了&#xff0c;需要释放端口或者使用其他端口来建立连接。您可以…

CLion 2024:为Mac与Win打造的卓越跨平台集成开发环境

CLion 2024作为一款跨平台IDE&#xff0c;CLion 2024不仅完美支持Mac和Windows两大操作系统&#xff0c;更在细节之处展现了其出色的跨平台兼容性。无论你是在Mac的优雅界面下工作&#xff0c;还是在Windows的实用环境中编程&#xff0c;CLion 2024都能为你提供一致且流畅的开发…

如何使用 Grafana 监控文件系统状态

当 JuiceFS 文件系统部署完成并投入生产环境&#xff0c;接下来就需要着手解决一个非常重要的问题 —— 如何实时监控它的运行状态&#xff1f;毕竟&#xff0c;它可能正在为关键的业务应用或容器工作负载提供持久化存储支持&#xff0c;任何小小的故障或性能下降都可能造成不利…

ES6: set和map数据结构以及使用场景

ES6:set和map数据结构 一、Set 数据结构&#xff1a;二、使用场景&#xff1a;使用Set 进行去重三、Map 数据结构四、使用场景&#xff1a;使用Map进行树型数据懒加载刷新五、Set和Map的区别六、Map、Set的实际使用场景 Set 和 Map 是 ES6 中引入的两种新的数据结构&#xff0c…

设计模式代码实战-装饰者模式

1、问题描述 小明喜欢品尝不同口味的咖啡&#xff0c;他发现每种咖啡都可以加入不同的调料&#xff0c;比如牛奶、糖和巧克力。他决定使用装饰者模式制作自己喜欢的咖啡。 请设计一个简单的咖啡制作系统&#xff0c;使用装饰者模式为咖啡添加不同的调料。系统支持两种咖啡类型…

ANSYS Electromagnetics Suite 2023 R2 三维电磁(EM)仿真软件下载

Ansys家最新的三维电磁&#xff08;EM&#xff09;仿真软件ANSYS Electromagnetics Suite 2023 R2日前发布了&#xff0c;老wu这次分享得有点晚 &#xffe3;ω&#xffe3;&#xff0c;现在已经将资源上传到了网盘供大家免费下载&#xff0c;同时&#xff0c;为了让大家都能与…

企业航拍VR全景视频展示仿如上门参观

360度VR全景视频因其广阔的视野和身临其境的体验&#xff0c;无论再房产楼盘的精致呈现&#xff0c;旅游景点的全景漫游&#xff0c;还是校园风光的生动展示&#xff0c;都成为企业商户的首选。 360度vr全景视频编辑软件是深圳VR公司华锐视点提供多种常见的三维仿真场景供选择&…

防火墙操作!

当小编在Linux服务器上部署好程序以后&#xff0c;但是输入URL出现下述情况&#xff0c;原来是防火墙的原因&#xff01;&#xff01; 下面是一些防火墙操作&#xff01; 为保证系统安全&#xff0c;服务器的防火墙不建议关闭&#xff01;&#xff01; 但是&#xff0c;我们可…

最优算法100例之44-不用加减乘除做加法

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 不用加减乘除做加法 题解报告 最优解法:使用异或 1)异或是查看两个数哪些二进制位只有一个为1,这些是非进位位,可以直接…

[python]cartopy安装后测试代码

测试环境&#xff1a; anaconda3python3.11 cartopy0.23.0 测试代码&#xff1a; # 导入所需的库 import matplotlib as mpl import matplotlib.pyplot as plt import cartopy.crs as ccrs# 创建画布以及ax fig plt.figure() ax fig.add_subplot(111, projectionccrs.Pla…

Android - 安卓概述

什么是安卓? Android 是一种基于 Linux 的开源操作系统&#xff0c;适用于智能手机和平板电脑等移动设备。 Android 是由 Google 和其他公司领导的 Open Handset Alliance 开发的。 Android 为移动设备的应用程序开发提供了统一的方法&#xff0c;这意味着开发人员只需为 And…

React + three.js 实现人脸动捕与3D模型表情同步

系列文章目录 React 使用 three.js 加载 gltf 3D模型 | three.js 入门React three.js 3D模型骨骼绑定React three.js 3D模型面部表情控制React three.js 实现人脸动捕与3D模型表情同步 示例项目(github)&#xff1a;https://github.com/couchette/simple-react-three-facia…

Rust跨平台编译

❝ 如果你感觉自己被困住了&#xff0c;焦虑并充满消极情绪&#xff0c;生命出现了停滞&#xff0c;那么治疗方法很简单&#xff1a;「做点什么」。 ❞ 大家好&#xff0c;我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder 前言 之前我们不是写了一篇R…