基于C#编程建立Vector数据类型及对应处理方法

news/2024/5/18 21:08:46/文章来源:https://blog.csdn.net/weixin_41649786/article/details/130071012

        以C#为例,讲解如何建立一个类,这其中需要考虑需要什么样的数据(成员),什么样的属性以及方法,以及提供给外部程序调用,最后考虑怎么样去实现这样的算法。例如对于一个向量Vector(类)而言,它需要一行数据,元素类型可以是int、double、float形式(或则是泛型<T>);需要的方法:向量的构造、显示、增删改查、运算符重载、求和、均值、最大值、最小值等处理。 本博客利用C#进行编程,新建了一个Vector类(向量),具备向量的常见运算操作和方法;

        程序+讲解文档下载:点击下载。

Step01:新建Vector类

        新建一个Vector类;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace XMU.DataBase
{public class Vector{}
}

注:

  • 命名空间中,之所以有“.DataBase”,是因为我在项目中新建了一个名为“DataBase”的文件夹,为了方便调用,此处可省略“.DataBase”。
  • 为了便于调用,将Vector类改为public形式。

 Step02:定义成员

        建立成员;Vector类需要一个容器“_data”存放数据;

public class Vector //<T>{/// <summary>///  成员:向量存储,///  不希望直接被外部访问,所以用protected/// </summary>protected double[] _data;}

Step03:定义属性

        建立属性;对于一个Vector数据,属性为Vector的长度;因此建立一个公开属性Length;

        /// <summary>/// 属性:获取Vector的长度(元素个数)/// </summary>public int Length => _data.Length;

Step04:向量的方法

        建立Vector类的方法; Vector方法有:构造方法Vector()、显示方法ToString()、Vector向量的增删改查功能、向量的运算方法;

Step041:向量构造

        建立构造函数Vector();建立一个Vector有多种方法,每种方法都需要单独写一个构造函数,Vector构造方法有3中,分别是空Vector、全0或全1、根据一串数建立Vector;具体如下:

Step0411:构造空向量

        建立一个空的Vector向量方法;        

        /// <summary>/// 方法:构造方法,构造一个空的Vector/// </summary>public Vector(){_data = new double[0];}

注:构造函数,不能写数据类型输出类型或则不输出void;

Step0412:构造全0或全1向量

        建立一个全0或全1的Vector向量方法;

        /// <summary>/// 方法:构造方法,构造一个全0或全1的Vector/// </summary>/// <param name="length">向量的长度</param>/// <param name="fillOne">可选,false(默认)表示全0的vector向量,/// true表示全1的Vector向量</param>public Vector(int length, bool fillOne = false){_data = new double[length];if (fillOne)                // 是否为全1的Vector向量{for(int i = 0; i < length; i++){_data[i] = 1;}}}

Step0413:根据数组构造向量

        根据一串数据,建立Vector向量方法;

        /// <summary>/// 方法:构造方法,根据一串double类型的数,建立Vector/// </summary>/// <param name="values">表示一串double类型的数据</param>public Vector(params double[] values){// 建立一个空的向量(),用于存放数据_data = new double[values.Length];//for(int i = 0; i < values.Length; i++)//{//    _data[i] = values[i];//}Array.Copy(values, _data, values.Length);}

Step042:显示方法重写

        建立显示方法ToString();由于默认的显示方式是返回类名,因此需要重写override;

        /// <summary>/// 方法:显示Vector元素/// </summary>/// <returns></returns>public override string ToString(){//return base.ToString();  // 默认返回类型,需重写return "[" + string.Join(", ", _data) + "]";}

