首页 > 编程语言 >java大整数类

java大整数类

时间:2024-04-01 15:32:01浏览次数:25  
标签:index return number 整数 BigInt java numberDigits otherNumber

import java.util.ArrayList;

public class BigInt implements Comparable<BigInt> {

    private static final char MINUS_CHAR = '-';
    private static final char PLUS_CHAR = '+';

    // Saves the digits of the number - last element represents the smallest unit of the number
    private ArrayList<Integer> numberDigits = new ArrayList<>();

    // Indication if the number is negative
    private boolean negative;

    // String representation as given by the user
    private String stringNumber;

    BigInt(String number){

        if (number.equals("")){
            stringNumber = "0";
            numberDigits.add(0);
        }
        else {
            // Dealing with the positive/negative signs
            char firstChar = number.charAt(0);
            if (firstChar == MINUS_CHAR || firstChar == PLUS_CHAR) {
                if (firstChar == MINUS_CHAR)
                    negative = true;

                number = number.substring(1);
            }

            // Regex to remove zeros at the beginning of the number
            number = number.replaceFirst("^0+(?!$)", "");
            stringNumber = number;

            // Saving the digits
            for (int index = 0; index < number.length(); index++) {
                int curDigNumericVal = Character.getNumericValue(number.charAt(index));

                // Current char is not a valid digit
                if (curDigNumericVal == -1)
                    throw new IllegalArgumentException();

                numberDigits.add(curDigNumericVal);
            }
        }
    }

    private boolean isNegative() {
        return negative;
    }

    private void flipNegativity() {
        if (stringNumber == "0")
            return;

        negative = !negative;
        if (stringNumber.charAt(0) == MINUS_CHAR){
            stringNumber = stringNumber.substring(1);
        } else {
            stringNumber = MINUS_CHAR + stringNumber;
        }
    }

    // Adding another bigInt number to the current bigInt number
    BigInt plus(BigInt otherNumber) {

        // current is negative, other is positive - subtract current from the other
        if (negative && !otherNumber.isNegative()) {
            return otherNumber.minus(new BigInt(stringNumber));
        }

        // other is negative - subtract its value
        if (otherNumber.isNegative()) {
            return minus(new BigInt(otherNumber.toString()));
        }

        // Setting the longer number of the two numbers
        ArrayList<Integer> longerNumber, shorterNumber;
        if (numberDigits.size() >= otherNumber.numberDigits.size()) {
            longerNumber = numberDigits;
            shorterNumber = otherNumber.numberDigits;
        }
        else {
            longerNumber = otherNumber.numberDigits;
            shorterNumber = numberDigits;
        }

        int lengthsDifferences = longerNumber.size() - shorterNumber.size();


        StringBuilder resultString = new StringBuilder();

        // Initializing a carry for every addition
        int carry = 0;


        // Iterating from smallest unit digit to the biggest
        for (int index = shorterNumber.size() - 1; index >= 0; index--) {
            int shorterNumberDigit = shorterNumber.get(index);
            int longerNumberDigit = longerNumber.get(index + lengthsDifferences);

            int newDigit = shorterNumberDigit + longerNumberDigit + carry;

            // Calculating the carry and the new digit
            carry = newDigit / 10;
            newDigit = newDigit % 10;

            resultString.append(newDigit);
        }

        // Adding digits of longer number
        for (int index = lengthsDifferences - 1; index >= 0; index--) {
            int currDig = longerNumber.get(index);

            // Check if need to add carry
            if (currDig + carry == 10) {
                resultString.append(0);
                carry = 1;
            } else {
                resultString.append(currDig + carry);
                carry = 0;
            }
        }

        // Check if there is carry on last digit
        if (carry > 0)
            resultString.append(carry);

        return new BigInt(resultString.reverse().toString());
    }

    BigInt minus(BigInt otherNumber){

        // If the other number is negative, add its value
        if (otherNumber.isNegative()) {
            return plus(new BigInt(otherNumber.stringNumber));
        }

        // subtract a bigger number than the current
        if (this.compareTo(otherNumber) < 0) {
            BigInt result = otherNumber.minus(this);
            result.flipNegativity();
            return result;
        }

        // Other number is positive and not greater than current:
        int lengthsDifferences = numberDigits.size() - otherNumber.numberDigits.size();

        StringBuilder resultString = new StringBuilder();

        int carry = 0;

        for (int index = otherNumber.numberDigits.size() - 1; index >=0 ; index--) {
            int biggerNumDig = numberDigits.get(index + lengthsDifferences) - carry;
            int smallerNumDig = otherNumber.numberDigits.get(index);

            carry = 0;

            if (biggerNumDig < smallerNumDig){
                carry = 1;
                biggerNumDig += 10;
            }

            resultString.append(biggerNumDig - smallerNumDig);
        }

        for (int index = lengthsDifferences - 1; index >=0 ; index--) {
            int currDig = numberDigits.get(index);

            // Check if carry is needed
            if (carry > currDig){
                resultString.append(currDig + 10 - carry);
                carry = 1;
            } else {
                resultString.append(currDig - carry);
                carry = 0;
            }
        }

        return new BigInt(resultString.reverse().toString());
    }

