C#,实用代码——运算符重载、泛型与加强版的数组Array

发布时间:2024年01月20日

自认为这是一篇特别适合稍微有点基础的C#初学者仔细阅读的入门教程级别的文章。

再多的文字描述,都不如一段代码更有参考价值。

1、泛型(Generic)

泛型(Generic)?,可以理解为程序模板。泛型代码中,先用<T>代替未来真正的数据类型。因而,泛型允许您编写一个可以适应于多种数据类型的类(属性及其方法)。当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型。

Generic, which can be understood as a program template. In generic code, use<T>to replace the real data type in the future. Thus, generics allow you to write a class (properties and their methods) that can be adapted to multiple data types. When the compiler encounters the constructor of a class or function call of a method, it generates code to handle the specified data type.

泛型是C#2.0推出的新语法,不是语法糖,而是2.0由框架升级提供的功能。

我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但我们没有办法,只能分别写多个方法来处理不同的数据类型。这个时候,那么问题来了,有没有一种办法,用同一个方法来处理传入不同种类型参数的办法呢?泛型的出现就是专门来解决这个问题的。
?

泛型类型参数

在使用泛型方法之前,我们先来了解下有关于泛型的一些知识。

在泛型类型或方法定义中,类型参数是在其实例化泛型类型的一个变量时,客户端指定的特定类型的占位符。 泛型类( GenericList<T>)无法按原样使用,因为它不是真正的类型;它更像是类型的蓝图。 若要使用 GenericList<T>,客户端代码必须通过指定尖括号内的类型参数来声明并实例化构造类型。 此特定类的类型参数可以是编译器可识别的任何类型。

泛型约束

定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的几种类型施加限制。 如果客户端代码尝试使用约束所不允许的类型来实例化类,则会产生编译时错误。 这些限制称为约束。 通过使用 where 上下文关键字指定约束。?
?

2、C#运算符重载(operator overload)

C#运算符重载(operator overload),可以理解为运算符的一种拓展技能。使得运算符不仅用于数值之间的加减乘除(或更多),也可以用于其他类型。比如数组array、矩阵matrix、字符串或更多数据类型与集合的类似运算。运算符重载使得代码编写、阅读都更加清晰,能更好地体现编程思路。故,运算符重载是工业软件编程中一种极为常用的、无法缺失的重要方法。对于科学计算的程序而言,没有运算符重载更是难以想象。

C # operator overload can be understood as an extension skill of operators. This allows operators to be used not only for addition, subtraction, multiplication and division (or more) between numeric values, but also for other types. Such as array, matrix, string, or similar operations of more data types and sets. Operator overloading makes code writing and reading clearer, and better reflects programming ideas. Therefore, operator overloading is a very common and indispensable method in industrial software programming. For scientific computing programs, it is hard to imagine without operator overloading.

3、加强版的数组Array源程序

