用java数组展示计算机的多位数相乘
我们通常用java语言实现多位数相乘时,都是直接输入两个数然后便会输出结果
例如:System.out.print(1234*567);
便直接得到结果: 699678
那计算机里面是怎么实现多位数相乘的呢?
换句话说,计算机不可能储存每个数相乘的结果。和我们计算乘法一样——我们用所背乘法口诀表来计算。计算机只记录了乘法表的结果,然后以此为基础计算所有多少位数相乘的结果。
例:
下面我们用java数组展示下用这个原理来计算多位数:
1、引进两个乘数并放入数组中
//因为int类型的整数最大范围为2147483647
//而使用字符串类型即String可以计算长度更大的多位数,所以这里不直接用int类型
String sa="12345";//乘数sa
String sb="678";//乘数sb
int i,j,carry=0;//carry用于暂时存储两数相乘时的进位
//将字符串切割为一个个char字符,并转换为整形放入整形数组里
int Array_a[]=new int[sa.length()];
int Array_b[]=new int[sb.length()];
for(i=0;i<sa.length();i++)
Array_a[Array_a.length-1-i]=Integer.parseInt(sa.charAt(i)+"");
for(i=0;i<sb.length();i++)
Array_b[Array_b.length-1-i]=Integer.parseInt(sb.charAt(i)+"");
注:这里我们存放整形数组时,是将字符串逆序存放,
即Array_a数组存放的是 54321
Array_b数组存放的是 876
因为后面这两个数组元素计算相乘时的进位逆序更容易添加。
2、创建一个二维数组,用于存放两个数组相乘的结果
int c[][]=new int[Array_b.length+1][Array_a.length+Array_b.length];
注:
二维数组c[][]行数为Array_b.length+1创多一行,因为用最后一行储存相加的结果
二维数组c[][]列数为Array_a.length+Array_b.length,因为两数相乘的结果的位数不可能大于这两个数的位数之和。
(即999=891 结果不可能大于三位数——即99和9两个数的位数和
同理99999=98901 结果不可能大于五位数——即999和99两个数的位数和
)
3、计算两个数组的相乘
for(i=0;i<Array_b.length;i++)
{
for(j=0;j<Array_a.length;j++)
{
//carry为进位 前面代码中已经创建并赋值为零 carry=0
c[i][j]=(carry+Array_b[i]*Array_a[j])%10;//进位和所乘的结果相加并求余
carry=(carry+Array_b[i]*Array_a[j])/10;//下一个高位数的进位
if(j==Array_a.length-1)//当最后一位数仍然要进位时,最后一个数直接等于进位
c[i][Array_a.length]=carry;
}
carry=0;//重置进位为0
}
为方便理解 概念图如下:
注:下面的箭头表示进位的数为多少例8*5=40向高位进4
上述代码计算完后结果为:
下一步:
//对所得结果的数组进行数组移位(即等于两数相乘时十位数往后添1个0,百位数往后添2个0等)
for(i=1;i<c.length;i++)
move_array(c[i],i);
下面是自己写的移位函数(具体怎么样不细讲):
//一维数组移位函数
public static void move_array(int a[],int leng)
{
int i;
int b[]=new int[leng];
for(i=0;i<b.length;i++)
b[i]=a[a.length-1-i];
for(i=a.length-1;i>=leng;i--)
a[i]=a[i-leng];
for(i=0;i<b.length;i++)
a[i]=b[b.length-1-i];
}
因为个位数乘完之后到十位数相乘并且需要移到十位数上面相乘
即:
移位后相加:
//用上述移位后的二维数组相加并储存到最后一行的二维数组中
for(j=0;j<Array_a.length+Array_b.length;j++)
{
for(i=0;i<Array_b.length;i++)
{
c[Array_b.length][j]=c[Array_b.length][j]+c[i][j];//数组每列累加到每列最后一个数
if(i==Array_b.length-1)
{
int c1=c[Array_b.length][j];//用于存储累加前的元素
c[Array_b.length][j]=(carry+c[Array_b.length][j])%10;
carry=(carry+c1)/10;
}
}
}
概念图如下:
4、最后将结果逆序并转为字符串输出结果:
//转换为字符串
String result="";
int judge=0;//用于判断数组移去前面的0后不再移动后面的0
for(j=Array_a.length+Array_b.length-1;j>=0;j--)
{
if(c[Array_b.length][j]!=0||judge==1)
{
result=result+c[Array_b.length][j];
judge=1;
}
}
System.out.println(result);
完整代码如下:
public class 多位数相乘 {
public static void main(String[] args)
{
int a=12345,b=678;
System.out.println("计算结果:"+multiply(a, b));
System.out.println(a+"*"+b+"="+(a*b));
}
public static String multiply(int a,int b)
{
//将整数a,b转换为字符串,确定 Array_a[]和Array_b[]数组长度,
//并再次转换为整型存到 Array_a[]和Array_b[]数组中
String sa=""+a;
String sb=""+b;
int i,j,carry=0;//carry用于暂时存储两数相乘时的进位
int Array_a[]=new int[sa.length()];
int Array_b[]=new int[sb.length()];
for(i=0;i<sa.length();i++)
Array_a[Array_a.length-1-i]=Integer.parseInt(sa.charAt(i)+"");
for(i=0;i<sb.length();i++)
Array_b[Array_b.length-1-i]=Integer.parseInt(sb.charAt(i)+"");
//创建二维数组,用于储存 Array_a[]和Array_b[]每个元素相乘的结果
//二维数组行数为Array_b.length+1创多一行,因为用最后一行储存相加的结果
//二维数组列数为Array_a.length+Array_b.length,因为两数相乘的结果的位数不可能大于这两个数的位数之和
int c[][]=new int[Array_b.length+1][Array_a.length+Array_b.length];
//计算 Array_a[]和Array_b[]每个元素相乘的结果并储存
for(i=0;i<Array_b.length;i++)
{
for(j=0;j<Array_a.length;j++)
{
c[i][j]=(carry+Array_b[i]*Array_a[j])%10;
carry=(carry+Array_b[i]*Array_a[j])/10;
if(j==Array_a.length-1)
c[i][Array_a.length]=carry;
}
carry=0;
}
//对所得结果的数组进行数组移位(即等于两数相乘时十位数往后添1个0,百位数往后添2个0等)
for(i=1;i<c.length;i++)
move_array(c[i],i);
//用上述移位后的二维数组相加并储存到最后一行的二维数组中
for(j=0;j<Array_a.length+Array_b.length;j++)
{
for(i=0;i<Array_b.length;i++)
{
c[Array_b.length][j]=c[Array_b.length][j]+c[i][j];//数组每列累加到每列最后一个数
if(i==Array_b.length-1)
{
int c1=c[Array_b.length][j];//用于存储累加前的元素
c[Array_b.length][j]=(carry+c[Array_b.length][j])%10;
carry=(carry+c1)/10;
}
}
}
//转换为字符串
String result="";
int judge=0;//用于判断数组移去前面的0后不再移动后面的0
for(j=Array_a.length+Array_b.length-1;j>=0;j--)
{
if(c[Array_b.length][j]!=0||judge==1)
{
result=result+c[Array_b.length][j];
judge=1;
}
}
return result;
}
//一维数组移位函数
public static void move_array(int a[],int leng)
{
int i;
int b[]=new int[leng];
for(i=0;i<b.length;i++)
b[i]=a[a.length-1-i];
for(i=a.length-1;i>=leng;i--)
a[i]=a[i-leng];
for(i=0;i<b.length;i++)
a[i]=b[b.length-1-i];
}
}
这是运行结果:
我们也同样可以用这个计算 结果比int类型范围更大的数
下面结果已经12345678*22345的结果已经超过了int类型 所以结果是错误的
以上便是我用java数组展示计算机计算多位数相乘的原理
以上仅是我个人(代码菜鸟一枚)的理解看法,如有不当请各位大佬提出!谢谢!