Java模拟两个大整数的加法、乘法、除法

来源:互联网 发布:网络中央控制主机 编辑:程序博客网 时间:2024/06/02 19:05
package ddd;import java.math.BigInteger;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class BigIntegerAddition {    /**     *      * 问题:java实现两个大数相加,可能存在溢出。 如123456789 + 987654321 返回 1111111110     *      * 解决办法:     * 1.直接用BigInteger      *      * 2.模拟手算加法,进位相加(暂时没有考虑负数的情况),该类模拟两个大数的相加, 相乘,相除。至于相减,看了该类的相加就知道如何实现了。     * 该类中的加、乘、除的算法思路与人工的计算方式一致。虽然算法目的是达到了,但效率的话的确有待商榷,因为本人能力有限,实在是想不到更好的实现方式,还望     * 各位路过的高人指点!!!若有更好的实现方式,记得留言咯!     */    public static void main(String[] args) {        String x = "23456789";        String y = "987654321";        BigInteger a = new BigInteger(x);        BigInteger b = new BigInteger(y);        BigInteger c = a.add(b);        System.out.println(c.toString());        System.out.println(add(x, y));        System.out.println(add("-100", "1"));        System.out.println(add("-1000", "1"));        System.out.println(add("-1", "1"));        System.out.println(add("-17", "901"));        System.out.println(add("1", "-100"));        System.out.println(add("1", "-1000"));        System.out.println(add("1", "-1"));        System.out.println(add("901", "-17"));        System.out.println(posMultiPos("556", "7"));        System.out.println(posMultiPos("195", "5"));        System.out.println(posMultiPos("919", "8"));        System.out.println("--->" + trimPrefixedZero("0"));        System.out.println(posMultiPos("99", "0"));        System.out.println(divid("138", "12", 6));        System.out.println(divid("10", "3", 6));    }    /**     * 两个整数的加法运算,考虑正负数,由于减法可以转化为加法运算,     * 所以本人并没有直接给出求大整数减法的算法     * @param x     * @param y     * @return     */    public static String add(String x, String y) {        if (isNullOrEmpty(x) || isNullOrEmpty(y)) {            return null;        }        if (!isNumeric(x) || !isNumeric(y)) {            return null;        }        if (x.equals("0")) {            return y;        }        if (y.equals("0")) {            return x;        }        if (x.charAt(0) == '-' && y.charAt(0) == '-') {            x = x.substring(1);            y = y.substring(1);            return "-" + posAddPos(x, y);        } else if (x.charAt(0) != '-' && y.charAt(0) != '-') {            return posAddPos(x, y);        } else if (x.charAt(0) == '-' && y.charAt(0) != '-') {            return negAddPos(x, y);        } else if (x.charAt(0) != '-' && y.charAt(0) == '-') {            String tem = x;            x = y;            y = tem;            return negAddPos(x, y);        }        return null;    }    /**     * 一个负数与一个正数的加法     * @param x     * @param y     * @return     */    public static String negAddPos(String x, String y) {        if (x.charAt(0) != '-' || y.charAt(0) == '-') {            throw new IllegalArgumentException("x必须是负数数,y必须是正数");        }        // 判断x代表的负数的绝对值是否比正数y的绝对值大        boolean isAbsXLarger = false;        x = x.substring(1);        if (x.length() > y.length()) {            isAbsXLarger = true;            String tmp = x;            x = y;            y = tmp;        } else if (x.length() == y.length()) {            isAbsXLarger = isAbsXLarger(x, y);            if (isAbsXLarger) {                String tmp = x;                x = y;                y = tmp;            }        }        x = addZeroToFirst(x, y.length());        int len = y.length();        int[] a = toIntArray(y);        int[] b = toIntArray(x);        int[] c = new int[len + 1];        for (int i = 0; i < len; i++) {            int ac = a[len - 1 - i];            int bc = b[len - 1 - i];            if (ac - bc >= 0) {                c[len - i] = ac - bc;            } else {                c[len - i] = (ac + 10) - bc;                int r = 1;                while ((len - 1 - i - r) >= 0 && a[len - 1 - i - r] == 0) {                    a[len - 1 - i - r] = 9;                    r++;                }                a[len - 1 - i - r] = a[len - 1 - i - r] - 1;            }        }        StringBuilder sb = new StringBuilder();        for (int i = 0; i <= len; i++) {            sb.append(c[i]);        }        String z = trimPrefixedZero(sb.toString());        if (z.equals("0")) {            z = "";        }        if (z.length() > 0 && isAbsXLarger) {            return "-" + sb.toString();        } else if (z.length() > 0) {            return sb.toString();        } else {            return "0";        }    }    /**     * 两个正数的加法     * @param x     * @param y     * @return     */    public static String posAddPos(String x, String y) {        if (x.length() > y.length()) {            String tmp = x;            x = y;            y = tmp;        }        x = addZeroToFirst(x, y.length());        String z = "";        int len = x.length();        int[] a = toIntArray(x);        int[] b = toIntArray(y);        int[] c = new int[len + 1];        int d = 0;        for (int i = 0; i < len; i++) {            int tmpSum = a[len - 1 - i] + b[len - 1 - i] + d;            c[len - i] = tmpSum % 10;            d = tmpSum / 10;        }        c[0] = d;        StringBuilder sb = new StringBuilder();        for (int i = 0; i <= len; i++) {            sb.append(c[i]);        }        z = trimPrefixedZero(sb.toString());        return z;    }    /**     * 大整数的乘法     * @param x     * @param y     * @return     */    public static String multi(String x, String y) {        if (isNullOrEmpty(x) || isNullOrEmpty(y)) {            return null;        }        if (!isNumeric(x) || !isNumeric(y)) {            return null;        }        if (x.charAt(0) == '-' && y.charAt(0) == '-') {            x = x.substring(1);            y = y.substring(1);            return posMultiPos(x, y);        } else if (x.charAt(0) != '-' && y.charAt(0) != '-') {            return posMultiPos(x, y);        } else if (x.charAt(0) == '-' && y.charAt(0) != '-') {            x = x.substring(1);            return "-" + posMultiPos(x, y);        } else if (x.charAt(0) != '-' && y.charAt(0) == '-') {            y = y.substring(1);            return "-" + posMultiPos(x, y);        }        return null;    }    /**     * 一个多位数与一个个位数的乘法,注:这两个数都只能是正数     * @param x     * @param y     * @return     */    private static String posMultiSingleDigit(String x, String y) {        if (y.length() != 1 || x.charAt(0) == '-') {            throw new IllegalArgumentException("参数异常");        }        String z = "";        int len = x.length();        int[] a = toIntArray(x);        int b = Integer.parseInt(y);        int[] c = new int[len + 1];        int d = 0;        for (int i = 0; i < len; i++) {            int tempV = a[len - 1 - i] * b;            int r = (tempV % 10) + d;            d = tempV / 10;            if (r >= 10) {                c[len - i] = r - 10;                d = d + 1;            } else {                c[len - i] = r;            }        }        c[0] = d;        StringBuilder sb = new StringBuilder();        for (int i = 0; i <= len; i++) {            sb.append(c[i]);        }        z = trimPrefixedZero(sb.toString());        return z;    }    /**     * 两个正数的乘法     * @param x     * @param y     * @return     */    public static String posMultiPos(String x, String y) {        if (x.length() < y.length()) {            String tem = x;            x = y;            y = tem;        }        int[] b = toIntArray(y);        int len = b.length;        String[] temp = new String[len];        for (int i = 0; i < len; i++) {            temp[len - 1 - i] = posMultiSingleDigit(x, b[len - 1 - i] + "");            temp[len - 1 - i] += getZeroStringOfLenght(i);        }        String result = "0";        for (int i = 0; i < len; i++) {            result = posAddPos(result, temp[i]);        }        return result;    }    /**     * 大整数的除法, 如果不能整除, 则小数保留位数为precision,如果能整除,则保留一位小数     * @param x     * @param y     * @param precision 小数的精度     * @return     */    public static String divid(String x, String y, int precision) {        if (isNullOrEmpty(x) || isNullOrEmpty(y)) {            return null;        }        if (!isNumeric(x) || !isNumeric(y)) {            return null;        }        boolean flag = false;        List<String> li = new ArrayList<String>();        if (x.charAt(0) == '-' && y.charAt(0) == '-') {            x = x.substring(1);            y = y.substring(1);            posDividPos(x, y, "", li, precision, false);        } else if (x.charAt(0) != '-' && y.charAt(0) != '-') {            posDividPos(x, y, "", li, precision, false);        } else if (x.charAt(0) == '-' && y.charAt(0) != '-') {            flag = true;            x = x.substring(1);            posDividPos(x, y, "", li, precision, false);        } else if (x.charAt(0) != '-' && y.charAt(0) == '-') {            flag = true;            y = y.substring(1);            posDividPos(x, y, "", li, precision, false);        }        String result = "";        for(String ele : li)        {            result += ele;        }        result = trimPrefixedZero(result);        if(flag && !result.equals("0")) {            result = "-" + result;        }        return result;    }    /**     * 两个正整数的除法     * @param x     * @param y     * @param temp     * @param li     */    private static void posDividPos(String x, String y, String temp, List<String> li, int precision, boolean dotIncluded) {        if (x.length() == 0 && precision  == 0) {            return;        }        char[] charArray = x.toCharArray();        String[] xArray = new String[charArray.length];        for (int i = 0; i < charArray.length; i++) {            String s = String.valueOf(charArray[i]);            xArray[i] = s;        }        List<String> xList = new ArrayList<String>(Arrays.asList(xArray));        if (xList.size() > 0) {            temp += xList.remove(0);        } else {            if(!dotIncluded) {                li.add(".");                dotIncluded = true;            }            if(precision > 0) {                precision--;                temp += "0";              }        }        temp = trimPrefixedZero(temp);        while (isAbsXLarger(y, temp)) {            li.add("0");            if (xList.size() > 0) {                temp = temp + xList.remove(0);            } else if(precision > 0) {                if(!dotIncluded) {                    li.add(".");                    dotIncluded = true;                }                temp = temp + "0";                precision--;                temp = trimPrefixedZero(temp);                if(temp.equals("0")) {//                  return;                }            } else {                return;            }        }        int k = cacu(temp, y);        li.add(k + "");        String result = add(temp, "-" + posMultiSingleDigit(y, k + ""));        result = trimPrefixedZero(result);        if (result.equals("0")) {            result = "";        }        temp = result;        String newX = "";        for (String str : xList) {            newX += str;        }        System.out.println(result);        posDividPos(newX, y, result, li, precision, dotIncluded);    }    public static String getZeroStringOfLenght(int a) {        String str = "";        for (int i = 0; i < a; i++) {            str += "0";        }        return str;    }    public static int[] toIntArray(String str) {        int len = str.length();        int[] result = new int[len];        for (int i = 0; i < len; i++) {            result[i] = str.charAt(i) - '0';        }        return result;    }    public static String addZeroToFirst(String str, int length) {        StringBuilder sb = new StringBuilder();        int diff = length - str.length();        while (diff > 0) {            sb.append("0");            diff--;        }        sb.append(str);        return sb.toString();    }    public static boolean isNumeric(String str) {        Pattern p = Pattern.compile("^\\-?[0-9]*$");        Matcher isNum = p.matcher(str);        return isNum.matches();    }    public static boolean isNullOrEmpty(String str) {        if (str == null) {            return true;        }        if (("").equals(str.trim())) {            return true;        }        return false;    }    public static boolean isAbsXLarger(String x, String y) {        if (x.length() > y.length()) {            return true;        } else if (x.length() == y.length()) {            int[] xArray = toIntArray(x);            int[] yArray = toIntArray(y);            for (int i = 0; i < xArray.length; i++) {                if (xArray[i] > yArray[i]) {                    return true;                } else if (xArray[i] == yArray[i]) {                    continue;                } else {                    return false;                }            }        }        return false;    }    public static String trimPrefixedZero(String z) {        while (z.length() > 1 && z.charAt(0) == '0') {            z = z.substring(1);        }        return z;    }    /**     * 该方法相当于求 x/y的值,注意x、y都是一个正整数     * @param x     * @param y     * @return     */    public static int cacu(String x, String y) {        int k = 0;        for (int i = 0; i <= 9; i++) {            if (isAbsXLarger(x, posMultiSingleDigit(y, i + "")) || (x.equals(posMultiSingleDigit(y, i + "")))) {//              System.out.println(x);//              System.out.println(posMultiSingleDigit(y, i + ""));                k = i;            }        }        return k;    }}
1 0
原创粉丝点击