注:sting.Join() 的功能是以指定的分隔符,以字符串的形式串联起来;

        当补全显示方法时,可以验证前面的构造方法是是否正确,因此可以在主函数Program.cs 中验证(下文的的验证代码,都是写在这个文件main中);

            // 验证 Vector的几种构造方法// 第一种方法:构造空的VectorVector v1 = new Vector();Console.WriteLine("空的Vector构造:" + v1);// 第二种方法:构造全0或全1的Vector向量Vector v21 = new Vector(5);Console.WriteLine("全0的Vector构造:" + v21);Vector v2 = new Vector(5, true);Console.WriteLine("全1的Vector构造:" + v2);// 第三种构造方法:根据一串数,构造VectorVector v3 = new Vector(1, 2, 3, 4);Console.WriteLine("根据一串数构造Vector:" + v3);

 Step043:增删改查

        建立Vector的增删改查方法;具体如下:

Step0431:查询元素

        Vector向量元素查询与设置(修改);根据提供的索引,查询get、设置(修改)set 向量Vector对应位置的元素;

        /// <summary>/// 方法:查询或修改设置index对应位置的元素/// </summary>/// <param name="index"></param>/// <returns></returns>public double this[int index]{get => _data[index];                // 查询set => _data[index] = value;        // 设置(修改)}

        验证Vector的查询和修改方法;

            // 查询index位置处的元素Console.WriteLine("该位置处的元素为" + v3[2]);// 设置修改index位置处的元素v3[2] = 0;Console.WriteLine("该位置处的元素为" + v3[2]);

        结果:

该位置处的元素为3

该位置处的元素为0

Step0432:删除元素

        Vector向量元素增加方法;根据提供的一个向量,在指定位置(可选)出增加某个元素或某串元素;

        /// <summary>/// 方法:在index对应(this)位置前插入向量v1/// </summary>/// <param name="v1">需要插入的向量</param>/// <param name="index">插入的位置/// (索引前,例如index=0,表示在第0个索引位置前插入向量v1)/// index =-1 或则大于this.Length的长度都表示在向量末尾插入,反之,则出错</param>/// <returns></returns>public Vector Insert(Vector v1, int index = -1){// 去除 index索引 index<-1 的情况if (index < -1){throw new Exception("index输入错误,请输入不小于-1的int值");}// 将index=1 或大于 index>Length变化为index=Lengthif (index > Length || index == -1){index = Length;}// 新建一个长度为Length + v1.Length的空向量(容器)Vector v = new Vector(Length + v1.Length);// 将源数据(被插入的数据)_data,复制到v向量容器中,复制元素的个数为indexArray.Copy(_data, v._data, index);// 将源数据(插入的数据)v1._data,复制到v向量容器中,复制元素的个数为v1.LengthArray.Copy(v1._data, 0, v._data, index, v1.Length);// 将源数据(被插入的数据)_data,从 index索引以后的元素,// 复制到v向量容器中,复制元素的个数为Length - indexArray.Copy(_data, index, v._data, index + v1.Length, Length - index);return v;}

        验证:

            // 插入(末尾增加,就相当于在末尾插入)v3[2] = 3;Vector v4 = new Vector(5, 6);Console.WriteLine("被插入数据:" + v3);Console.WriteLine("插入的数据:" + v4);Console.WriteLine("插入后的结果:" + v3.Insert(v4, 3));

        结果:

被插入数据:[1, 2, 3, 4]

插入的数据:[5, 6]

插入后的结果:[1, 2, 3, 5, 6, 4]

 注释:这个入参(插入的数据)必须是Vector,若是其他数据(比如说数组),可以用步骤Step0413的方法,将一串数据,构造成Vector,在执行插入;

Console.WriteLine("插入后的结果:" + v3.Insert(new Vector(5, 6), 3));

