我正在尝试使用堆栈来实现一个算法来找到最大的公约数:我无法根据下面的逻辑来制定正确的答案。请帮忙。这是我的代码:
def d8(a,b)
if (a==b)
return a
end
s = Stack.new
s.push(b)
s.push(a)
c1 = s.pop
c2 = s.pop
while c1!=c2
if s.count>0
c1 = s.pop
c2 = s.pop
end
if c1== c2
return c1
elsif c1>c2
c1 = c1-c2
s.push(c2)
s.push(c1)
else
c2 = c2 -c1
s.push(c2)
s.push(c1)
end
end
return nil
end
答案 0 :(得分:3)
GCD不能是nil
。两个整数总是有一个GCD。因此,函数中的逻辑已经不正确,因为在某些条件下它具有return nil
。
查看此return nil
条件时,会发生c1 == c2
(它将退出while
循环)。同时,在while
循环内,您返回值if c1 == c2
。这两个案例存在逻辑矛盾。换句话说,您将退出while
条件上的c1 == c2
循环,并在if c1 == c2
条件触发并将条件视为有效并返回正确答案之前将该条件视为无效。
稍微简化逻辑,你得到:
def d8(a,b)
return a if a == b # Just a simpler way of doing a small if statement
s = Stack.new # "Stack" must be a gem, not std Ruby; "Array" will work here
s.push(b)
s.push(a)
#c1 = s.pop # These two statements aren't really needed because of the first
#c2 = s.pop # "if" condition in the while loop
while c1 != c2
if s.count > 0
c1 = s.pop
c2 = s.pop
end
# if c1 == c2 isn't needed because the `while` condition takes care of it
if c1 > c2
c1 = c1 - c2
else
c2 = c2 - c1
end
# These pushes are the same at the end of both if conditions, so they
# can be pulled out
s.push(c2)
s.push(c1)
end
return c1 # This return occurs when c1 == c2
end
这将有效,但更明显的是,堆栈的使用是多余的,并且在算法中根本没有用处。 s.count > 0
将始终为true
,并且您在推送变量后立即弹出变量(基本上是无操作)。所以这相当于:
def d8(a,b)
return a if a == b
c1 = a
c2 = b
while c1 != c2
if c1 > c2
c1 = c1 - c2
else
c2 = c2 - c1
end
end
return c1
end
答案 1 :(得分:0)
将使用Java代码
public static int gcd (int p, int q) {
StackGeneric<Integer> stack = new StackGeneric<Integer>();
int temp;
stack.push(p);
stack.push(q);
while (true) {
q = stack.pop();
p = stack.pop();
if (q == 0) {
break;
}
temp = q;
q = p % q;
p = temp;
stack.push(p);
stack.push(q);
}
return p;
}
使用while循环将函数调用替换为递归解决方案,并对其进行迭代,直到第二个参数变为0为止,这与递归函数调用一样发生
public static int gcd (int p, int q) {
if (q == 0) {
return p;
}
return gcd(q, p % q);
}