我有一个实际计算someValues的方法。方法如下。
public static double sum(int z, int x, int y)
{
double count = 0.0;
if (x == 0)
{
if (z <= 0) return 1.0;
return 0.0;
}
for (int i = 1; i <= y; i++)
{
count += sum(z - i, x - 1, y);
}
return count;
}
我只想将此方法从递归转换为正常迭代。或者如果可能的话,可以使用某个线方程请帮帮我。
答案 0 :(得分:1)
所以这不漂亮,但它没有递归工作。此外,由于原因,我将返回类型从double更改为int:
public static int sum(int z, int x, int y)
{
// Compute number of calls
int[][] calls = new int[x+1][x*y+1];
calls[0][0] = 1;
for (int i = 0; i < x; i++) {
for (int j = 0; j <= x*y; j++) {
for (int target = j+1; target <= j+y && target <= x*y; target++) {
calls[i+1][target] += calls[i][j];
}
}
}
// Return count of last column where z <= 0
int result = 0;
for (int j = x*y; z-j <= 0; j--) {
result += calls[x][j];
}
return result;
}
要了解,请查看此高科技Excel表格:
此图表说明了sum(3, 3, 3)
的来电。水平地你看到x和垂直你看到z都变得更小。 y是3而且没有改变。
左上角1
表示对sum(3, 3, 3)
的一次调用。然后,此调用会产生三个子调用(因为y = 3):sum(2, 2, 3)
,sum(1, 2, 3)
和sum(0, 2, 3)
。这三个调用可以在下一列中找到(其中x = 2)。
然后,这三个调用中的每一个再次产生三个调用,显示在x = 1的行中。关于z,这九个调用有点重叠。然后,这九个呼叫中的每一个再次产生三个呼叫,导致在x = 0列中进行27次呼叫。
要获得结果,您只需计算x = 0列中的所有调用,其中z <= 0.在此示例中,这是每次调用,因此得到的结果为27.对于更大的z,结果将是小一点。
答案 1 :(得分:0)
public static double sum(int z, int x, int y) {
int num = 0;
for (int i = 0; i <= y; i++) {
if (z - x - i > 0) {
num++;
}
}
return (double) (Math.pow(y, x) - num);
}
说明:您的方法最多会在y^x
个递归调用中启动。在递归的最后一级,x == 0
,您必须在所有呼叫中确定z
的最大值,并检查这些呼叫中有多少有z > 0
,以便呼叫返回0,您不必考虑它。现在,在递归的最后一级,z
的最大值由z - x
给出。现在,您只需计算for
循环中z - x
保持正数的所有实例,这样就不会影响您的总和。计算出该数字后,从结果的初始近似值中减去它,即y^x
。