极大数乘法。举例说明:123*456
123
* 456
————————
738
615
492
---------------
56088
算法思想是:以第二个数的每一位分别乘以第一位数的每一位然后相加,当然这其中要考虑的如下三个问题:
1.确保是正确的位数
2.进位问题
3.相加的位置问题
现描述如下假设极大数是以string存储的,那么以以下的方式转换为int数组
1.数组的第一个位置存储极大数的位数
2.数组以倒序的方式存储数字个十百千万.... 上的值
如string a = “123” 那么转换的数组为int[] aa = (3, 3, 2, 1);
因为当两个数相乘的时候结果的位数是小于等于两个数的位数之和
因此用上面的例子来说明的话
string a = “123” 数组:int[] aa = (3, 3, 2, 1);
string b = “456” 数组:int[] bb = (3, 6, 5, 4);
string result = ?? 数组:int[] resultarray = new int[7];
现在给出如下的算法:
/// <summary> /// Large Number Multiply /// </summary> /// <param name="firstNumber">The First Large Number</param> /// <param name="secondNumber">The Second Large Number</param> /// <remarks>The first array is the median of the large number /// e.g. if the number is 123 when it converts to array, it was sotored 3,3,2,1</remarks> /// <returns></returns> public static string LargeNumberMultiply(string firstNumber, string secondNumber) { char[] filter = "0 ".ToCharArray(); firstNumber = firstNumber.TrimStart(filter); secondNumber = secondNumber.TrimStart(filter); string resultNumber = string.Empty; int firstMedian = firstNumber.Length; int secondMedian = secondNumber.Length; int maxResultMedian = firstMedian + secondMedian; int[] first = StringToIntArray(firstNumber); int[] second = StringToIntArray(secondNumber); //median's sum + 1,1 is to save the median int[] result = new int[firstMedian + secondMedian + 1]; //loop variable, k meaning the middle result, l meaning the last result int i = 0, j = 0, k = 0, l = 0; int resultMedian = 0; int mul = 0;//The result. e.g. 4 * 8 = 48 int remain = 0;//The remain. e.g. 4 * 8 = 48 mod 10 = 8 int carry = 0;//The carry. e.g. 4 * 8 = 48 / 10 = 4 for (k = 1, i = 1; i < second.Length; i++, k++) { if (second[i] == 0)//if the second[i] is zero, continue { continue; } mul = remain = carry = 0; for (l = k, j = 1; j < first.Length; j++, l++) { mul = first[j] * second[i]; mul += carry; remain = mul % 10; carry = mul / 10; //need to extensive one median if (l == resultMedian + 1) { resultMedian++; } //add with previous result. First the result is zero. result[l] += remain; if (result[l] >= 10) { //consider the result exceed 10 carry += (result[l] / 10); result[l] %= 10; } } //the last multiply result need to consider the carry. if is not zero //need to carry if (carry != 0) { resultMedian++; //when the loop is over, "l" auto ++ so is result[l] = carry; not result[l + 1] = carry; result[l] = carry; } } //save the the result median result[0] = resultMedian; for (k = result[0]; k > 0; k--) { resultNumber += result[k].ToString(); } return resultNumber; } public static int[] StringToIntArray(string temp) { int length = temp.Length; int[] result = new int[length + 1]; result[0] = length; for (int i = 0, j = length; i < temp.Length && j > 0; i++, j--) { //At this position //when use result[i + 1] = Convert.ToInt32(temp[i]); //the result is ASICC so must convert char to string result[j] = Convert.ToInt32(temp[i].ToString()); } return result; }
在此进位是从如下的考虑的,什么时候该让result的位数加 1了?
当 l == 位数+1 的时候,这个时候就表示现有的位数已经不够了,因此需要位数增加
进位问题是通过取余来获得的,并且是通过 mul += carry;其中carry是上一个位置产生的进位例如123*456的时候,从第二个数开始
分别乘以第一个数,当6*2的时候应该是把6*3的结果产生1的进位给加上去
相加的位置问题,通过两个循环变量,l和k k meaning the middle result, l meaning the last result
因为每一次的第二层循环结束时,都确定了一位,例如第一次对应的是个位,第二次对应的是十位,第三次对应的是百位,而相应的存储在数组中的位置依次是result[1],result[2],result[3],依次类推,每一次的第二层循环都确定一个数直至最后得出结果
该程序已经在C# 中测试,已经测试通过