【问题标题】:GCD of three numbers (without using array) euclidean algorithm三数的GCD(不使用数组)欧几里得算法
【发布时间】:2021-11-02 22:57:07
【问题描述】:

我有一个任务,这让我有点头疼。目标是找到三个整数的最大公约数,我成功地用两个相当容易地做到了,但是当我不能使用任何数组时,它会变得有点复杂。

这是我使用的完整代码,从两个整数中找到 gcd,测试全部为绿色:

public static int GetGcdByEuclidean(int a, int b)
        {
            if (a == 0 && b == 0)
            {
                throw new ArgumentException(null);
            }
            else if (a == int.MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(a));
            }
            else if (b == int.MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(b));
            }
            else
            {
                int abs1 = Math.Abs(a);
                int abs2 = Math.Abs(b);
                a = abs1;
                b = abs2;

                while (a != 0 && b != 0)
                {
                    if (a > b)
                    {
                        a %= b;
                    }
                    else
                    {
                        b %= a;
                    }
                }

                return a | b;
            }
        }

现在我对 GCD 使用了相同的原理,但使用了我在网上找到的东西:gcd(a, b, c) = gcd(a, gcd(b, c)) = gcd( gcd(a, b), c) = gcd(gcd(a, c), b)..

public static int GetGcdByEuclidean(int a, int b, int c)
        {
            int result = 0;

            if ((a == 0 && b == 0) && c == 0)
            {
                throw new ArgumentException(null);
            }
            else if (a == int.MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(a));
            }
            else if (b == int.MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(b));
            }
            else if (c == int.MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(c));
            }
            else
            {
                int abs1 = Math.Abs(a);
                int abs2 = Math.Abs(b);
                int abs3 = Math.Abs(c);
                a = abs1;
                b = abs2;
                c = abs3;

                while (a != 0 && b != 0 && c != 0)
                {
                    if (a > b && a > c && b > c)
                    {
                        b %= c;
                        a %= b;
                        result = a;
                    }
                    else if (a > b && a > c && b < c)
                    {
                        c %= b;
                        a %= c;
                        result = a;
                    }
                    else if (b > a && b > c && a > c)
                    {
                        a %= c;
                        b %= a;
                        result = b;
                    }
                    else if (b > a && b > c && a < c)
                    {
                        c %= a;
                        b %= c;
                        result = b;
                    }
                    else if (c > a && c > b && a > b)
                    {
                        a %= b;
                        c %= a;
                        result = c;
                    }
                    else
                    {
                        b %= a;
                        c %= b;
                        result = c;
                    }
                }

                return result;
            }
        }

【问题讨论】:

标签: c# if-statement while-loop greatest-common-divisor


【解决方案1】:

只需保留 2 个数字的解决方案,并使用以下公式从 1 到 3 个数字调用它:gcd(a, b, c) = gcd(a, gcd(b, c))

public static int GetGcdByEuclidean(int a, int b)
{
    // Your working solution for two numbers...
}

public static int GetGcdByEuclidean(int a, int b, int c)
{
    return GetGcdByEuclidean(a, GetGcdByEuclidean(b, c)); 
}

注意,在 C# 中,您可以拥有多个同名的方法,只要参数列表不同。参数的名称无关紧要,只是参数的数量或类型必须不同。这称为overloading


具有任意数量的数字(但至少两个)的解决方案:

public static int GetGcdByEuclidean(int a, int b, params int[] other)
{
    int gcd = GetGcdByEuclidean(a, b);
    foreach (int x in other) {
        gcd = GetGcdByEuclidean(gcd, x);
    }
    return gcd; 
}

【讨论】:

  • 哇!它确实有效,我没想到这种解决方案。谢谢。
  • 我想知道您是否可以使用数组重载,例如:public static int GetGcdByEuclidean(int a, int b, params int[] other) return GetGcdByEuclidean(a, GetGcdByEuclidean(b, other[])); 也可以这样使用吗?
  • 是的,你可以递归调用这些方法。确保在每次调用时将参数数量减少一个,直到只剩下两个。例如。 gcd(a, gcd(b, other[0], copyOfOtherStartingAt2ndPosition)).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多