Step0433:删除指定长度连续的字符串

        Vector向量元素删除方法;根据提供的索引范围(开始索引starIndex和删除元素的长度delLength,delLength可选,默认delLength= 1),在指定位置(可选)出删除delLength个元素;

        /// <summary>/// 方法:根据指定的索引位置和删除元素的个数,删除向量元素/// </summary>/// <param name="startIndex">开始删除的位置索引</param>/// <param name="delLenth">删除元素的长度(个数)</param>/// <returns></returns>public Vector DeleteLen(int startIndex, int delLenth = 1){if (startIndex < 0 || startIndex > Length - 1 || delLenth < 1){throw new Exception("删除方法的输入参数有误");}// 防止删除的长度过长if (startIndex + delLenth > Length){delLenth = Length - startIndex;}// 新建 空向量(容器)Vector v = new Vector( Length - delLenth);// 存储第一段;Array.Copy(_data, v._data, startIndex);// 存储第二段Array.Copy(_data, startIndex + delLenth, v._data, startIndex, Length - startIndex - delLenth);return v;}

        验证:

            // 删除,将v3中第3位和第四位删除掉,startIndex = 2,delLength = 2;Vector v5 = v3.Insert(v4, 2);Console.WriteLine("向量:" + v5);Console.WriteLine("删除部分元素后的向量:" + v5.DeleteLen(2, 2));

Step0434:根据索引删除字符串

        Vector向量元素删除方法(第二种方法);根据一些列索引位置,删除元素;(待补充)

Step0435:查询元素对应的索引

        根据元素查询元素在向量Vector中对应的所有索引位置;

        /// <summary>/// 方法:根据元素的值,查询该值对应的所有的索引/// </summary>/// <param name="value"></param>/// <returns>返回Vector元素为value的所有索引,是int[]类型数据</returns>public int[] QueryElementIndex(double value){// 首先不要判断向量中有多少个元素valueint count = 0;for (int i = 0; i < Length; i++){if (_data[i] == value){count++;}}// 在根据count,创建适合大小为count的容器indexContainerint[] indexContainer = new int[count];  int index = 0;      // 容器indexContainer的索引for (int i = 0; i < Length; i++){if (_data[i] == value){// 存放符合条件的索引值到容器indexContainer中indexContainer[index] = i;index++;}}return indexContainer;}

        验证:

            // 查询向量中Vector元素为value的所有索引Vector v6 = new Vector(3,4,3,2,3,1,2,3);int[] indexContainer = v6.QueryElementIndex(3);Console.WriteLine(string.Join(",", indexContainer));

        结果:

0,2,4,7

Step0436:在指定位置前插入向量

        在一个向量指定位置上,插入一个新的向量

        /// <summary>/// 方法:在index对应(this)位置前插入向量v1/// </summary>/// <param name="v1">需要插入的向量</param>/// <param name="index">插入的位置/// (索引前,例如index=0,表示在第0个索引位置前插入向量v1)/// index =-1 或则大于this.Length的长度都表示在向量末尾插入,反之,则出错</param>/// <returns></returns>public Vector Insert(Vector v1, int index = -1){// 去除 index索引 index<-1 的情况if (index < -1){throw new Exception("index输入错误,请输入不小于-1的int值");}// 将index=1 或大于 index>Length变化为index=Lengthif (index > Length || index == -1){index = Length;}// 新建一个长度为Length + v1.Length的空向量(容器)Vector v = new Vector(Length + v1.Length);// 将源数据(被插入的数据)_data,复制到v向量容器中,复制元素的个数为indexArray.Copy(_data, v._data, index);// 将源数据(插入的数据)v1._data,复制到v向量容器中,复制元素的个数为v1.LengthArray.Copy(v1._data, 0, v._data, index, v1.Length);// 将源数据(被插入的数据)_data,从 index索引以后的元素,// 复制到v向量容器中,复制元素的个数为Length - indexArray.Copy(_data, index, v._data, index + v1.Length, Length - index);return v;}

        验证:

            // 插入(末尾增加,就相当于在末尾插入)Console.WriteLine("================");v3[2] = 3;Vector v4 = new Vector(5, 6);Console.WriteLine("被插入数据:" + v3);Console.WriteLine("插入的数据:" + v4);Console.WriteLine("插入后的结果:" + v3.Insert(v4, 3));Console.WriteLine("插入后的结果:" + v3.Insert(new Vector(5, 6), 3));

        结果:

================

被插入数据:[1, 2, 3, 4]

插入的数据:[5, 6]

插入后的结果:[1, 2, 3, 5, 6, 4]

插入后的结果:[1, 2, 3, 5, 6, 4]

