Java 计算指数增长序列中的值之和
(见下面的解决方案) (潜伏者出现) 我使用BigDecimal/BigInteger类来处理非常大的数字 我有一个计算复合增长序列的公式 对于每个n,值=初始*(coef^n) 我试图找到一种快速的方法来计算n0和n1之间的值子集的和 例如,n0=4,n1=6 返回:首字母*(系数^4)+首字母*(系数^5)+首字母*(系数^6) 我不太懂数学,但也许有一种公式化的表达方式 我基本上是把所有的值加起来,通过提高系数将其中的一些值聚集成10的幂 据我所知,这个函数是准确的。我可以为返回一个值 n0=1,n1=50000,初始值=100,coef=1.05英寸,在一秒钟内 虽然我可能永远不会将该函数用于大于~20000的值,但如果有更有效的方法来实现这一点,那就太好了Java 计算指数增长序列中的值之和,java,bigdecimal,exponential,Java,Bigdecimal,Exponential,(见下面的解决方案) (潜伏者出现) 我使用BigDecimal/BigInteger类来处理非常大的数字 我有一个计算复合增长序列的公式 对于每个n,值=初始*(coef^n) 我试图找到一种快速的方法来计算n0和n1之间的值子集的和 例如,n0=4,n1=6 返回:首字母*(系数^4)+首字母*(系数^5)+首字母*(系数^6) 我不太懂数学,但也许有一种公式化的表达方式 我基本上是把所有的值加起来,通过提高系数将其中的一些值聚集成10的幂 据我所知,这个函数是准确的。我可以为返回一个值 n
public static final BigDecimal sum(int n0, int n1, BigDecimal initial, BigDecimal coef) {
BigDecimal sum = BigDecimal.ZERO;
int short_cut = 1000000000;
//Loop for each power of 10
while (short_cut >= 10) {
//Check the range of n is greater than the power of 10
if (n1 - n0 >= short_cut) {
//Calculate the coefficient * the power of 10
BigDecimal xCoef = coef.pow(short_cut);
//Add the first sum of values for n by re-calling the function for n0 to n0 + shortcut - 1
BigDecimal add = sum(n0, n0 + short_cut - 1, initial, coef);
sum = sum.add(add);
//Move n forward by the power of 10
n0 += short_cut;
while (n1 - n0 >= short_cut) {
//While the range is still less than the current power of 10
//Continue to add the next sum multiplied by the coefficient
add = add.multiply(xCoef);
sum = sum.add(add);
//Move n forward
n0 += short_cut;
}
}
//Move to the next smallest power of 10
short_cut /= 10;
}
//Finish adding where n is smaller than 10
for (; n0 <= n1; n0++)
sum = sum.add(initial.multiply(coef.pow(n0)));
return sum;
}
(首字母*coef^n0-coef^n1+1)/1-coef
谢谢维基百科。我将写一些算法思想 首先,让我们简化您的公式: 所以你应该计算:S=a*(c^n0)+a*(c^(n0+1))+…+a*(c^n1) 其中初始值=a和系数=c 设S(n)是下列和的函数: S(n)=a+a*c+a*(c^2)+…+a*(c^n) 我们将得到S=S(n1)-S(n0-1) 另一方面,S(n)是a的和,因此S(n)=a*(1-c^n)/(1-c) 所以我们将得到S=S(n1)-S(n0-1)=a*(1-c^n1)/(1-c)-a*(1-c^(n0-1))/(1-c)=a*(c^(n0-1)-c^n1)/(1-c) 所以现在我们必须处理计算c^n指数(当然BigDecimal类有pow方法,我们这样做只是为了能够计算算法的复杂性)。以下算法具有O(log(n))复杂性:
function exp(c,n){
// throw exception when n is not an natural number or 0
if(n == 0){
return 1;
}
m = exp(c, floor(n/2));
if (n % 2 == 0){
return m*m;
} else{
return m*m*c;
}
}
因此,如果我们考虑到代数运算具有O(1)复杂性这一事实,我们可以得出结论,求和可以用O(log(n))复杂性来计算 你也许应该问一下这个关于数学的问题。SE@DanzaBarr当我输入答案时,您已经编辑了问题并添加了解决方案:)
function exp(c,n){
// throw exception when n is not an natural number or 0
if(n == 0){
return 1;
}
m = exp(c, floor(n/2));
if (n % 2 == 0){
return m*m;
} else{
return m*m*c;
}
}