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 }

 

posted on 2018-04-13 18:00  你猜怎么着  阅读(7919)  评论(0编辑  收藏  举报

导航