疫苗要打加强针!数组要用加强版!
三连发
加强版整数数组源代码https://mp.csdn.net/mp_blog/creation/editor/124151056
加强版实数数组源代码https://mp.csdn.net/mp_blog/creation/editor/124151110 加强版泛型数组源代码https://mp.csdn.net/mp_blog/creation/editor/124151190
源代码
1 文本格式
using System;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
/// <summary>
/// 加强版(整数)数组
/// 数组只是数组,
/// 如果需要Insert,Delete等操作,建议使用List
/// </summary>
public class IArray
{
/// <summary>
/// 随机数发生器
/// </summary>
private Random rnd { get; set; } = new Random((int)DateTime.Now.Ticks);
/// <summary>
/// 保存数组数据
/// </summary>
private int[] Value { get; set; } = null;
/// <summary>
/// 保存数组的原始数据
/// </summary>
private int[] Original { get; set; } = null;
/// <summary>
/// 数组的长度
/// </summary>
private int Length { get; set; } = Int16.MaxValue;
/// <summary>
/// 默认构造函数
/// </summary>
public IArray()
{
Value = new int[Length];
Original = new int[Length];
}
/// <summary>
/// 指定长度的构造函数
/// </summary>
/// <param name="n"></param>
public IArray(int n)
{
Length = n;
Value = new int[Length];
Original = new int[Length];
}
/// <summary>
/// 以 x 为样板的构造函数(克隆)
/// </summary>
/// <param name="x"></param>
public IArray(IArray x)
{
Length = x.Length;
Value = new int[Length];
Original = new int[Length];
for (int i = 0; i < Length; i++)
{
Value[i] = x[i];
Original[i] = x[i];
}
}
/// <summary>
/// 以数组 v 为数据的构造函数
/// </summary>
/// <param name="v"></param>
public IArray(int[] v)
{
Length = v.Length;
Value = new int[Length];
Original = new int[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 IArray(int[] x)
{
return new IArray(x);
}
/// <summary>
/// 以字符串为数据的赋值型构造函数
/// IArray a = "1,2,3,4";
/// </summary>
/// <param name="s"></param>
public static implicit operator IArray(string s)
{
string[] sa = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
List<int> list = new List<int>();
foreach (string sx in sa)
{
if (Int32.TryParse(sx.Trim(), out int x))
{
list.Add(x);
}
}
return new IArray(list.ToArray());
}
/// <summary>
/// 第一个数据
/// </summary>
public int Left
{
set
{
Value[0] = value;
}
get
{
return Value[0];
}
}
/// <summary>
/// 最后一个数据
/// </summary>
public int Right
{
set
{
Value[Length - 1] = value;
}
get
{
return Value[Length - 1];
}
}
/// <summary>
/// 最小数据
/// </summary>
public int Min
{
get
{
Array.Sort(Value);
return Value[0];
}
}
/// <summary>
/// 最大数据
/// </summary>
public int Max
{
get
{
Array.Sort(Value);
return Value[Length - 1];
}
}
/// <summary>
/// 提取数组数据
/// </summary>
public int[] GetValues
{
get { return Value; }
}
/// <summary>
/// 提取指定下标数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public int this[int index]
{
get { return Value[index]; }
set { Value[index] = value; }
}
/// <summary>
/// 加号重载(两个IArray相加)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator +(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] + b[i];
}
return c;
}
/// <summary>
/// 加号重载(a的每个元素加上数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator +(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] + b;
}
return c;
}
/// <summary>
/// 减号重载(两个IArray相减)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator -(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] - b[i];
}
return c;
}
/// <summary>
/// 减号重载(a的每个元素减去数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator -(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] - b;
}
return c;
}
/// <summary>
/// 乘号重载(两个IArray的元素一一对应相乘)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator *(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] * b[i];
}
return c;
}
/// <summary>
/// 乘号重载(a的每个元素乘以数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator *(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] * b;
}
return c;
}
/// <summary>
/// 除号重载(两个IArray的元素一一对应相除)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator /(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
if (b[i] == 0)
{
throw new Exception("Divided by zero!");
}
c[i] = a[i] / b[i];
}
return c;
}
/// <summary>
/// 除号重载(a的每个元素除以数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator /(IArray a, int b)
{
if (b == 0)
{
throw new Exception("divided by zero");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] / b;
}
return c;
}
/// <summary>
/// 排序(正序)
/// </summary>
public void Sort()
{
Array.Sort(Value);
}
/// <summary>
/// 倒排序
/// </summary>
public void Reverse_Sort()
{
Array.Sort(Value, (a, b) => b.CompareTo(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 = Value[0];
for (int i = 1; i < Length; i++)
{
v += Value[i] * Math.Pow(x, i);
}
return v;
}
/// <summary>
/// 左转(一格)
/// </summary>
public void Left_Rotate()
{
int 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()
{
int 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)
{
int 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++)
{
int 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(int key)
{
int pivot = Find_Pivot(0, Length - 1);
if (pivot == -1)
{
return Binary_Search(0, Length - 1, key);
}
if (Value[pivot] == key)
{
return pivot;
}
if (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 && Value[mid] > Value[mid + 1])
{
return mid;
}
if (mid > low && Value[mid] < Value[mid - 1])
{
return (mid - 1);
}
if (Value[low] >= 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, int key)
{
if (high < low)
{
return -1;
}
int mid = (low + high) / 2;
if (key == Value[mid])
{
return mid;
}
if (key > 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(int x)
{
int i;
for (i = 0; i < Length - 1; i++)
{
if (Value[i] > Value[i + 1])
{
break;
}
}
int l = (i + 1) % Length;
int r = i;
while (l != r)
{
if (Value[l] + Value[r] == x)
{
return true;
}
if (Value[l] + 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 * 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 int 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 && Value[mid + 1] < Value[mid])
{
return Value[mid + 1];
}
if (mid > low && Value[mid] < Value[mid - 1])
{
return Value[mid];
}
if (Value[high] > Value[mid])
{
return Min_Between(low, mid - 1);
}
return Min_Between(mid + 1, high);
}
/// <summary>
/// 计算(回转)数组的最大哈明距离
/// </summary>
/// <returns></returns>
public int Maximum_Hamming_Distance()
{
int[] brr = new int[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] != 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 (Value[i] != 0)
{
Value[count++] = Value[i];
}
}
while (count < Length)
{
Value[count++] = 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);
int temp = Value[i];
Value[i] = Value[j];
Value[j] = temp;
}
}
/// <summary>
/// 计算第 k 个最小数
/// </summary>
/// <param name="k"></param>
/// <returns></returns>
public int 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 += Value[i];
}
return sum;
}
/// <summary>
/// 均值
/// </summary>
/// <returns></returns>
public double Mean()
{
double sum = 0.0;
for (int i = 0; i < Length; i++)
{
sum += Value[i];
}
return (double)sum / (double)Length;
}
/// <summary>
/// 中值(不是均值哦)
/// </summary>
/// <returns></returns>
public double Median()
{
Array.Sort(Value);
if ((Length % 2) != 0)
{
return (double)Value[Length / 2];
}
return (double)(Value[(Length - 1) / 2] + Value[Length / 2]) * 0.5;
}
/// <summary>
/// 和值查找表
/// </summary>
private int[,] lookup { get; set; } = null;
/// <summary>
/// 构建和值稀疏表
/// </summary>
public void Build_Sparse_Table()
{
lookup = new int[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 (lookup[i, j - 1] < 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 int Sparse_Min_Between(int low, int high)
{
int j = (int)Math.Log(high - low + 1);
if (lookup[low, j] <= 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 int[,] ToMatrix(int m, int n)
{
if (m * n != Length)
{
throw new Exception("Error matrix size!");
}
int[,] matrix = new int[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 (int x in Value)
{
r += x + ", ";
}
if (r.Length == 0) return "";
return r.Trim().Substring(0, r.Length - 1);
}
}
}
2 代码格式
cs
using System;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
/// <summary>
/// 加强版(整数)数组
/// 数组只是数组,
/// 如果需要Insert,Delete等操作,建议使用List
/// </summary>
public class IArray
{
/// <summary>
/// 随机数发生器
/// </summary>
private Random rnd { get; set; } = new Random((int)DateTime.Now.Ticks);
/// <summary>
/// 保存数组数据
/// </summary>
private int[] Value { get; set; } = null;
/// <summary>
/// 保存数组的原始数据
/// </summary>
private int[] Original { get; set; } = null;
/// <summary>
/// 数组的长度
/// </summary>
private int Length { get; set; } = Int16.MaxValue;
/// <summary>
/// 默认构造函数
/// </summary>
public IArray()
{
Value = new int[Length];
Original = new int[Length];
}
/// <summary>
/// 指定长度的构造函数
/// </summary>
/// <param name="n"></param>
public IArray(int n)
{
Length = n;
Value = new int[Length];
Original = new int[Length];
}
/// <summary>
/// 以 x 为样板的构造函数(克隆)
/// </summary>
/// <param name="x"></param>
public IArray(IArray x)
{
Length = x.Length;
Value = new int[Length];
Original = new int[Length];
for (int i = 0; i < Length; i++)
{
Value[i] = x[i];
Original[i] = x[i];
}
}
/// <summary>
/// 以数组 v 为数据的构造函数
/// </summary>
/// <param name="v"></param>
public IArray(int[] v)
{
Length = v.Length;
Value = new int[Length];
Original = new int[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 IArray(int[] x)
{
return new IArray(x);
}
/// <summary>
/// 以字符串为数据的赋值型构造函数
/// IArray a = "1,2,3,4";
/// </summary>
/// <param name="s"></param>
public static implicit operator IArray(string s)
{
string[] sa = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
List<int> list = new List<int>();
foreach (string sx in sa)
{
if (Int32.TryParse(sx.Trim(), out int x))
{
list.Add(x);
}
}
return new IArray(list.ToArray());
}
/// <summary>
/// 第一个数据
/// </summary>
public int Left
{
set
{
Value[0] = value;
}
get
{
return Value[0];
}
}
/// <summary>
/// 最后一个数据
/// </summary>
public int Right
{
set
{
Value[Length - 1] = value;
}
get
{
return Value[Length - 1];
}
}
/// <summary>
/// 最小数据
/// </summary>
public int Min
{
get
{
Array.Sort(Value);
return Value[0];
}
}
/// <summary>
/// 最大数据
/// </summary>
public int Max
{
get
{
Array.Sort(Value);
return Value[Length - 1];
}
}
/// <summary>
/// 提取数组数据
/// </summary>
public int[] GetValues
{
get { return Value; }
}
/// <summary>
/// 提取指定下标数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public int this[int index]
{
get { return Value[index]; }
set { Value[index] = value; }
}
/// <summary>
/// 加号重载(两个IArray相加)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator +(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] + b[i];
}
return c;
}
/// <summary>
/// 加号重载(a的每个元素加上数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator +(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] + b;
}
return c;
}
/// <summary>
/// 减号重载(两个IArray相减)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator -(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] - b[i];
}
return c;
}
/// <summary>
/// 减号重载(a的每个元素减去数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator -(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] - b;
}
return c;
}
/// <summary>
/// 乘号重载(两个IArray的元素一一对应相乘)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator *(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] * b[i];
}
return c;
}
/// <summary>
/// 乘号重载(a的每个元素乘以数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static IArray operator *(IArray a, int b)
{
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] * b;
}
return c;
}
/// <summary>
/// 除号重载(两个IArray的元素一一对应相除)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator /(IArray a, IArray b)
{
if (a.Length != b.Length)
{
throw new Exception("Not same array size!");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
if (b[i] == 0)
{
throw new Exception("Divided by zero!");
}
c[i] = a[i] / b[i];
}
return c;
}
/// <summary>
/// 除号重载(a的每个元素除以数值b)
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static IArray operator /(IArray a, int b)
{
if (b == 0)
{
throw new Exception("divided by zero");
}
IArray c = new IArray(a);
for (int i = 0; i < a.Length; i++)
{
c[i] = a[i] / b;
}
return c;
}
/// <summary>
/// 排序(正序)
/// </summary>
public void Sort()
{
Array.Sort(Value);
}
/// <summary>
/// 倒排序
/// </summary>
public void Reverse_Sort()
{
Array.Sort(Value, (a, b) => b.CompareTo(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 = Value[0];
for (int i = 1; i < Length; i++)
{
v += Value[i] * Math.Pow(x, i);
}
return v;
}
/// <summary>
/// 左转(一格)
/// </summary>
public void Left_Rotate()
{
int 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()
{
int 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)
{
int 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++)
{
int 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(int key)
{
int pivot = Find_Pivot(0, Length - 1);
if (pivot == -1)
{
return Binary_Search(0, Length - 1, key);
}
if (Value[pivot] == key)
{
return pivot;
}
if (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 && Value[mid] > Value[mid + 1])
{
return mid;
}
if (mid > low && Value[mid] < Value[mid - 1])
{
return (mid - 1);
}
if (Value[low] >= 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, int key)
{
if (high < low)
{
return -1;
}
int mid = (low + high) / 2;
if (key == Value[mid])
{
return mid;
}
if (key > 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(int x)
{
int i;
for (i = 0; i < Length - 1; i++)
{
if (Value[i] > Value[i + 1])
{
break;
}
}
int l = (i + 1) % Length;
int r = i;
while (l != r)
{
if (Value[l] + Value[r] == x)
{
return true;
}
if (Value[l] + 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 * 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 int 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 && Value[mid + 1] < Value[mid])
{
return Value[mid + 1];
}
if (mid > low && Value[mid] < Value[mid - 1])
{
return Value[mid];
}
if (Value[high] > Value[mid])
{
return Min_Between(low, mid - 1);
}
return Min_Between(mid + 1, high);
}
/// <summary>
/// 计算(回转)数组的最大哈明距离
/// </summary>
/// <returns></returns>
public int Maximum_Hamming_Distance()
{
int[] brr = new int[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] != 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 (Value[i] != 0)
{
Value[count++] = Value[i];
}
}
while (count < Length)
{
Value[count++] = 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);
int temp = Value[i];
Value[i] = Value[j];
Value[j] = temp;
}
}
/// <summary>
/// 计算第 k 个最小数
/// </summary>
/// <param name="k"></param>
/// <returns></returns>
public int 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 += Value[i];
}
return sum;
}
/// <summary>
/// 均值
/// </summary>
/// <returns></returns>
public double Mean()
{
double sum = 0.0;
for (int i = 0; i < Length; i++)
{
sum += Value[i];
}
return (double)sum / (double)Length;
}
/// <summary>
/// 中值(不是均值哦)
/// </summary>
/// <returns></returns>
public double Median()
{
Array.Sort(Value);
if ((Length % 2) != 0)
{
return (double)Value[Length / 2];
}
return (double)(Value[(Length - 1) / 2] + Value[Length / 2]) * 0.5;
}
/// <summary>
/// 和值查找表
/// </summary>
private int[,] lookup { get; set; } = null;
/// <summary>
/// 构建和值稀疏表
/// </summary>
public void Build_Sparse_Table()
{
lookup = new int[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 (lookup[i, j - 1] < 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 int Sparse_Min_Between(int low, int high)
{
int j = (int)Math.Log(high - low + 1);
if (lookup[low, j] <= 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 int[,] ToMatrix(int m, int n)
{
if (m * n != Length)
{
throw new Exception("Error matrix size!");
}
int[,] matrix = new int[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 (int x in Value)
{
r += x + ", ";
}
if (r.Length == 0) return "";
return r.Trim().Substring(0, r.Length - 1);
}
}
}