标签:
朋友面试的时候遇到的一道题,用java写程序,计算两个20位数字的乘法。听着很有趣,就试着实现了。
思路是用代码模拟乘法手算的过程,也就是一位位的去乘,结果保留在对应的位上,并解决进位问题。
问对方是否解出来的时候,对方告诉我java有一个java.math.BigInteger包里,有一个BigInteger s1=new BigInteger(a);接收String类型数据,可以使用s1.multiply(s2)进行大位数的乘法。
以下是我的代码:
import java.math.BigInteger;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
public class Chengfa {
static Map<Integer, Integer> map1 = new TreeMap<Integer, Integer>(); // 存放用户输入的第一个数字,键为数字所在位数,123依次代表个十百,依次类推,值为该位的数字。
static Map<Integer, Integer> map2 = new TreeMap<Integer, Integer>(); // 存放用户输入的第二个数字,含义与map1相同。
static Map<Integer, Integer> map3 = new TreeMap<Integer, Integer>(); // 存放计算出的结果,键与值的含义与mpa1相同。
static int calcNumber=0;//用于统计计算了多少次
public static void main(String[] args) {
System.out.println("请输入第一个数字:");
Scanner in = new Scanner(System.in);
String a = in.next(); // 接收用户输入的第一个数字,以String类型保存
System.out.println("请输入第二个数字:");
String b = in.next(); // 接收用户输入的第二个数字,以String类型保存
map1=saveToMap(a); //将字符串a里的数字按位存入到map1集合中
map2=saveToMap(b); //将字符串b里的数字按位存入到map1集合中
map3=calc(map1, map2);
String result=getResult(map3);
System.out.println("乘积的答案是:" + result);
System.out.println("总的运算次数是:"+calcNumber);
BigInteger s1=new BigInteger(a);
BigInteger s2=new BigInteger(b);
System.out.println("用java.math.BigInteger验算的答案:"+s1.multiply(s2));
}
/**
* 将用户输入的字符串按位存入map集合中
* @param number 传入的参数为用户输入的字符串
* @return 返回存完数字的map集合
*/
public static Map<Integer, Integer> saveToMap(String number) {
Map<Integer, Integer> mapTemp = new TreeMap<Integer, Integer>();
int length = number.length(); //将传入的字符串的长度取出来,以便在下面的循环中,将数字倒叙放入map集合中
for (int m = 1; m <= number.length(); m++) { // 将输入的第一个字符串转换成单个的数字,并按位放在map1中
mapTemp.put(length--, Integer.parseInt(number.substring(m - 1, m)));//将字符串中的数字倒叙放入map集合中
}
return mapTemp;
}
/**
* 嵌套2个for循环,实现map1里面每一个数字与map2里的每一个数字依次相乘,并将结果按位保存在结果集合中
* @param map1
* @param map2
* @return
*/
public static Map<Integer, Integer> calc(Map<Integer, Integer> map1, Map<Integer, Integer> map2) {
Map<Integer, Integer> mapTemp1 = new TreeMap<Integer, Integer>();
for (int total = 1; total <= map1.size() + map2.size(); total++) { //初始化mapTemp1里的数据,避免保存数字时出现的空指针问题
mapTemp1.put(total, 0);
}
for (int i = 1; i <= map1.size(); i++) { // 第一层循环,当1取map1里的个位,当2取map1里的十位,依此递加
for (int k = 1; k <= map2.size(); k++) { // 第二层循环,当1取map2里的个位,当2取map2里的十位,依此递加
int result1 = map1.get(i) * map2.get(k); // 将map1里的i位数与map2里的各位置数逐步相乘,result1为乘积
calcNumber++;
int currentNum = k + i - 1;
if (result1 / 10 == 0) { // 当乘积的结果为个位数时,进入此代码块,只需要把个位放进去
addNumber(currentNum, result1,mapTemp1);
} else { // 当乘积为两位数时,进入此代码块,先把个位放进去,再把十位放进去
addNumber(currentNum, result1 % 10,mapTemp1); // 把个位放到map3集合中的currentNum的位置
addNumber(currentNum + 1, result1 / 10,mapTemp1); // 把十位放到map3集合中的currentNum的下一个位置
}
}
}
return mapTemp1;
}
/**
* 将运算结果保存至该位的运算方法,主要用来解决数字相加后大于9的进位问题
* @param currentNum 结果应该放入的位置(位数)
* @param result 需要放入该位置的数值
*/
public static void addNumber(int currentNum, int result,Map<Integer, Integer> resultMap) {
int resultTem = resultMap.get(currentNum) + result;
if (resultTem / 10 == 0) { // 如果resultTem是个位数,直接添加到该位置就好,不需要考虑进位问题
resultMap.put(currentNum, resultTem);
calcNumber++;
} else { // 如果resultTem是两位数,则需要考虑进位问题
resultMap.put(currentNum, resultTem % 10);// 把个位数添加到该位置
addNumber(currentNum + 1, resultTem / 10,resultMap);
calcNumber++;
}
}
/**
* 将map3里面的结果转换成String类型以便最终显示给用户的方法
* @param resultMap
* @return
*/
public static String getResult(Map<Integer, Integer> resultMap){
String result="";
for (int g = resultMap.size(); g >= 1; g--) {
if (resultMap.get(g) == 0 && result.equals("")) {// 如果map3.get(g)为0,且result里面没数字,证明是前面需要省略的0,不做任何操作
} else {
result += resultMap.get(g) + "";
}
}
return result;
}
}
标签:
原文地址:http://blog.csdn.net/erichk2008/article/details/51363293