一、简介
上一篇文档中描述了如何写一个 Vector 类,然而所写的 Vector 类仅限于
double 型,无法满足实际工作需求。因此在上一篇文档基础上,撰写本文,介绍
如何书写一个泛型 Vector,可以应用于 int、double、float 等 C#数值型的 Vector。
本文所描述的 Vector<T>是一个泛型,具有不同数值类型 Vector 向量构造、
新增、删除、查询、更改、深度复制、显示元素值、vector 运算、排序等功能。
整体代码如下所示。
注:本文中 Vector 表示向量的类,vetcor 表示具体的向量。
二、方法
2.1 建立 Vector<T>类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace XMU//.Base
{
/// <summary>
/// 类:向量类,存放向量的定义,以及向量的一些操作和算法;
/// </summary>
internal class Vector<T> where T : struct
{
}
}
注:<T> where T : struct 中,T 表示泛型,是一个占位符,可以表示 C#
任何数据类型,包括自定义的类型,where T : struct 表示泛型的约束,约束泛型
的类型为 struct,及数值型。
2.2 Vector 成员
Vector 成员只包含一个存储数据的 T[]型_data 成员字段,代码如下:
/// <summary>
/// Vector成员定义:定义数据成员
/// </summary>
private T[] _data;
2.3 Vector 属性
Vector 只包含一个记录 Vector 向量长度 Length 的属性,具体代码如下:
/// <summary>
/// Vector属性定义:定义向量的长度属性
/// </summary>
public int Length => _data.Length;
2.4 Vector 方法
本文撰写的 Vector 类方法主要分为两种,一种是向量 Vector<T>的构造;一
种是 vector 元素之间的操作,具体包括 vector 的增、删、改、查、复制、求和、
求最大值、求最小值、求均值、排序;最后一种是 vector 加减乘除的运算。
2.4.1 构造函数
本文所写的 Vector 构造函数有三种类型:构造空的 vector、根据指定长度构
造全 0 或全 1 vector、根据数组构造 vector,具体代码如下:
#region 构造函数/方法
/// <summary>
/// Vector构造函数:空Vector构造
/// </summary>
public Vector()
{
_data = new T[0];
}
/// <summary>
/// Vectot构造:根据长度来构造全0或全1Vector,默认为全 0 Vector
/// </summary>
/// <param name="length">Vector长度</param>
/// <param name="fillOne">可选:布尔值,是否为全1Vector,默认为false,表示全
0true表示全 1 Vector;</param>
public Vector(int length, bool fillOne = false)
{
_data = new T[length];
if (fillOne)
{
for (int i = 0; i < length; i++)
{
_data[i] = (dynamic)1;
}
}
}
/// <summary>
/// Vector构造:根据T类型数组元素,构造(复制)一个Vector
/// </summary>
/// <param name="values">T 类型的数组,至少2个元素的数组</param>
public Vector(params T[] values)
{
// 新建一个等大的容器,用于存放数据
_data = new T[values.Length];
// 将值写入到Vector中
Array.Copy(values, _data, values.Length);
}
#endregion
为了便于显示 vector 元素,验证代码正确性,建议优先重写 Tostring 方法,
具体代码如下:
/// <summary>
/// Vector方法:重写Vector显示方法
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "[" + string.Join(", ", _data) + "]";
}
2.4.2 Vector 元素操作方法
Append
Append 方法可以在 vector 新增一个同类型的数或另一个 vector,具体代码
如下(无返回值):
/// <summary>
/// Vector 新增元素
/// </summary>
/// <param name="values">需要新增的T数组values</param>
/// <returns></returns>
public void Append(params T[] values)
{
Vector<T> v = new Vector<T>(Length + values.Length);
// 元素写入
Array.Copy(_data, v._data, Length);
// 插入元素写入
Array.Copy(values, 0, v._data, Length, values.Length);
_data = v._data;
}
/// <summary>
/// Vector 新增元素
/// </summary>
/// <param name="v1">需要新增的Vextor向量</param>
/// <returns></returns>
public void Append(Vector<T> v1)
{
Vector<T> v = new Vector<T>(Length + v1.Length);
// 元素写入
Array.Copy(_data, v._data, Length);
// 插入的元素写入
Array.Copy(v1._data, 0, v._data, Length, v1._data.Length);
_data = v._data;
}
this[]
this[] 可以根据中括号内的索引值,查询对应位置的元素,具体代码如下:
/// <summary>
/// Vectot 元素查询和更改
/// </summary>
/// <param name="index">查询或更改的位置(索引)</param>
/// <returns></returns>
public T this[int index]
{
get => _data[index]; // 查询
set => _data[index] = value; // 更改元素值
}
Insert
Insert 方法可以在 vector 中任何位置插入同类型的数或 vector 向量,若不指
定位置,则在末尾插入,具体代码如下(无返回值):
/// <summary>
/// Vextor Vector1中插入另一个Vector2;
/// 如果是数组,需将数组通过Vector构造函数构造成Vector类型数据。
/// </summary>
/// <param name="v1">需要插入的Vector</param>
/// <param name="indexInsert">可选:插入的位置,
/// 默认indexInsert=-1,表示在末尾,indexInsert 必须大于-1</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public Vector<T> Insert(Vector<T> v1, int indexInsert = -1)
{
if (indexInsert < -1)
{