源代码:

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
	/// <summary>
	/// 加强版(泛型)数组
	/// 泛型是把双刃剑!
	/// 数组只是数组,
	/// 如果需要Insert,Delete等操作,建议使用List
	/// </summary>
	public class TArray<T> : IComparable<T>
	{
		/// <summary>
		/// 随机数发生器
		/// </summary>
		private Random rnd { get; set; } = new Random((int)DateTime.Now.Ticks);
		/// <summary>
		/// 保存数组数据
		/// </summary>
		private T[] Value { get; set; } = null;
		/// <summary>
		/// 保存数组的原始数据
		/// </summary>
		private T[] Original { get; set; } = null;
		/// <summary>
		/// 数组的长度
		/// </summary>
		private int Length { get; set; } = Int16.MaxValue;

		/// <summary>
		/// 默认构造函数
		/// </summary>
		public TArray()
		{
			Value = new T[Length];
			Original = new T[Length];
		}
		/// <summary>
		/// 指定长度的构造函数
		/// </summary>
		/// <param name="n"></param>
		public TArray(int n)
		{
			Length = n;
			Value = new T[Length];
			Original = new T[Length];
		}

		/// <summary>
		/// 以 x 为样板的构造函数(克隆)
		/// </summary>
		/// <param name="x"></param>
		public TArray(TArray<T> x)
		{
			Length = x.Length;
			Value = new T[Length];
			Original = new T[Length];
			for (int i = 0; i < Length; i++)
			{
				Value[i] = x[i];
				Original[i] = x[i];
			}
		}

		/// <summary>
		/// 以数组 v 为数据的构造函数
		/// </summary>
		/// <param name="v"></param>
		public TArray(T[] v)
		{
			Length = v.Length;
			Value = new T[Length];
			Original = new T[Length];
			for (int i = 0; i < Length; i++)
			{
				Value[i] = v[i];
				Original[i] = v[i];
			}
		}

		/// <summary>
		/// 以数组 x 为数据的赋值型构造函数
		/// </summary>
		/// <param name="x"></param>
		public static implicit operator TArray<T>(T[] x)
		{
			return new TArray<T>(x);
		}

		/// <summary>
		/// 以字符串为数据的赋值型构造函数
		/// TArray a = "1,2,3,4";
		/// </summary>
		/// <param name="s"></param>
		public static implicit operator TArray<T>(string s)
		{
			string[] sa = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			List<T> list = new List<T>();
			foreach (string sx in sa)
			{
				if (double.TryParse(sx.Trim(), out double x))
				{
					list.Add((T)(object)x);
				}
			}
			return new TArray<T>(list.ToArray());
		}

		/// <summary>
		/// 第一个数据
		/// </summary>
		public T Left
		{
			set
			{
				Value[0] = value;
			}
			get
			{
				return Value[0];
			}
		}
		/// <summary>
		/// 最后一个数据
		/// </summary>
		public T Right
		{
			set
			{
				Value[Length - 1] = value;
			}
			get
			{
				return Value[Length - 1];
			}
		}
		/// <summary>
		/// 最小数据
		/// </summary>
		public T Min
		{
			get
			{
				Array.Sort(Value);
				return Value[0];
			}
		}
		/// <summary>
		/// 最大数据
		/// </summary>
		public T Max
		{
			get
			{
				Array.Sort(Value);
				return Value[Length - 1];
			}
		}
		/// <summary>
		/// 提取数组数据
		/// </summary>
		public T[] GetValues
		{
			get { return Value; }
		}
		/// <summary>
		/// 提取指定下标数据
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		public T this[int index]
		{
			get { return Value[index]; }
			set { Value[index] = value; }
		}
		/// <summary>
		/// 加号重载(两个TArray相加)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static TArray<T> operator +(TArray<T> a, TArray<T> b)
		{
			if (a.Length != b.Length)
			{
				throw new Exception("");
			}
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				dynamic bv = b[i];
				c[i] = av + bv;
			}
			return c;
		}
		/// <summary>
		/// 加号重载(a的每个元素加上数值b)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static TArray<T> operator +(TArray<T> a, T b)
		{
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				c[i] = av + b;
			}
			return c;
		}
		/// <summary>
		/// 减号重载(两个TArray相减)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static TArray<T> operator -(TArray<T> a, TArray<T> b)
		{
			if (a.Length != b.Length)
			{
				throw new Exception("Not same array size!");
			}
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				dynamic bv = b[i];
				c[i] = av - bv;
			}
			return c;
		}
		/// <summary>
		/// 减号重载(a的每个元素减去数值b)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static TArray<T> operator -(TArray<T> a, T b)
		{
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				c[i] = av - b;
			}
			return c;
		}
		/// <summary>
		/// 乘号重载(两个TArray的元素一一对应相乘)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static TArray<T> operator *(TArray<T> a, TArray<T> b)
		{
			if (a.Length != b.Length)
			{
				throw new Exception("Not same array size!");
			}
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				dynamic bv = b[i];
				c[i] = av * bv;
			}
			return c;
		}
		/// <summary>
		/// 乘号重载(a的每个元素乘以数值b)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		public static TArray<T> operator *(TArray<T> a, T b)
		{
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				c[i] = av * b;
			}
			return c;
		}
		/// <summary>
		/// 除号重载(两个TArray的元素一一对应相除)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static TArray<T> operator /(TArray<T> a, TArray<T> b)
		{
			if (a.Length != b.Length)
			{
				throw new Exception("Not same array size!");
			}
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				if (Math.Abs((dynamic)b[i]) <= float.Epsilon)
				{
					throw new Exception("Divided by zero!");
				}
				dynamic av = a[i];
				dynamic bv = b[i];
				c[i] = av / bv;
			}
			return c;
		}
		/// <summary>
		/// 除号重载(a的每个元素除以数值b)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public static TArray<T> operator /(TArray<T> a, T b)
		{
			if (Math.Abs((dynamic)b) <= float.Epsilon)
			{
				throw new Exception("divided by zero");
			}
			TArray<T> c = new TArray<T>(a);
			for (int i = 0; i < a.Length; i++)
			{
				dynamic av = a[i];
				c[i] = av / b;
			}
			return c;
		}
		/// <summary>
		/// 排序(正序)
		/// </summary>
		public void Sort()
		{
			Array.Sort(Value);
		}
		/// <summary>
		/// 倒排序
		/// </summary>
		public void Reverse_Sort()
		{
			Array.Sort(Value, (a, b) => ((dynamic)b).CompareTo((dynamic)a));
		}
		/// <summary>
		/// 以数组数据为参数的方程式
		/// F(x) = a[0] + a[1] * x + a[2]* x^2 ...
		/// 计算 F(x) 函数值
		/// </summary>
		/// <param name="x"></param>
		/// <returns></returns>
		public double Compute_Equation(double x)
		{
			double v = (dynamic)Value[0];
			for (int i = 1; i < Length; i++)
			{
				v += (dynamic)Value[i] * Math.Pow(x, i);
			}
			return v;
		}

		/// <summary>
		/// 左转(一格)
		/// </summary>
		public void Left_Rotate()
		{
			T v = Left;
			for (int i = 0; i < (Length - 1); i++)
			{
				Value[i] = Value[i + 1];
			}
			Value[Length - 1] = v;
		}

		/// <summary>
		/// 右转(一格)
		/// </summary>
		public void Right_Rotate()
		{
			T v = Right;
			for (int i = (Length - 1); i > 0; i--)
			{
				Value[i] = Value[i - 1];
			}
			Value[0] = v;
		}

		/// <summary>
		/// 左转(前) num 个数(递归方式)
		/// input:  1,2,3,4,5,6,7
		/// output: 3,4,5,6,7,1,2
		/// </summary>
		/// <param name="num"></param>
		public void Left_Rotate(int num)
		{
			if (num == 0)
			{
				return;
			}
			num = (num % Length);
			Reverse(0, num - 1);
			Reverse(num, Length - 1);
			Reverse(0, Length - 1);
		}

		/// <summary>
		/// 下标 start 到 end 反转
		/// </summary>
		/// <param name="start"></param>
		/// <param name="end"></param>
		public void Reverse(int start, int end)
		{
			while (start < end)
			{
				dynamic temp = Value[start];
				Value[start] = Value[end];
				Value[end] = temp;
				start++;
				end--;
			}
		}

		/// <summary>
		/// 左转 num 个数(非递归方式)
		/// input:  1,2,3,4,5,6,7
		/// output: 3,4,5,6,7,1,2
		/// </summary>
		/// <param name="num"></param>
		public void Left_Rotate_No_Recurse(int num)
		{
			if (num == 0 || num == Length)
			{
				return;
			}
			num = num % Length;
			int i = num;
			int j = Length - num;
			while (i != j)
			{
				if (i < j)
				{
					Swap(num - i, num + j - i, i);
					j -= i;
				}
				else
				{
					Swap(num - i, num, j);
					i -= j;
				}
			}
			Swap(num - i, num, i);
		}

		/// <summary>
		/// 从指定下标开始左转d个数
		/// </summary>
		/// <param name="i">开始下标</param>
		/// <param name="d">左转数</param>
		/// <param name="n"></param>
		public void Left_Rotate_Recurse(int i, int d, int n)
		{
			if (d == 0 || d == n)
			{
				return;
			}
			if ((n - d) == d)
			{
				Swap(i, n - d + i, d);
				return;
			}
			if (d < (n - d))
			{
				Swap(i, n - d + i, d);
				Left_Rotate_Recurse(i, d, n - d);
			}
			else
			{
				Swap(i, d, n - d);
				Left_Rotate_Recurse(n - d + i, 2 * d - n, d);
			}
		}

		/// <summary>
		/// 将从下标fi开始的d个元素与从下标si开始的d个元素交换
		/// </summary>
		/// <param name="fi"></param>
		/// <param name="si"></param>
		/// <param name="d"></param>
		public void Swap(int fi, int si, int d)
		{
			for (int i = 0; i < d; i++)
			{
				dynamic temp = Value[fi + i];
				Value[fi + i] = Value[si + i];
				Value[si + i] = temp;
			}
		}

		/// <summary>
		/// 应用标准二分法快速查找数值
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public int Pivoted_Binary_Search(T key)
		{
			int pivot = Find_Pivot(0, Length - 1);
			if (pivot == -1)
			{
				return Binary_Search(0, Length - 1, key);
			}
			if ((dynamic)Value[pivot] == key)
			{
				return pivot;
			}
			if ((dynamic)Value[0] <= key)
			{
				return Binary_Search(0, pivot - 1, key);
			}
			return Binary_Search(pivot + 1, Length - 1, key);
		}

		/// <summary>
		/// 递归当时快速搜索转轴数()
		/// 转轴是第一个后面的数小于自己的数的下标
		/// 比如:数组 3, 4, 5, 6, 1, 2 的转轴下标是 3 (6的下标)
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		private int Find_Pivot(int low, int high)
		{
			if (high < low)
			{
				return -1;
			}
			if (high == low)
			{
				return low;
			}

			int mid = (low + high) / 2;
			if (mid < high && (dynamic)Value[mid] > (dynamic)Value[mid + 1])
			{
				return mid;
			}

			if (mid > low && (dynamic)Value[mid] < (dynamic)Value[mid - 1])
			{
				return (mid - 1);
			}

			if ((dynamic)Value[low] >= (dynamic)Value[mid])
			{
				return Find_Pivot(low, mid - 1);
			}

			return Find_Pivot(mid + 1, high);
		}

		/// <summary>
		/// 标准二分搜索算法
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <param name="key"></param>
		/// <returns></returns>
		private int Binary_Search(int low, int high, T key)
		{
			if (high < low)
			{
				return -1;
			}

			int mid = (low + high) / 2;
			if (key == (dynamic)Value[mid])
			{
				return mid;
			}
			if (key > (dynamic)Value[mid])
			{
				return Binary_Search((mid + 1), high, key);
			}
			return Binary_Search(low, (mid - 1), key);
		}

		/// <summary>
		/// 搜索数组中是否有“对和值(两个数的和)”等于 x
		/// </summary>
		/// <param name="x"></param>
		/// <returns></returns>
		public bool PairSum_Insort(T x)
		{
			int i;
			for (i = 0; i < Length - 1; i++)
			{
				if ((dynamic)Value[i] > (dynamic)Value[i + 1])
				{
					break;
				}
			}
			int l = (i + 1) % Length;
			int r = i;
			while (l != r)
			{
				if ((dynamic)Value[l] + (dynamic)Value[r] == x)
				{
					return true;
				}
				if ((dynamic)Value[l] + (dynamic)Value[r] < x)
				{
					l = (l + 1) % Length;
				}
				else
				{
					r = (Length + r - 1) % Length;
				}
			}
			return false;
		}

		/// <summary>
		/// 返回下标乘积最大数
		/// i*Value[i]
		/// </summary>
		/// <returns></returns>
		public int Maximum_Multipled_Sum()
		{
			int res = int.MinValue;
			for (int i = 0; i < Length; i++)
			{
				int curr_sum = 0;
				for (int j = 0; j < Length; j++)
				{
					int index = (i + j) % Length;
					curr_sum += j * (dynamic)Value[index];
				}
				res = Math.Max(res, curr_sum);
			}
			return res;
		}

		/// <summary>
		/// 二分法搜索 low ... high 之间的最小数
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		public T Min_Between(int low, int high)
		{
			if (high < low)
			{
				return Value[0];
			}
			if (high == low)
			{
				return Value[low];
			}
			int mid = low + (high - low) / 2;
			if (mid < high && (dynamic)Value[mid + 1] < (dynamic)Value[mid])
			{
				return Value[mid + 1];
			}
			if (mid > low && (dynamic)Value[mid] < (dynamic)Value[mid - 1])
			{
				return Value[mid];
			}
			if ((dynamic)Value[high] > (dynamic)Value[mid])
			{
				return Min_Between(low, mid - 1);
			}
			return Min_Between(mid + 1, high);
		}

		/// <summary>
		/// 计算(回转)数组的最大哈明距离
		/// </summary>
		/// <returns></returns>
		public int Maximum_Hamming_Distance()
		{
			T[] brr = new T[2 * Length + 1];
			for (int i = 0; i < Length; i++)
			{
				brr[i] = Value[i];
			}
			for (int i = 0; i < Length; i++)
			{
				brr[Length + i] = Value[i];
			}
			int maxHam = 0;
			for (int i = 1; i < Length; i++)
			{
				int currHam = 0;
				for (int j = i, k = 0; j < (i + Length); j++, k++)
				{
					if (brr[j] != (dynamic)Value[k])
					{
						currHam++;
					}
				}
				if (currHam == Length)
				{
					return Length;
				}
				maxHam = Math.Max(maxHam, currHam);
			}
			return maxHam;
		}

		/// <summary>
		/// 移动所有的 0 到数组末尾
		/// </summary>
		public void Push_Zeros_To_End()
		{
			int count = 0;
			for (int i = 0; i < Length; i++)
			{
				if ((dynamic)Value[i] != 0)
				{
					Value[count++] = Value[i];
				}
			}
			while (count < Length)
			{
				Value[count++] = (dynamic)0;
			}
		}

		/// <summary>
		/// Fisher-Yates洗牌算法,听起来很高大上 :P
		/// Fisher–Yates shuffle Algorithm
		/// </summary>
		public void Randomize()
		{
			for (int i = Length - 1; i > 0; i--)
			{
				int j = rnd.Next(0, i + 1);
				dynamic temp = Value[i];
				Value[i] = Value[j];
				Value[j] = temp;
			}
		}

		/// <summary>
		/// 计算第 k 个最小数
		/// </summary>
		/// <param name="k"></param>
		/// <returns></returns>
		public T Kth_Smallest(int k)
		{
			Array.Sort(Value);
			return Value[k - 1];
		}

		/// <summary>
		/// 下标 low ... high 之间的和值
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		public int Sum_Between(int low, int high)
		{
			int sum = 0;
			for (int i = low; i < high; i++)
			{
				sum += (dynamic)Value[i];
			}
			return sum;
		}

		/// <summary>
		/// 均值
		/// </summary>
		/// <returns></returns>
		public double Mean()
		{
			double sum = 0.0;
			for (int i = 0; i < Length; i++)
			{
				sum += (dynamic)Value[i];
			}
			return (double)sum / (double)Length;
		}

		/// <summary>
		/// 中值(不是均值哦)
		/// </summary>
		/// <returns></returns>
		public double Median()
		{
			Array.Sort(Value);
			if ((Length % 2) != 0)
			{
				return (dynamic)Value[Length / 2];
			}

			return (double)((dynamic)Value[(Length - 1) / 2] + (dynamic)Value[Length / 2]) * 0.5;
		}

		/// <summary>
		/// 和值查找表
		/// </summary>
		private T[,] lookup { get; set; } = null;

		/// <summary>
		/// 构建和值稀疏表
		/// </summary>
		public void Build_Sparse_Table()
		{
			lookup = new T[Length + 1, Length + 1];
			for (int i = 0; i < Length; i++)
			{
				lookup[i, 0] = Value[i];
			}

			for (int j = 1; (1 << j) <= Length; j++)
			{
				for (int i = 0; (i + (1 << j) - 1) < Length; i++)
				{
					if ((dynamic)lookup[i, j - 1] < (dynamic)lookup[i + (1 << (j - 1)), j - 1])
					{
						lookup[i, j] = lookup[i, j - 1];
					}
					else
					{
						lookup[i, j] = lookup[i + (1 << (j - 1)), j - 1];
					}
				}
			}
		}

		/// <summary>
		/// 稀疏查表法求 low high 之间的最小值
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		public T Sparse_Min_Between(int low, int high)
		{
			int j = (int)Math.Log(high - low + 1);
			if ((dynamic)lookup[low, j] <= (dynamic)lookup[high - (1 << j) + 1, j])
			{
				return lookup[low, j];
			}
			else
			{
				return lookup[high - (1 << j) + 1, j];
			}
		}

		/// <summary>
		/// 转为 M x N 的矩阵
		/// </summary>
		/// <param name="m"></param>
		/// <param name="n"></param>
		/// <returns></returns>
		/// <exception cref="Exception"></exception>
		public T[,] ToMatrix(int m, int n)
		{
			if (m * n != Length)
			{
				throw new Exception("Error matrix size!");
			}
			T[,] matrix = new T[m, n];
			for (int i = 0; i < m; i++)
			{
				for (int j = 0; j < n; j++)
				{
					matrix[i, j] = this[i * n + j];
				}
			}
			return matrix;
		}

		/// <summary>
		/// ToString函数的重写
		/// 1 overload 重载
		/// 2 override 重写
		/// 3 new 覆写
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			string r = "";
			foreach (T x in Value)
			{
				r += x + ", ";
			}
			if (r.Length == 0) return "";
			return r.Trim().Substring(0, r.Length - 1);
		}

		public int CompareTo(T other)
		{
			throw new NotImplementedException();
		}
	}
}

?——————————————————————

POWER BY 315SOFT.COM &
TRUFFER.CN

文章来源:https://blog.csdn.net/beijinghorn/article/details/124151190
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。