您好,亲爱的社区,
我已经考虑了很长时间,但是似乎找不到解决方案。
我有int[][] bino = new int[15][]
,我在其中计算帕斯卡金字塔的前15行,并且不允许更改类型(无双精度,多精度等)。
我们知道12名教师为479001600
int的最大值为2147483647,因此fac(12)仍适合其中。
现在,最后三行变得很复杂。
Fac(13)是6227020800,对于int而言太大。
所以发生的是,对于第13,14和15行,它不会显示正确的数字 (因为6227020800 mod 2147483647 = 1932053506,这意味着在我的示例中,fac(13)= 1932053506)。
问题是,是否可以通过某种方式仍然显示正确的数字,而无需更改int[][] bino = new int[15][]
中的字段类型。其他任何事情都可以更改。
public static void main(String args[])
{
int[][] bino = new int[15][]; //Create 2d array for pascal pyramid
for(int i = 0; i < bino.length;i++)
for(int j = 0; j < bino[i].length;j++)
{
binos[i][j] = nOverk(i,j)
}
}
public int nOverk(int n, int k)
{
return(fac(n) / (fac(k) * fac((n-k))));
}
public int fac(int z) //Calculats the faculty of a number
{
int res = 1;
if(z == 0 || z == 1)
return 1;
for(int i = 2; i <= z; i++)
res *= i;
return res;
}
答案 0 :(得分:5)
AFAICT您只能使用resp。 fac()
需要nOverk()
。在fac(n) / (fac(k) * fac((n-k))))
一词中,您可以抵消一些因素,将临时值保持在允许的范围内。
例如,您只计算nOverk(4,2) = 4*3*2*1 / ((2*1) * (2 * 1))
而不是(4 * 3) / (2 * 1)
。在某些极端情况下,这无济于事,但我认为以这种方式定义任务以使其有所帮助。
public int nOverk(int n, int k)
{
return (lim_fac(n, k) / lim_fac(k, k));
}
private int lim_fac(int z, int n) //Calculats the "limited" faculty of a number, by multiplying n factors.
{
int res = 1;
if (n == 0) {
return 1;
}
if (n == 1) {
return z;
}
for (int i = z - n + 1; i <= z; i++) {
res *= i;
}
return res;
}
注意:我不确定100%是否正确lim_fac()
,但您应该明白。
答案 1 :(得分:3)
简单的解决方案是使用long
,但是您可以使用int
处理更大的数字(并节省工作量),而不必计算fac(a)/fac(b)
来提高效率。
public static void main(String... args) {
int[][] bino = new int[15][]; //Create 2d array for pascal pyramid
for (int i = 0; i < bino.length; i++) {
bino[i] = new int[i + 1];
for (int j = 0; j < i + 1; j++) {
bino[i][j] = nOverk(i, j);
}
}
}
static int nOverk(int n, int k) {
int min = Math.min(k, n - k);
int max = Math.max(k, n - k);
return fac(n, max) / fac(min, 1);
}
static int fac(int hi, int lo) {
if (hi == 0 || hi == 1)
return 1;
int res = 1;
for (int i = lo + 1; i <= hi; i++)
res *= i;
return res;
}
答案 2 :(得分:3)
在帕斯卡(Pascal)的三角形中,每个数字是其正上方两个数字的和。如果任务只是打印前15行,则不需要使用阶乘。
public static void main(String[] args) {
int n = 15;
int[][] pascal = new int[n+1][];
// initialize first row
pascal[1] = new int[1+2];
pascal[1][1] = 1;
// fill in Pascal's triangle
for (int i = 2; i <= n; i++) {
pascal[i] = new int[i+2];
for (int j = 1; j < pascal[i].length - 1; j++)
pascal[i][j] = pascal[i-1][j-1] + pascal[i-1][j];
}
// print results
for (int i = 1; i <= n; i++) {
for (int j = 1; j < pascal[i].length - 1; j++) {
System.out.print(pascal[i][j] + " ");
}
System.out.println();
}
}