标签:
Problem:
Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
Analysis:
The naive solution of this problem is to following the routine of multiplication, whose algorithm we are quite familar with. Solution 1: (Naive solution) 1. Iterate on one string‘s digit, use the digit multiply with the other number. 2. Add the partial result with total result. (note the trailing zero of each mulitiplication). Although the algorithm is clear, but it involves many mainpulations over string. I have made many mistakes in my first implementation.
Wrong solution:
public class Solution { public String multiply(String num1, String num2) { if (num1 == null || num2 == null) throw new IllegalArgumentException("The passed in arguments is illegal!"); char[] num2_array = num2.toCharArray(); String ret = "0"; for (int i = num2_array.length - 1; i >= 0; i--) { String temp = multiple(num1, num2_array[i]); ret = add(temp + (‘0‘*num2_array.length-1-i), ret); } return ret; } private String multiple(String num_str, Character n) { int carry = 0; char[] num = num_str.toCharArray(); StringBuffer ret = new StringBuffer(); for (int i = num.length - 1; i >= 0; i--) { int temp = Integer.valueOf(num[i]) * Integer.valueOf(n) + carry; int cur_digit = temp % 10; carry = temp / 10; ret.insert(0, cur_digit); } return ret.toString(); } private String add(String num1_str, String num2_str) { char[] num1 = num1_str.toCharArray(); char[] num2 = num2_str.toCharArray(); int carry = 0; int len = Math.max(num1.length, num2.length); StringBuffer ret = new StringBuffer(); for(int i = 0; i < len; i++) { int temp1 = (num1.length-1 >= i) ? Integer.valueOf(num1[i]) : 0; int temp2 = (num2.length-1 >= i) ? Integer.valueOf(num2[i]) : 0; int temp = temp1 + temp2 + carry; int cur_digit = temp % 10; carry = temp / 10; ret.insert(0, cur_digit); } return ret.toString(); } }
Mistakes analysis:
***************************************************************************** Mistakes mistake 1: forget to add carray number, when loop is over. for (int i = num.length - 1; i >= 0; i--) { ... ret.insert(0, cur_digit); } return ret.toString(); ? What if the carry is not 0. Fix: for (int i = num.length - 1; i >= 0; i--) { ... } if (carry != 0) ret.insert(0, carry); return ret.toString(); mistake 2: use Integer.valueOf() against character rather than String. int temp = Integer.valueOf(num[i]) * Integer.valueOf(n) + carry; Integer.valueOf(character c) would return the Ascii code of character c, rather than the Integer form with the value: c. Fix: covert the character into a string. int temp = Integer.valueOf(num[i]+"") * Integer.valueOf(n+"") + carry; mistake 3: use Ruby code for the implemetation. wish ‘0‘ * 3 could return "000" ret = add(temp + (‘0‘*num2_array.length-1-i), ret); Fix: use a while loop to add trial zero. while (trail_zero < num2_array.length-1-i) { temp += ‘0‘; trail_zero++; } mistake 4: the index of add is wrong, since the two string may be in different length, and we must start from the right digt to left digit. Start from left is absolutely wrong! for(int i = 0; i < len; i++) { int temp1 = (num1.length-1 >= i) ? Integer.valueOf(num1[i]) : 0; int temp2 = (num2.length-1 >= i) ? Integer.valueOf(num2[i]) : 0; ... } Fix: for(int i = 0; i < len; i++) { int temp1 = (len1-1-i >= 0) ? Integer.valueOf(num1[len1-1-i]+"") : 0; int temp2 = (len2-1-i >= 0) ? Integer.valueOf(num2[len2-1-i]+"") : 0; ... }
Solution 1:
public class Solution { static public String multiply(String num1, String num2) { if (num1 == null || num2 == null) throw new IllegalArgumentException("The passed in arguments is illegal!"); char[] num2_array = num2.toCharArray(); String ret = "0"; for (int i = num2_array.length - 1; i >= 0; i--) { String temp = multiple(num1, num2_array[i]); int trail_zero = 0; while (trail_zero < num2_array.length-1-i) { temp += ‘0‘; trail_zero++; } ret = add(temp, ret); } while (ret.length() > 1 && ret.charAt(0) == ‘0‘) ret = ret.substring(1, ret.length()); return ret; } static private String multiple(String num_str, Character n) { int carry = 0; char[] num = num_str.toCharArray(); StringBuffer ret = new StringBuffer(); for (int i = num.length - 1; i >= 0; i--) { int temp = Integer.valueOf(num[i]+"") * Integer.valueOf(n+"") + carry; int cur_digit = temp % 10; carry = temp / 10; ret.insert(0, cur_digit); } if (carry != 0) ret.insert(0, carry); return ret.toString(); } static private String add(String num1_str, String num2_str) { char[] num1 = num1_str.toCharArray(); char[] num2 = num2_str.toCharArray(); int len1 = num1.length; int len2 = num2.length; int carry = 0; int len = Math.max(num1.length, num2.length); StringBuffer ret = new StringBuffer(); for(int i = 0; i < len; i++) { int temp1 = (len1-1-i >= 0) ? Integer.valueOf(num1[len1-1-i]+"") : 0; int temp2 = (len2-1-i >= 0) ? Integer.valueOf(num2[len2-1-i]+"") : 0; int temp = temp1 + temp2 + carry; int cur_digit = temp % 10; carry = temp / 10; ret.insert(0, cur_digit); } if (carry != 0) ret.insert(0, carry); return ret.toString(); } }
Improvement analysis:
Solution 2:
标签:
原文地址:http://www.cnblogs.com/airwindow/p/4779824.html