我一直在努力解决这个问题几个小时没有成功。我正在尝试将这个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代码是正确的)。
答案 0 :(得分:1)
您的@digit
是一个实例变量,而不是本地变量。 (这就是@
的意思。)每次调用analyze
时,它都会重置为全零。并且由于analyze
在中途调用它,它最终会在它开始执行它之前用一个全零的数组覆盖前一个调用的版本。 (另一方面,在Java代码中,它是本地的 - 每个调用都有自己的digit
。)
尝试删除变量名称中的@
,看看是否有帮助。