需要帮助将Java移植到Ruby。奇怪的行为

时间:2011-10-20 11:34:48

标签: java ruby

我一直在努力解决这个问题几个小时没有成功。我正在尝试将这个Java代码重新编写到Ruby中,我认为我已经完成了,然而,发生了一些奇怪的事情。

Java方法:

static void analyze (int n, int seriesLen)
{
    int digit[] = new int [9];
    int d = 0;
    int m = n;

    series[seriesLen - 1] = n;

    while (m >= 10) {
        digit[d++] = m % 10;
        m /= 10;
    }
    digit[d++] = m;
    for (int subset = (1 << d) - 2; subset > 0; subset--) {
        int j = 0;
        int s = subset;
        int pos = d - 1;
        /* find first digit */
        while ((s & 1) == 0) {
            s >>= 1;
            pos--;
        }

        /* if first digit is a 0, move on */

        if (digit[pos] == 0) continue;

        do {
            if ((s & 1) == 1) j = j*10 + digit[pos];
            s >>= 1;
            pos--;
            } while (s > 0);


        if (j > 1 && n % j == 0) {
            int k = 0;
            s = subset ^ ((1 << d) - 1);
            pos = d - 1;

            while (s > 0) {
                if ((s & 1) == 1) k = k*10 + digit[pos];
                s >>= 1;
                pos--;
            }

            analyze (k, seriesLen + 1);
        }
    }

    System.out.println("seriesLen: " + seriesLen);
    if (betterSeries (seriesLen)) {
        for (int i = 0; i < seriesLen; i++) {
            best[i] = series[i];
        }
        bestLen = seriesLen;
    }

}

Ruby方法:

def analyze(n, seriesLen)
    @digit = [0,0,0,0,0,0,0,0,0]
    m = n
    d = 0
    $series[seriesLen-1] = n

    while(m >= 10)
        @digit[d] = (m % 10)
        d = d + 1
        m /= 10
    end
    @digit[d] = m
    d = d + 1
    subset = (1 << d) - 2
    while (subset > 0)
        j = 0
        s = subset
        pos = d - 1
        while ((s & 1) == 0)
            s >>= 1
            pos -= 1
        end
        if (@digit[pos] == 0):
            subset -= 1
            next
        end
        begin
            j = (j*10 + @digit[pos]) if ((s & 1) == 1)
            s >>= 1
            pos -= 1
        end while s > 0
        if (j > 1 && n % j == 0):
            k = 0
            s = (subset) ^ ((1 << d) - 1)
            pos = d - 1
            while (s > 0)
                k = (k*10 + @digit[pos]) if ((s & 1) == 1)
                s >>= 1
                pos -= 1
            end

            analyze(k, seriesLen + 1)
        end

        subset -= 1
    end

    if (betterSeries(seriesLen)):
        for i in 0...seriesLen
            $best[i] = $series[i]
        end
        $bestLen = seriesLen;
    end
end

我对这两个版本的代码的相关数据做了一些跟踪。直到大约一半时,一切都完全相同。在此之后,Java版本中的digit []数组除了2位数[2](这是正确的)之外全部为零。但是,在Ruby版本的这一点上,digit [2]与所有其他元素一起为零。我很困惑为什么他们似乎在这种不连续性出现之前长时间完美地协调工作。我甚至无法弄清楚为什么Java版本中的数字[2] = 2(我肯定Java代码是正确的)。

1 个答案:

答案 0 :(得分:1)

您的@digit是一个实例变量,而不是本地变量。 (这就是@的意思。)每次调用analyze时,它都会重置为全零。并且由于analyze在中途调用它,它最终会在它开始执行它之前用一个全零的数组覆盖前一个调用的版本。 (另一方面,在Java代码中,它是本地的 - 每个调用都有自己的digit。)

尝试删除变量名称中的@,看看是否有帮助。