在VB.NET或C#中,我希望能够动态地计算一个或多个值的最大公约数(GCD),而无需使用递归方法。
我以C#中的准则this解决方案来计算两个值的GCD。现在,我希望对该解决方案进行调整,以能够计算不确定的值量(一个或多个值包含在传递给下面的函数的值数组中)...
这是我目前所做的:
VB.NET(原始代码):
<DebuggerStepperBoundary>
Private Shared Function InternalGetGreatestCommonDivisor(ParamArray values As Integer()) As Integer
' Calculate GCD for 2 or more values...
If (values.Length > 1) Then
Do While Not values.Contains(0)
For Each value As Integer In values
Dim firstMaxValue As Integer = values.Max()
Dim secondMaxValue As Integer = values.OrderByDescending(Function(int As Integer) int)(1)
values(values.ToList.IndexOf(firstMaxValue)) = (firstMaxValue Mod secondMaxValue)
Next value
Loop
Return If(values.Contains(0), values.Max(), values.Min())
Else ' Calculate GCD for a single value...
Return ...
End If
End Function
C#(在线代码转换,我根本没有测试过):
[DebuggerStepperBoundary]
private static int InternalGetGreatestCommonDivisor(params int[] values)
{
// Calculate GCD for 2 or more values...
if (values.Length > 1)
{
while (!values.Contains(0))
{
foreach (int value in values)
{
int firstMaxValue = values.Max();
int secondMaxValue = values.OrderByDescending((int @int) => @int).ElementAtOrDefault(1);
values[values.ToList().IndexOf(firstMaxValue)] = (firstMaxValue % secondMaxValue);
}
}
return (values.Contains(0) ? values.Max() : values.Min());
}
else // Calculate GCD for a single value...
{
return ...;
}
我知道将类型转换为List会影响大量值的整体性能,但最优先的事情是使该算法按预期工作,并最终对其进行优化/重构。
对于某些值的组合,我的适应效果正常,但对于其他值却不起作用。例如,在this在线GCD计算器中,如果我们输入以下值:{1920、1080、5000、1000、6800、5555}理论上的GCD为5,或者至少是该在线服务计算出的GCD ,但是我的算法返回15。
答案 0 :(得分:1)
// pass all the values in array and call findGCD function
int findGCD(int arr[], int n)
{
int gcd = arr[0];
for (int i = 1; i < n; i++) {
gcd = getGcd(arr[i], gcd);
}
return gcd;
}
// check for gcd
int getGcd(int x, int y)
{
if (x == 0)
return y;
return gcd(y % x, x);
}
答案 1 :(得分:0)
您可以使用Linq:
static int GCD2(int a, int b){
return b == 0 ? Math.Abs(a) : GCD2(b, a % b);
}
static int GCD(int[] numbers){
return numbers.Aggregate(GCD2);
}
答案 2 :(得分:0)
您面临的问题是由于您太早离开内循环而造成的。仅检查一个值是否为0是不够的,因为实际上您必须检查除一个值之外的所有值是否都是0。
C#代码如下所示:
private static int InternalGetGreatestCommonDivisor(params int[] values)
{
// Calculate GCD for 2 or more values...
if (values.Length > 1)
{
while (values.Count(value => value > 0) != 1)
{
int firstMaxValue = values.Max();
int secondMaxValue = values.OrderByDescending((int @int) => @int).ElementAtOrDefault(1);
values[values.ToList().IndexOf(firstMaxValue)] = (firstMaxValue % secondMaxValue);
}
return values.Max();
}
else
{
// Calculate GCD for a single value...
}
}
对于您的示例,代码返回5
。恐怕我不能为您提供VB.NET代码的确切表示。