    // Multiply bigInt
    BigInt multiply(BigInt otherNumber){

        BigInt finalResult = new BigInt("0");
        BigInt currentUnit = new BigInt("1");

        for (int otherNumIndex = otherNumber.numberDigits.size() - 1; otherNumIndex >=0; otherNumIndex--){
            int currentOtherNumDigit = otherNumber.numberDigits.get(otherNumIndex);

            // Holds the result of multiplication of the number by the current digit of the other number

            BigInt currentResult = new BigInt("0");
            BigInt currentDigitUnit = new BigInt(currentUnit.toString());

            for (int index = numberDigits.size() - 1; index >=0; index--) {
                int currentDigit = numberDigits.get(index);
                int digitsMultiplication = currentDigit * currentOtherNumDigit;

                currentResult = currentDigitUnit.MultiplyUnit(digitsMultiplication);
                currentDigitUnit.multiplyByTen();
            }

            currentUnit.multiplyByTen();
            finalResult = finalResult.plus(currentResult);
        }

        // Check if need to flip negativity
        if (otherNumber.isNegative() && !isNegative() || isNegative() && !otherNumber.isNegative())
            finalResult.flipNegativity();

        return finalResult;
    }

    BigInt divide(BigInt otherNumber) {

        if (isBigIntZero(otherNumber))
            throw new ArithmeticException();

        // Handling the case where the current number is positive and the other is negative
        if (otherNumber.isNegative() && !isNegative()) {
            BigInt result = divide(new BigInt(otherNumber.stringNumber));
            result.flipNegativity();
            return result;

            // Handling the case where the current number is negative and the other is positive
        } else if (!otherNumber.isNegative() && isNegative()) {
            BigInt result = new BigInt(stringNumber).divide(otherNumber);
            result.flipNegativity();
            return result;
        }

        int compareResult = this.compareTo(otherNumber);
        if (compareResult == 0)
            return new BigInt("1");
        else if (compareResult < 0)
            return new BigInt("0");

        BigInt result = new BigInt("0");
        BigInt tempNumber = new BigInt("0");

        while (tempNumber.compareTo(this) < 0) {
            tempNumber = tempNumber.plus(otherNumber);
            result = result.plus(new BigInt("1"));
        }

        return result;

    }

    private boolean isBigIntZero(BigInt number) {
        return number.stringNumber.replace("0", "").equals("");

    }

    // Multiply a unit of BigInt with an integer. Example: 1000000000000000000 * 54
    private BigInt MultiplyUnit(int majorUnits){

        // Setting the string representation
        String majorUnitsString = String.valueOf(majorUnits);
        String newNumber = majorUnitsString + stringNumber.substring(1);

        return new BigInt(newNumber);
    }

    private void multiplyByTen() {
        this.numberDigits.add(0);
        stringNumber += '0';
    }

    @Override
    public int compareTo(BigInt other) {

        // Current is negative, other is positive
        if (isNegative() && !other.isNegative())
            return -1;

            // Current is positive, other is negative
        else if (!isNegative() && other.isNegative()){
            return 1;
        }

        // Both are negative
        else if (isNegative()){
            // Current is negative and has more digits - therefore it is smaller
            if (numberDigits.size() > other.numberDigits.size())
                return -1;
                // Current is negative and has less digits - Therefore it is bigger
            else if (numberDigits.size() < other.numberDigits.size())
                return 1;

                // Both have same number of digits - need to iterate them
            else
                for (int index = 0; index < numberDigits.size(); index++) {

                    // Current has bigger negative digit - therefore it is smaller
                    if (numberDigits.get(index) > other.numberDigits.get(index))
                        return -1;

                        // Current has smaller negative digit - therefore it is smaller
                    else if (numberDigits.get(index) < other.numberDigits.get(index))
                        return 1;
                }

            // If we have reached here, the numbers are completely identical
            return 0;
        }

        // If we have reached here, both numbers are positive

        // Current is positive and has more digits - Therefore it is bigger
        if (numberDigits.size() > other.numberDigits.size()) {
            return 1;
        }

        // Current is positive and has less digits - Therefore it is smaller
        else if (numberDigits.size() < other.numberDigits.size())
            return -1;

            // Both have same number of digits - need to iterate them
        else
            for (int index = 0; index < numberDigits.size(); index++) {

                // Current has bigger positive digit - therefore it is bigger
                if (numberDigits.get(index) > other.numberDigits.get(index))
                    return 1;

                    // Current has smaller positive digit - therefore it is smaller
                else if (numberDigits.get(index) < other.numberDigits.get(index))
                    return -1;
            }

        // If we have reached here, the numbers are completely identical
        return 0;
    }