Step044:运算符重载

        Vector向量符重载;Vector向量常见的运算符有向量之间相加、减,数乘向量、对应元素相乘、向量的数量积a·b=|a|·|b|·cos〈a,b〉、向量的向量积a×b

Step0441:“+”正号重载

        默认的正号拷贝的方法,不是深度拷贝,一个修改,也会影响另一个,因此需要重写修改“+”正号的操作运算符方法;

        public Vector Copy(){// 返回的是一个元素完全相同的新变量return new Vector(_data);}/// <summary>/// 方法:向量的正号拷贝,返回当前向量的深度拷贝的向量/// </summary>/// <param name="v1">需要拷贝的向量</param>/// <returns>返回当前向量的深度拷贝的向量</returns>public static Vector operator +(Vector v1)      // 运算符重载必须加static{return v1.Copy();}

      注:Copy()方法的作用是用来深度拷贝的,直接赋值,会导致它俩的地址一样

        验证:

            // 向量的拷贝,旧方法拷贝不是深度拷贝,修改其中的一个也会修改另一个,因为他俩地址一样Vector v7 = v6;v7[0] = 0;Console.WriteLine(v6 + "旧方法拷贝修改" + v7);// 新的拷贝方法(正号-深度拷贝),深度拷贝;Vector v8 = +v6;v8[0] = -1;Console.WriteLine(v6 + "新方法拷贝修改" + v8);

        结果:

[0, 4, 3, 2, 3, 1, 2, 3]旧方法拷贝修改[0, 4, 3, 2, 3, 1, 2, 3]

[0, 4, 3, 2, 3, 1, 2, 3]新方法拷贝修改[-1, 4, 3, 2, 3, 1, 2, 3]

Step0442:“-”负号重载

        默认的负号拷贝的方法,不是深度拷贝,一个修改,也会影响另一个,因此需要重写修改“-”正号的操作运算符方法;

        /// <summary>/// 方法:向量的负号拷贝,返回当前向量的相反向量/// </summary>/// <param name="v1">需要拷贝的向量</param>/// <returns>返回当前向量的相反向量</returns>public static Vector operator -(Vector v1)      // 运算符重载必须加static{Vector v2 = new Vector(v1.Length);for(int i = 0; i < v1.Length; i++){v2[i] = -v1[i];}return v2;}

        验证:

            // 负号Vector v9 = -v8;Console.WriteLine(v8 + "相反向量" + v9);

        结果:

[-1, 4, 3, 2, 3, 1, 2, 3]相反向量[1, -4, -3, -2, -3, -1, -2, -3]

Step0443:“+”向量相加

        向量之间“+”加法不同于数字方面的加法,它是对应索引的元素之间进行算术相加,因此需要重载;

        /// <summary>/// 方法:+加号运算符重载/// </summary>/// <param name="v1">第1个向量</param>/// <param name="v2">第2个向量</param>/// <returns>相加后的向量</returns>public static Vector operator +(Vector v1, Vector v2)      // 运算符重载必须加static{Vector v = new Vector(v1.Length);if(v1.Length != v2.Length){throw new Exception("向量长度不一样,不能相加");}for (int i = 0; i < v1.Length; i++){v[i] = v2[i] + v1[i];}return v;}

        验证:

            // 向量相加Console.WriteLine(v8 + v9);

        结果:

[0, 0, 0, 0, 0, 0, 0, 0]

Step0444:“-”向量相减

        向量之间“-”减法不同于数字方面的相减,它是对应索引的元素之间进行算术相减,因此需要重载;

        /// <summary>/// 方法:+加号运算符重载/// </summary>/// <param name="v1">向量1</param>/// <param name="v2">向量1</param>/// <returns>向量1+向量2 的结果,返回一个Vcetor向量</returns>public static Vector operator -(Vector v1, Vector v2)      // 运算符重载必须加static{Vector v = new Vector(v1.Length);if (v1.Length != v2.Length){throw new Exception("向量长度不一样,不能相加");}for (int i = 0; i < v1.Length; i++){v[i] = v2[i] - v1[i];}return v;//return v1 + (-v2);}

        注:由于已有“+”加法和“-”负号重载符,因此可以将向量A-向量B看成A + (-B),即A向量+B向量的相反向量,因此代码可以改为

        /// <summary>/// 方法:+加号运算符重载/// </summary>/// <param name="v1"></param>/// <param name="v2"></param>/// <returns></returns>public static Vector operator -(Vector v1, Vector v2)      // 运算符重载必须加static{return v1 + (-v2);}

        验证:

            // 向量相加Console.WriteLine("第一个向量" + v9 + "第2个向量" + v10);Console.WriteLine("向量相加" + (v9 + v10));// 向量相减Console.Write("向量相减" + (v9 - v10));

        注;向量除了相加减,还有一些特殊要求,比如说向量+/-一个数;因此,对于加法、减法还需要在添加一个运算符重载,比如说向量A+5,可以看出向量A加上5*全1的向量,因此整个会在后面补充;

Step0445:“*”向量相乘

        向量相乘方法不同于数字相乘,它是对应位置的元素进行相乘(向量长度必须一致);

        /// <summary>/// 方法:*向量乘法运算符重载/// </summary>/// <param name="v1">向量1</param>/// <param name="v2">向量2</param>/// <returns>向量1×向量2 的结果,返回一个Vcetor向量</returns>public static Vector operator *(Vector v1, Vector v2){Vector v = new Vector(v1.Length);if (v1.Length != v2.Length){throw new Exception("向量长度不一样,不能相乘");}for (int i = 0; i < v1.Length; i++){v[i] = v2[i] * v1[i];}return v;}

        验证:

            // 向量相乘Console.WriteLine("向量相乘:" + (v9 * v10));

Step0446:Dot向量点乘

        向量点乘的运算方法为对应元素相乘,然后在总的相加,成一个数,比如所可以计算A点的距离,及x2+y2+z2=R2;这个就相当于计算A向量与A向量相乘,然后计算元素之和;因此在此之前,需要添加一个求向量和的算法;

        因此,需要在写Dot方法之前,先写一个Sum求和方法;

        /// <summary>/// 方法:向量求和/// </summary>/// <returns>返回向量元素之和</returns>public double Sum(){double sum = 0;for(int i = 0; i < Length; i++){sum += _data[i];}return sum;}

        验证:

            // 向量求和Console.WriteLine("向量求和:" + v9.Sum());

        Dot方法代码如下:

        /// <summary>/// 方法:向量点乘/// </summary>/// <param name="v1"></param>/// <returns></returns>public double Dot(Vector v1){if(Length != v1.Length){throw new Exception("长度不一样,不能点乘");}double sum = 0;for(int i = 0; i < Length; i++){sum = sum + this._data[i] * v1[i];}return sum;}

        也可以直接写成:

        /// 方法:向量点乘/// </summary>/// <param name="v1"></param>/// <returns></returns>public double Dot(Vector v1){// 调用重写*乘号算法Vector v = this * v1;// 调用求和Sum方法return v.Sum();}

        验证:

            // 向量点乘Console.WriteLine("向量点乘:" + v9.Dot(v10));

        结果:

向量点乘:-83

Step044:向量元素常见处理方法

        向量元素的常见处理算法有:求和、均值、最大、最小值等等;

Step0441:Sum求和

        向量求和是将所有元素进行求和,具体参考“Step0445:Dot向量点乘”;

        /// <summary>/// 方法:向量求和/// </summary>/// <returns>返回向量元素之和</returns>public double Sum(){double sum = 0;for(int i = 0; i < Length; i++){sum += _data[i];}return sum;}

Step0442:Mean求均值

        向量求解元素之间的均值是在求和的基础上,在除以元素的个数,因此可以写成:

        /// <summary>/// 方法:求解向量的均值/// </summary>/// <returns></returns>public Double Mean(){if(Length == 0){throw new Exception("向量元素个数为0");}// 调用求和double sum = this.Sum();double mean = sum / Length;return mean;}

        验证:

            // 向量求均值Console.WriteLine("向量均值:" + v9.Mean());

        结果:

向量均值:-2.125

Step0443:Max求最大值

        通过循环对比,找出最大值,代码如下:

        /// <summary>/// 方法:求向量的最大值/// </summary>/// <returns>返回向量的最大值</returns>public double Max(){if (Length == 0){throw new Exception("向量元素个数为0");}double maxValue = _data[0];for(int i = 0; i < Length; i++){if(maxValue < _data[i]){maxValue = _data[i];}}return maxValue;}

        验证:

            // 向量的最大值Console.WriteLine("向量最大值:" + v9.Max());

        结果:

向量最大值:1

Step0444:Min求最小值

        通过循环对比,找出最小值,代码如下:

        /// <summary>/// 方法:求向量的最小值/// </summary>/// <returns>返回向量的最小值</returns>public double Min(){if(Length == 0){throw new Exception("向量元素个数为0");}double minValue = _data[0];for (int i = 0; i < Length; i++){if (minValue > _data[i]){minValue = _data[i];}}return minValue;}

        验证:

            // 向量的最小值Console.WriteLine("向量最小值:" + v9.Min());

Step045:向量常见的判断方法

        判断方法有:是否全部为0,向量是否相等;

Step0451:IsZero判断是否为全0向量

        循环判断每个元素是否等于0,若存在不等于0情况,则返回false,否则返回true;

        /// <summary>/// 判断是否为全0向量/// </summary>/// <returns>全0返回true,反之,返回false</returns>public bool IsZero(){for(int i = 0; i < Length; i++){if(_data[i] != 0){return false;}}return true;}

        验证:

            // 判断是否为全0向量Vector v11 = new Vector(5);Console.WriteLine("判断是否为全0向量" + v11.IsZero());v11[2] = 5;Console.WriteLine("判断是否为全0向量" + v11.IsZero());

Step0452:IsOne判断是否为全1向量

        循环判断每个元素是否等于1,若存在不等于1情况,则返回false,否则返回true;

        /// <summary>/// 方法:判断是否为全1向量/// </summary>/// <returns>全1返回true,反之,返回false</returns>public bool IsOne(){for (int i = 0; i < Length; i++){if (_data[i] != 1){return false;}}return true;}

        验证:

           // 判断是否为全1向量Vector v12 = new Vector(5, true);Console.WriteLine("判断是否为全1向量" + v12.IsOne());v12[2] = 0;Console.WriteLine("判断是否为全1向量" + v12.IsOne());

        结果:

判断是否为全1向量True

判断是否为全1向量False

Step0453:Equal判断向量是否相等

        判断两个向量是都相等,可以循环判断每个元素差是否为0;也可以转换一下思路,通过判断两个向量的差,来判断两个向量是否相等;

        /// <summary>/// 判断两个向量是否相等/// </summary>/// <param name="v1">需要被判断的向量</param>/// <returns>相等返回true,反之则为false</returns>public bool Equal(Vector v1){if(Length != v1.Length){return false;}return (this - v1).IsZero();}

        验证:

            // 判断两个向量是否相等Vector v13 = new Vector(1, 2, 3, 4, 5, 6, 7, 8);Vector v14 = new Vector(0, 2, 3, 4, 5, 6, 7, 8);Console.WriteLine("判断向量是否相等" + v13.Equal(v13));Console.WriteLine("判断向量是否相等" + v13.Equal(v14));

        结果:

判断向量是否相等True

判断向量是否相等False

Step046:其他向量操作方法

        除此之外,向量还有截取、拼接等算法

Step0461:向量的拼接

Step0462:向量的截取

完整的代码请到我的博客中下载

https://download.csdn.net/download/weixin_41649786/87674833icon-default.png?t=N2N8https://download.csdn.net/download/weixin_41649786/87674833

 不足之处,敬请斧正!

路漫漫其修远兮,吾将上下而求索!

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

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

相关文章

【深度学习】rnn是什么?循环神经网络是什么?RNN前向传播。

文章目录循环神经网络1.循环神经网络原理2.使用Numpy实现RNN层的前向传播3.RNN存在的问题4.小结循环神经网络 通常卷积神经网络 适合处理图像问题&#xff0c;然而通常适合处理自然语言的网络是循环神经网络。rnn是所有基本网络&#xff0c;就像cnn 是很多复杂网络的基本原型。…

leedcode刷题(3)

各位朋友们大家好&#xff0c;今天是我leedcode刷题系列的第三篇&#xff0c;废话不多说&#xff0c;直接进入主题。 文章目录分割链表题目要求用例输入提示做题思路c语言代码实现Java代码实现相交链表题目要求用例输入提示做题思路c语言实现代码Java代码实现分割链表 leedcod…

《 LeetCode 热题 HOT 100》——无重复字符的最长子串

本期给大家带来的是 LeetCode 热题 HOT 100 第三题关于 无重复字符的最长子串 的讲解。首先&#xff0c;我们还是先从题目入手进行分析思考&#xff01;&#xff01;&#xff01; 题目如下 &#xff1a;&#x1f447; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符…

改进蚁狮优化算法

目录 ​1 主要内容 2 部分程序 3 程序结果 4 程序链接 ​1 主要内容 该程序方法复现《改进蚁狮算法的无线传感器网络覆盖优化》两种改进算法模型&#xff0c;即原始ALO算法的基础上添加了两种改进策略&#xff1a; - 改进1&#xff1a;将原先的间断性边界收缩因子变为连…

【Android开发经验】-- 如何实现RecyclerView子项的点击事件?

目录 实例 实现思路 实现代码 进一步需求&#xff1a;数据库存储 实例 假设现在需要完成一个以下需求的任务&#xff0c;下面两个图左边是点击前未完成&#xff0c;右边是点击后已完成&#xff0c;如何实现点击图标切换另一个图标&#xff1f;&#xff08;矩形框中的内容是…

医药产品经理渠道资源获取的方法有哪些?

收集渠道信息是医药产品经理非常重要的工作之一&#xff0c;以下是一些可行的方法&#xff1a; 与销售人员和客户服务团队交流 销售人员和客户服务团队是企业与患者、医生和医院进行联系的主要渠道。他们可以提供很多有关市场需求和竞争对手情况的信息。产品经理可以通过与销…

机械臂动力学参数辨识学习笔记

1、为什么需要动力学参数辨识&#xff1f; 图1 电机三环控制图 通常情况下&#xff0c;标准的工业控制器通过机械臂内部的PID进行调节控制机械臂的运动&#xff0c;即用PID输出力矩&#xff0c;涉及到经典的图一所示的电机三环控制&#xff08;位置环、速度环、电流环&#xff…

用机器学习sklearn+opencv-python过古诗文网4位数字+字母混合验证码

目录 获取验证码图片 用opencv-python处理图片 制作训练数据集 训练模型 识别验证码 编写古诗文网的登录爬虫代码 总结与提高 源码下载 在本节我们将使用sklearn和opencv-python这两个库过掉古诗文网的4位数字字母混合验证码&#xff0c;验证码风格如下所示。 验证码获…

DM的学习心得和知识总结(三)|DM数据库DBMS_WORKLOAD_REPOSITORY 包及其性能分析工具AWR

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、达梦数据库产品及解决方案&#xff0c;点击前往 2、达梦技术文档&#xff0c;点击前往 3、武汉达梦数据库有限公司 官网首页&#xff0c;点击前往 1、本文内容全部…

【软考备战·希赛网每日一练】2023年4月10日

文章目录一、今日成绩二、错题总结第一题第二题三、知识查缺题目及解析来源&#xff1a;2023年04月10日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 本题属于专业英语&#xff0c;大体了解意思即可。 题目大意&#xff1a; 第二题 解析&#xff1a…

ORACLE创建表空间、用户、授权和Navicat创建序列和触发器及解决ORA-00942、ORA-01219错误

问题描述&#xff1a;因为每次Oracle删除数据库的时候磁盘文件还没删除&#xff0c;然后自己手动停止Oracle&#xff0c;删除磁盘里的.DBF文件导致数据库重启后无法连接。 cmd sqlplus sys as sysdba执行alter database open;查看你报错的数据文件&#xff08;就是你停止Orac…

ESP32 分区表

ESP32 分区表 1. 分区表概述 ESP32 针对 flash 进行划分&#xff0c;划分为不同的区域用作不同的功能&#xff0c;并在flash的 0x8000 位置处烧写了一张分区表用来描述分区信息。 分区表可以根据自己的需要进行配置&#xff0c;每一个分区都有其特定的作用&#xff0c;可根据…

Jetpack Compose之选择器

选择器是啥 选择器主要是指Checkbox复选框&#xff0c;单选开关Switch,滑杆组件Slider等用于提供给用户选择一些值和程序交互的组件&#xff0c;比如像复选框Checkbox&#xff0c;可以让用户选择一个或者多个选项&#xff0c;它可以将一个选项打开或者是关闭&#xff0c;通常用…

【JavaEE】ConcurrentHashMap与Hashtable有什么区别?

博主简介&#xff1a;努力的打工人一枚博主主页&#xff1a;xyk:所属专栏: JavaEE初阶Hashtable、ConcurrentHashMap是使用频率较高的数据结构&#xff0c;它们都是以key-value的形式来存储数据&#xff0c;且都实现了Map接口&#xff0c;日常开发中很多人对其二者之间的区别并…

STM32F4_窗口看门狗精讲(WWDG)

目录 1. 窗口看门狗WWDG简介 2. 窗口看门狗和独立看门狗的区别 3. WWDG主要特性 4. WWDG功能 4.1 窗口看门狗框图(重要) 4.2 看门狗超时计算 5. WWDG寄存器 5.1 控制寄存器 WWDG_CR 5.2 配置寄存器 WWDG_CFR 5.3 状态寄存器 WWDG_SR 6 库函数配置窗口看门狗(采用中断…

Mybatis(五)------Mybatis执行Mapper接口的方法流程

前面几篇文章我们介绍了JDBC、Mybatis的工具类等&#xff0c;下面我们开始对于mybatis的各个机制开始解析。 前面我们知道&#xff0c;mybatis对excutor进行封装成sqlsession提供给开发人员进行数据库的增删改查&#xff0c;我们先从Mybatis最顶层的API入手。 SQLSession的创…

爬虫日常练习-艾图网单页面图片爬取

文章目录爬虫练习分析网站代码设计下载图片完整代码爬虫练习 hello&#xff0c;大家好。好久不见了&#xff0c;无聊的网友今天开始更新关于爬虫的一些日常练习。每次学习完一个新的知识后没有多的案例给自己练习真的很不舒服&#xff0c;希望该系列文章能够让刚刚开始学习爬虫…

常见面试题之Redis篇

1.1.Redis与Memcache的区别&#xff1f; redis支持更丰富的数据类型&#xff08;支持更复杂的应用场景&#xff09;&#xff1a;Redis不仅仅支持简单的k/v类型的数据&#xff0c;同时还提供list&#xff0c;set&#xff0c;zset&#xff0c;hash等数据结构的存储。memcache支持…

腾讯云CVM云服务器评测:标准型S5、S6

一、腾讯云CVM云服务器评测&#xff1a;标准型S5、S6 腾讯云服务器CVM标准型S5是次新一代云服务器规格&#xff0c;标准型S6是最新一代的云服务器&#xff0c;S6实例的CPU处理器主频性能要高于S5实例&#xff0c;同CPU内存配置下的标准型S6实例要比S5实例性能更好一些&#xf…

【C语言】for 关键字

&#x1f6a9;WRITE IN FRONT&#x1f6a9; &#x1f50e;介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四"&#x1f50e;&#x1f3c5;荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星TOP100…