java两数相乘基础算法
下面是别人给我的代码:
1 package com.bootdo; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 System.out.println(multiply("2354343543543", "3213213213")); 7 } 8 public static String multiply(String num1, String num2) { 9 int l = num1.length(); 10 int r = num2.length(); 11 //用来存储结果的数组,可以肯定的是两数相乘的结果的长度,肯定不会大于两个数各自长度的和。 12 int[] num = new int[l+r]; 13 //第一个数按位循环 14 for(int i=0;i<l;i++) { 15 //得到最低位的数字 16 int n1=num1.charAt(l-1-i)-'0'; 17 //保存进位 18 int tmp=0; 19 //第二个数按位循环 20 for(int j=0;j<r;j++) { 21 int n2=num2.charAt(r-1-j)-'0'; 22 //拿出此时的结果数组里存的数+现在计算的结果数+上一个进位数 23 tmp=tmp+num[i+j]+n1*n2; 24 //得到此时结果位的值 25 num[i+j]=tmp%10; 26 //此时的进位 27 tmp/=10; 28 } 29 //第一轮结束后,如果有进位,将其放入到更高位 30 num[i+r]=tmp; 31 } 32 33 int i=l+r-1; 34 //计算最终结果值到底是几位数, 35 while(i>0&&num[i]==0){ 36 i--; 37 } 38 String result=""; 39 //将数组结果反过来放,符合正常读的顺序, 40 //数组保存的是:1 2 3 4 5 41 //但其表达的是54321,五万四千三百二十一。 42 while(i>=0) { 43 result += num[i--]; 44 } 45 return result; 46 } 47 48 }
以下是我自己修改后的代码,因为上面的代码我在开始看的时候陷入了一个误区,就是num[]存储的时候是从角标为0开始的,在最后处理的时候要将数组结果反过来,一般在做两数相乘的时候都是从后往前算(即第二个数的个位与第一个数的个位、十位...依次相乘,且从右往左书写,养成了习惯),因此我依据自己的习惯将逻辑稍作修改,从右往左存储,在最后直接从左往右读取即可。
*注:代码中 num1.charAt(l - 1 - i) - '0'; 是根据asc码将字节转为整形的过程。
1 package test; 2 3 4 public class Test { 5 6 public static void main(String[] args) { 7 8 System.out.println(multiply("55", "44")); 9 10 } 11 12 public static String multiply(String num1, String num2) { 13 int l = num1.length(); 14 int r = num2.length(); 15 // 用来存储结果的数组,可以肯定的是两数相乘的结果的长度,肯定不会大于两个数各自长度的和。 16 int[] num = new int[l + r]; 17 //记录内循环num开始的角标 18 int x = num.length - 1; 19 //记录外循环num开始的角标 20 int y = num.length - 1; 21 // 第一个数按位循环 22 for (int i = 0; i < l; i++) { 23 y --; 24 // 得到最低位的数字 25 int n1 = num1.charAt(l - 1 - i) - '0'; 26 // 保存进位 27 int tmp = 0; 28 // 第二个数按位循环 29 for (int j = 0; j < r; j++) { 30 int n2 = num2.charAt(r - 1 - j) - '0'; 31 // 拿出此时的结果数组里存的数+现在计算的结果数+上一个进位数 32 tmp = tmp + num[x] + n1 * n2; 33 // 得到此时结果位的值 34 num[x] = tmp % 10; 35 // 此时的进位 36 tmp /= 10; 37 //角标往前移一位 38 x --; 39 } 40 // 第一轮结束后,如果有进位,将其放入到更高位(在内循环中已经减1,此时的角标即为最高位) 41 num[x] = tmp; 42 x = y; 43 } 44 45 int i = l + r - 1; 46 // 计算最终结果值开头为零的个数 47 int q = 0; 48 while (i > 0 && q <= i && num[q] == 0) { 49 q ++; 50 } 51 //从不为0的下标开始循环 52 String result = ""; 53 for (int j = q; j <= i; j++) { 54 result += num[j]; 55 } 56 57 return result; 58 } 59 60 }