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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM