计算幂和的问题

Posted

技术标签:

【中文标题】计算幂和的问题【英文标题】:Problems with calculating the sum of powers 【发布时间】:2018-06-19 09:37:22 【问题描述】:

这是任务。

给定一个数组,机器输出每个其他数字的总和到下一个数字的幂。 例如: 给定array [w, x, y, z],输出将是

的值

Math.pow( w, x ) + Math.pow( y, z )

问题

找到机器给定数组的输出:[98, 45, 97, 36, 22, 62, 88, 71, 16, 20, 54, 59, 23, 31, 12, 23, 77, 39, 37 , 51, 68, 69, 92, 30]。

这是我用 JS 编写的代码,它给出了错误的结果 我得到了

的结果

1143588350561521212653379541203320722577849507571892512032437843441247325541362219974575744439494976388658582305078438350758494949763886585823050784383509633

这是错误的。

let a = [98, 45, 97, 36, 22, 62, 88, 71, 16, 20, 54, 59, 23, 31, 12, 23, 77, 39, 37, 51, 68, 69, 92, 30];
let s = 0,
  r = 1;
for (let i = 0; i <= 22; i = i + 2) 
  for (let j = 1; j <= a[i + 1]; j++) 
    r = multiply(r, a[i]);
  
  s = sum(s, r);
  r = 1;


// Add big numbers as strings in order to avoid scientific (exponent) notation
function sum(arg1, arg2) 
  var sum = "";
  var r = 0;
  var a1, a2, i;

  if (arg1.length < arg2.length) 
    a1 = arg1;
    a2 = arg2;
   else 
    a1 = arg2;
    a2 = arg1;
  
  a1 = a1.toString().split("").reverse();
  a2 = a2.toString().split("").reverse();

  for (i = 0; i < a2.length; i++) 
    var t = ((i < a1.length) ? parseInt(a1[i]) : 0) + parseInt(a2[i]) + r;
    sum += t % 10;
    r = t < 10 ? 0 : Math.floor(t / 10);
  

  if (r > 0)
    sum += r;
  sum = sum.split("").reverse();

  while (sum[0] == "0")
    sum.shift();

  return sum.length > 0 ? sum.join("") : Number("");



// Multiply big numbers as strings in order to avoid scientific (exponent) notation
function multiply(a, b) 
  var aa = a.toString().split('').reverse();
  var bb = b.toString().split('').reverse();

  var stack = [];

  for (var i = 0; i < aa.length; i++) 
    for (var j = 0; j < bb.length; j++) 
      var m = aa[i] * bb[j];
      stack[i + j] = (stack[i + j]) ? stack[i + j] + m : m;
    
  
  for (var i = 0; i < stack.length; i++) 
    var num = stack[i] % 10;
    var move = Math.floor(stack[i] / 10);
    stack[i] = num;

    if (stack[i + 1])
      stack[i + 1] += move;
    else if (move != 0)
      stack[i + 1] = move;
  
  return stack.reverse().join('');

// Print the result
console.log(s);

【问题讨论】:

你想要哪种类型的输出..? 不管是字符串还是数字 感谢编辑:-) 【参考方案1】:

我建议使用 big-integer 库:

let a = ...;
let s = bigInt()
for (var i = 0; i < a.length; i += 2) 
  s = s.plus(bigInt(a[i]).pow(bigInt(a[i+1])));

【讨论】:

【参考方案2】:

正如多米尼克所说,使用任何大整数库:

function calc(arr) 
  result = bigInt();
  for (var i = 0; i < arr.length; i += 2) 
    result = result.plus(bigInt(arr[i]).pow(arr[i+1]))
  
  return result.toArray(10).value.join('');


console.log(calc([98, 45, 97, 36, 22, 62, 88, 71, 16, 20, 54, 59, 23, 31, 12, 23, 77, 39, 37, 51, 68, 69, 92, 30]))
&lt;script src="https://peterolson.github.io/BigInteger.js/BigInteger.min.js"&gt;&lt;/script&gt;

javascript 无法在不丢失精度的情况下原生处理大整数。

【讨论】:

以上是关于计算幂和的问题的主要内容,如果未能解决你的问题,请参考以下文章

在有效时间内将正整数写为 2 的幂和的总方法数

求解自然数幂和的若干种方法

快速幂和快速乘

快速幂和快速乘

快速幂和慢速乘

快速幂和逆元问题