    @Override
    public boolean equals(Object o) {
        // self check
        if (this == o)
            return true;

        // null check
        if (o == null)
            return false;

        // type check and cast
        if (getClass() != o.getClass())
            return false;

        BigInt other = (BigInt) o;
        // field comparison

        return other.toString().equals(stringNumber);
    }

    @Override
    public String toString() {
        return stringNumber;
    }
}

main


import java.util.Scanner;

public class Main5 {

    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        BigInt firstNumber;
        BigInt secondNumber;

        System.out.println("Enter first number: ");
        firstNumber = inputBigIntNumber();

        System.out.println("Enter second number: ");
        secondNumber = inputBigIntNumber();

        System.out.println("The result of plus is: " + firstNumber.plus(secondNumber));
        System.out.println("The result of minus is: " + firstNumber.minus(secondNumber));
        System.out.println("The result of multiply is: " + firstNumber.multiply(secondNumber));

        try {
            System.out.println("The result of divide is: " + firstNumber.divide(secondNumber));
        } catch (ArithmeticException ex){
            System.out.println("Can not divide by zero");
        }

    }

    // Taking a valid integer input from the user (greater than 0)
    private static BigInt inputBigIntNumber(){

        String str = scanner.nextLine();

        while (true) {
            try {
                return new BigInt(str);
            }
            catch (IllegalArgumentException ex) {
                System.out.println("Invalid number, please try again: ");
            }
        }
    }
}

标签:index,return,number,整数,BigInt,java,numberDigits,otherNumber
From: https://blog.csdn.net/douyh/article/details/137231313

相关文章

  • 代码随想录算法训练营第二十五天(回溯2)|216. 组合总和 III、17. 电话号码的字母组合(JA
    文章目录216.组合总和III解题思路源码17.电话号码的字母组合解题思路源码216.组合总和III找出所有相加之和为n的k个数的组合,且满足下列条件:只使用数字1到9每个数字最多使用一次返回所有可能的有效组合的列表。该列表不能包含相同的组合两次,组合可......
  • 代码随想录算法训练营第二十七天(回溯3)|39. 组合总和、40. 组合总和 II、131. 分割回文
    文章目录39.组合总和解题思路源码40.组合总和II解题思路源码131.分割回文串解题思路源码39.组合总和给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回......
  • JimuReport 积木报表 v1.7.4 正式版本发布,免费的 JAVA 报表工具
    项目介绍一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等!Web版报表设计器,类似于excel操作风格,通过拖拽完成报表设计。秉承“简单、易用、专业”的产品理念,极大的降低报表开发难度、缩短开......
  • Java 实现OCR扫描/识别图片文字
    图片内容一般无法编辑,如果想要读取图片中的文本,我们需要用到OCR工具。本文将介绍如何在Java中实现OCR识别读取图片中的文字。所需工具:IDEASpire.OCRforJava-JavaOCR组件,支持识别多种语言、字体,可读取JPG、PNG、GIF、BMP和TIFF等常用图片中的文本信息。    ......
  • Java 8 新特性:Lambda 表达式、方法引用和 Stream 流
    函数式接口具有单个抽象方法的接口被称为“函数式接口”,函数式接口的实例被称为“函数对象”,表示函数和要采取的动作。六大基础函数式接口:函数式接口名称用途方法Consumer<T>消费型接口操作类型T的对象voidaccept(Tt)Supplier<T>供给型接口返回类型为T......
  • Java:异常处理
    在Java中,异常是程序运行时发生的不正常情况,它们打断了正常的指令流。异常处理是Java语言的一个重要特性,它可以帮助程序员捕获并处理运行时可能出现的错误,从而提高程序的健壮性。以下是Java中异常相关的详细知识:异常类的层次结构Java的异常类都继承自java.lang.Throwable类......
  • 身份证实名认证接口会返回什么?javascript身份核验接口示例
    身份证实名认证接口是通过核验身份证号、姓名、证件头像等一系列的要素信息进行用户身份验证,那么,身份证实名认证接口一般在核验完成后会返回什么参数信息呢?下面翔云API小编为大家答疑解惑!一般情况下,身份核验只会返回一致或者不一致的结果,不一致的情况下会返回那些参数不一致,以翔......
  • 【附源码】JAVA计算机毕业设计智慧外贸平台(springboot+mysql+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在全球经济一体化的时代背景下,智慧外贸平台的建设已成为提升我国外贸竞争力、优化国际贸易环境的关键一环。随着信息技术的迅猛发展,传统的外贸模式已......
  • 【附源码】JAVA计算机毕业设计智慧物流管理系统(springboot+mysql+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息化时代的快速发展,物流行业作为现代经济体系的重要支柱,正面临着前所未有的机遇与挑战。传统的物流管理方式已难以适应现代社会的需求,智能化、......
  • 【附源码】JAVA计算机毕业设计智慧小饭桌(springboot+mysql+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着社会的快速发展和科技的进步,人们对教育的关注和要求也在不断提高。在当今快节奏的生活中,许多家庭面临着孩子午餐难以解决的问题,尤其是对于那些工......