• 多项式的概念:
  • 多项式在计算机程序中的表示:用一个变量表示多项式的基 var base =  ,用一个数组表示系数 var arr = [a1, a2, a3, ... , an],数组的长度就是项数 n
  • 任何一个数字都可以用不同 base 的多项式表示,所以一个多项式也可以转换为另一个不同 base 的多项式

 

问题1:给定一个多项式,base已知,系数数组已知,如何计算它的和?

var sum = (base, arr) => {
let t = 0;
arr.forEach((item, index) => {
t += item * Math.pow(base, arr.length - 1 - index);
});
return t;
};

以上代码简单的计算了多项式的和,有个问题就是多项式的和可能超出一个变量所能表示的数字的最大值导致溢出,这里不解决该问题。

 

问题2:给定一个多项式,base已知,系数数组已知,如果要把它转换为另一个base2的多项式,base2 < base,那么base2需要一个多大的数组表示?

很明显,高base转低base,项数肯定会增多。首先,假设第一个多项式 base = b1 共 n 项,转换为第二个多项式 base = b2 共 m 项,现在就是要计算 m 的最小值。

m 什么时候最小,就是该多项式的和最大的时候,每一项都是 b2 - 1,和为 b2^m - 1,第一个多项式的和也需要在最大的情况下,才能计算出m的最小值,也就是 b1^n - 1

两个多项式的和相等,所以 b2^m = b1^n,

多项式的转换,多项式变基_多项式

     ,根据换底公式,

多项式的转换,多项式变基_数组_02

,注意,m 的值大概率不是整数,如果是小数就要取大于该小数的最小整数,可以用Math.ceil()函数

 

问题3:给定一个多项式,base已知,系数数组已知,如何用程序转换为另一个已知base2(base2 < base)的多项式?

首先,假设第一个多项式 base = b1 共 n 项,转换为第二个多项式 base = b2 共 m 项,m已经在上一步计算出来了。

第一个多项式可以表示为 

多项式的转换,多项式变基_数组_03

        这步很重要,下面的更重要

然后先用除法计算a1的b2多项式,就像用十进制计算二进制那样计算,会得到一个数组arr,每一项都小于b2,该多项式的和为a1。

然后(这句比较难懂后面有例子),再用该数组从末位开始乘b1+a2,然后除以b2,然后依次进位,得到a1b1+a2的b2多项式数组,和为a1b1+a2,然后如此重复,直到计算完an这一项,例子如下:

十进制数字 a1 =  295 共三位数,数组就是 [2, 9, 5],b1=16,a2假设=7,b2 = 10,从个位开始 5*16+7 = 87 进位 8 余 7,然后计算十位 9*16+8 = 152 ,进 15 余 2,然后百位 2*16+15 = 47,进 4 余 7,

所以新数组就是:[4, 7, 2, 7],也就是十进制数字4727,4727 = 295*16+7,完美,上面用十进制和十六进制举例子,其他进制也是一样。

程序如下:

var sum = (base, arr) => {
let t = 0;
arr.forEach((item, index) => {
t += item * Math.pow(base, arr.length - 1 - index);
});
return t;
};
const PolynomialTransformation = (base1, arr1, base2) => {

//先排除开头的0
let start = 0;
for(let i = 0; i < arr1.length; i++){
if(arr1[i] !== 0){
break;
}
else{
start++;
}
}
//全0返回空数组
if(start === arr1.length){
return [];
}

let arr2Length = Math.ceil((arr1.length - start) * (Math.log(base1) / Math.log(base2)));
let arr2 = new Array(arr2Length).fill(0);

let stepLength = arr2.length - 1;

for(let i = 0; i < arr1.length; i++){

let carry = arr1[i];

let place = arr2.length - 1;


while(true) {
carry += base1 * arr2[place];
arr2[place] = carry % base2;
carry = Math.floor(carry / base2);
if(carry === 0 && place < stepLength){
stepLength = place;
break;
}
place--;
}
}

return arr2;
};

var base1 = 16;
var arr1 = [5, 15, 9, 10, 15];
var base2 = 3;

console.log(sum(base1, arr1)); //391599
let arr2 = PolynomialTransformation(base1, arr1, base2);
console.log(arr2.toString()); //0,2,0,1,2,2,0,0,1,1,2,0,0
console.log(sum(base2, arr2)); //391599