MathEx 数学计算帮助类
最大公约数
/// <summary>
/// 找到并返回最大公约数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static int FindGCD(int a, int b)
{
if (a==0)
{
return b;
}
if (b==0)
{
return a;
}
int _a = a, _b = b;
int r = _a & _b;
while (r!=0)
{
_a = _b;
_b = r;
r = _a & _b;
}
return _b;
}
相对质数
/// <summary>
/// 确定给定的两个数是相对质数
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool IsRelativelyPrime(int a ,int b)
{
return FindGCD(a, b) == 1;
}
二项式系数 C(n,k)
从n个选取k个的方法总数
/// <summary>
/// 二项式系数 C(n,k)
/// </summary>
/// <param name="n"></param>
/// <param name="k"></param>
/// <returns></returns>
public static ulong BinomialCoefficients(uint n, uint k)
{
ulong rslt = 1;
if (k > n-k)
{
k = n - k;
}
for (int i = 0; i < k; i++)
{
rslt *= Convert.ToUInt64(n - i);
rslt /= Convert.ToUInt64(i + 1);
}
return rslt;
}
逆平方根
/// <summary>
/// 逆平方根(浮点数的平方根倒数)
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
public static float Q_rsqrt(float x)
{
float xhalf = 0.5f * x;
unsafe
{
int i = *(int*)&x; // 浮点值当整数读取
i = 0x5f3759df - (i >> 1); // 给初始猜测
x = *(float*)&i; // 整数当浮点数读取
x = x * (1.5f - xhalf * x * x);
x = x * (1.5f - xhalf * x * x); // 第二次迭代,可删除
}
return x;
}
public static float Q_rsqrt2(float x)
{
float xhalf = 0.5f * x;
int i = Convert.ToInt32(FloatToBinary(x).Replace(" ", string.Empty), 2);
i = 0x5f3759df - (i >> 1); // 给初始猜测
x = BinaryToFloat(Convert.ToString(i, 2));
x = x * (1.5f - xhalf * x * x);
x = x * (1.5f - xhalf * x * x); // 第二次迭代,可删除
return x;
}
约瑟夫环
/// <summary>
/// 约瑟夫环问题:有n个人围成一个圈,每隔q个人踢掉一个人,问最后留下来的人是几号
/// O(logN)
/// </summary>
/// <param name="n"></param>
/// <param name="q"></param>
private static long JosephRing(long n, long q)
{
long D = 1, end = (q - 1) * n;
while (D <= end)
{
D = Ceil(q * D, q - 1);
}
return q * n + 1 - D;
}
private static long Ceil(long x, long y)
{
return x / y + (x % y == 0 ? 0 : 1);
}
最大公共子字符串
/// <summary>
/// 最大公共子字符串
/// </summary>
/// <param name="str1">字符串1</param>
/// <param name="str2">字符串2</param>
/// <returns>子串</returns>
static string GetMaxCommonStr(string str1, string str2)
{
if (string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2))
{
return string.Empty;
}
var temp = new int[str1.Length, str2.Length];
int max = -0; // 相同子串的最大长度
int n1End = -1; // str1的长公共字符串的最后位置
int n2End = -1; // str2的长公共字符串的最后位置
for (int i = 0; i < str1.Length; i++)
{
for (int j = 0; j < str2.Length; j++)
{
if (str1[i] != str2[j])
{
temp[i, j] = 0;
}
else
{
if (i == 0 || j == 0)
{
temp[i, j] = 1;
}
else
{
temp[i, j] = temp[i - 1, j - 1] + 1;
}
if (temp[i,j] > max)
{
max = temp[i, j];
n1End = i;
n2End = j;
}
}
}
}
var rslt = new StringBuilder();
while (n1End >= 0 && n2End>= 0 && temp[n1End, n2End] > 0)
{
rslt.Insert(0, str1[n1End]);
n1End--;
n2End--;
}
return rslt.ToString();
}