所以这就是挑战。给定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)。思考,投入?
答案 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)]