使用堆栈找到最大的公约数

时间:2013-10-04 10:01:17

标签: ruby

我正在尝试使用堆栈来实现一个算法来找到最大的公约数:我无法根据下面的逻辑来制定正确的答案。请帮忙。这是我的代码:

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

2 个答案:

答案 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);
    }