找到小于2个整数a和b的2个最大数字的算法,它们可以相互整除

时间:2010-07-12 00:09:57

标签: c# .net algorithm

所以这就是挑战。给定2个名为a和b的整数:

//找到两个最小的数字,小于a和b,可以互相整除。

//输入:a:102,b:53 //输出:(102,51)

//输入:a:7,b:4 //输出:(6,3)

//输入:a:3,b:2 //输出:(2,2)

抓住的是,我不想蛮力。我认为它出现在O(n²)。

以下是该方法的签名:

static Tuple<int, int> Analyze(int a, int b)
{
    if (a % b == 0)
        return new Tuple<int, int>(a, b);
    else
        // Here’s where the algorithm kicks in
}

以下是一个示例实现:

static Tuple<int, int> Analyze(int left, int right)
{
    if (left % right == 0)
        return new Tuple<int, int>(left, right);
    else
    {
        for (int i = left; i >= right; i--)
        {
            for (int j = right; j >= 0; j--)
                if (i % j == 0)
                    return new Tuple<int, int>(i, j);
                else
                    i--;
        }
    }

    return null;
}

这是测试客户端:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Analyze(102, 53));
        Console.WriteLine(Analyze(6, 4));
        Console.WriteLine(Analyze(3, 2));
    }
}

我的实施有明显的问题,但对初学者来说并不坏。例如,当我使用106和54作为我的参数时,如果我没有减少外部循环变量(i--在else块中),我会找到匹配106和53.相反,我发现匹配104和52,这不是很正确,但是相对接近期望的结果。但是,我的示例实现比粗暴的强制方法要快得多,因为我永远不会循环超过b次,使其成为O(b)。思考,投入?

2 个答案:

答案 0 :(得分:1)

你看过Wolfram关于最大公约数的文章吗?我找到了一个很好的java代码,它实现了一个很好的GCD算法,你可以为你的目的修改{{3} }

答案 1 :(得分:1)

我认为这样可行,并且非常简单,如果我不感到困惑,它应该找到最大的sum(a,b)

static Tuple Analyze(int a, int b)
{
    if (a % b == 0)
        return new Tuple(a, b);
    else {
        // The algorithm starts here.
        // This is fairly easy to implement with tail recursion, but not optimal:
        // There are two cases to worry about:
        //   1) 'b' will never divide into 'a' evenly, but 'b-1' might.
        //   2) 'a' doesn't divide evenly by 'b', but 'a-1' might.
        if (a < b*2) return Analyze(a, b-1);
        else return Analyze(a-1, b);
    }
}

按字典顺序查找最大值是微不足道的。只需从b downto 1循环播放。

显然,如果你跳过一个以上,你就能做得更好。这是python中的一个例子(假设a>b,如果不是,则交换它们):

>>> def analyze(a, b):
...   if 0 == a%b: return (a,b)          # If b is a factor, return them.
...   if a < b*2: return analyze(a,a/2)  # If b can't factor, adjust 'b' to next.
...   return analyze(a-(a%b),b)          # Otherwise, adjust 'a' to next.
... 
>>> map(lambda p: analyze(*p), [(102, 53), (6, 4), (3,2)])
[(102, 51), (6, 3), (3, 1)]