文章目录

  • 1.高精度的加法
  • 2.高精度的减法
  • 3.高精度的乘法


实际上高精度就是说参与运算的数据和运算结果的范围,超出标准数据类型能表示的数据大小范围的运算下面的算法只能满足于正整数的运算,不能是负号、小数等

1.高精度的加法

方法一:
1、输入两个字符串,表示即将要进行加法运算的数,之所以是字符串,是因为有可能要输入的数字要很多位数字,从而超出了数据类型的范围。
2、定义一个数组来表示结果,其中这个数组的长度是两个字符串中的长度最大值max还要大1,比如888和222相加,那么得到的结果就是1110,结果长度为4,比两个字符串的长度的最大值3还要大1。
3、从右到左开始遍历字符串,从而首先将个位的数字相加,然后到十位、百位、千位等。
4、在遍历字符串的时候,将每一个数位上的数字进行相加,从而得到他们的和total,然后要将total和10进行比较,如果total大于等于10,那么需要进1,那么此时需要在定义一个变量con表示是否要进位,如果con为0,那么不需要进位,如果为1,那么就进1位,在下一次的运算的时候就需要加上con。,同时将结果total %=10,比如123+27 = 150,那么将个位进行运算时一开始total = 10,此时大于等于10了,那么要进1,然后进行取模,从而得到了个位上的数位0。
5、注意考虑到了两个字符串的长度不同的情况,那么将**没有遍历完的字符串继续遍历,将其每一位数字都要加上进位,**因为在完成步骤4的时候,进位con可能是1,所以需要加上进位,有人会问是不是只要加上进位con1次就可以了呢?答案是否定的,因为有可能在加上con进位之后,它的和也是大于等于10,所以没有遍历玩的每一个数字都需要考虑是否要进位。比如运算99999+ 1 = 100000,从而验证了上面的说法。

代码实现:

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        int len ,len2;
        len = str1.length();
        len2 = str2.length();
        int max = len > len2? len : len2;//获取两个字符串的最长长度
        String[] result = new String[max + 1];//表示两个字符串进行加法之后的结果,其中结果的长度要比max大1
        getAddCount(result,str1,str2,len,len2);//高精度加法
        for(String a:result)
            if( a!= null)//这一步必须要的,因为有可能会出现有一个字符为null的情况,比如188 + 3,那么result的数组的长度为4,而运算结果只要3为数,有了这一步,就避免了输出null,从而导致错误
                System.out.print(a);
        System.out.println();
    }
    /**
     * 高精度的加法
     * @param string  结果的字符串
     * @param str1  字符串1
     * @param str2  字符串2,这两个字符串表示的是进行运算的两个字符产
     * @param len1  字符串1的长度
     * @param len2  字符串2的长度
     */
    public static void getAddCount(String[] string, String str1,String str2,int len1,int len2){
        int i = len1 - 1,j = len2 - 1;
        int index = string.length;
        int con = 0;//表示进位,一开始没有进行运算,那么初始化为0
        //从右到左开始遍历,从而首先开始计算个位上的结果,然后是十位、百位、千位~~~~
        while(i >= 0 && j >= 0){
            //当两个字符串都没有遍历完的时候
            int num1 = Integer.parseInt(str1.substring(i,i+1));//将每一个数位上的数字转换成整形,然后进行相加
            int num2 = Integer.parseInt(str2.substring(j,j+1));
            int total = num1 + num2 + con;//这一步十分重要,因为考虑到最后两个数的和如果大于10,那么这两个数的前面要加上这个进位,所以每次进行相加的时候都要加上进位
            con = total >= 10 ? 1:0; //将两个数进行相加,然后将两个数的和和10进行比较,如果大于等于10,那么进位为1,否则为0,然后他们的和要%10
            total %= 10;
            String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
            string[--index] = num;//因为从右到左开始遍历,那么先计算的是个位上的结果,所以将结果放在string数组后面,然后前移
            i--;//将两个字符串前移
            j--;
        }
        //如果字符串1没有遍历完,而字符串2已经遍历完了,那么将字符串1剩余的数字压入字符串数组中
        while(i >= 0){
            int num1 = Integer.parseInt(str1.substring(i,i+1));
            int total = num1 + con;//如果上面的操作中con不为0,而是1,所以要加上进位,所以在此考虑total是否大于等于10,如果是,那么con为1
            con = total >= 10 ? 1:0; 
            total %= 10;
            String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
            string[--index] = num;
            i--;
        }
        //如果字符串2没有遍历完,而字符串1已经遍历完了,那么将字符串2剩余的数字压入字符串数组中
        while(j >= 0){
            int num1 = Integer.parseInt(str2.substring(j,j+1));
            int total = num1 + con;//如果上面的操作中con不为0,而是1,所以要加上进位,所以在此考虑total是否大于等于10,如果是,那么con为1
            con = total >= 10 ? 1:0; 
            total %= 10;
            String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
            string[--index] = num;
            j--;
        }
        //注意这种情况最关键了,如果到最后con还是为1,那么就将这个con储存到字符串数组中,比如222+888,那么最后结果是1110,所以string的第一个字符就是con,表示最高位
        if(con != 0)
            string[0] = String.valueOf(con);
    }
}

当然也可以先将两个字符串进行比较,如果字符串1小于字符串2,那么就将两者进行交换,从而保证了字符串1是最大的,那么字符串2遍历完以后,只要考虑字符串1是否还有一些数字剩余,然后再将剩余的字符添加到字符串数组中

字符串1: 2222222222
字符串2:8888
经过比较后,字符串1是最大的,那么再遍历完字符串2以后,就将字符串1剩余的字符插入到字符串数组中。

字符串1: 8888
字符串2: 2222222222
那么如果不比较,那么就要按照上面代码的步骤,当字符串遍历完以后,还要比较字符串1是否已经遍历完,然后再判断字符串2是否已经遍历完。所以为避免麻烦,这里将两者进行比较,然后将两者进行交换,从而
字符串1: 2222222222
字符串2: 8888
然后最后只要判断字符串1是否已经遍历完了,如果没有,就将剩余的字符插入到字符串数组中

有人看了下面的代码,可能会问比较字符串,不是有方法compareTo吗?为什么还要新建一个方法呢?其实之前我也是这样的,但是后来发现是不对的。这里插入一下compareTo的代码:

public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

通过上面的代码我对于compareTo的理解是,compareTo方法是从左到右开始开始遍历两个字符串,如果字符相同,就继续遍历,否则,如果字符不同,那么就返回这两者的ASCII码差值(应该是ASCII码吧,不太确定,如果错误的,请大家指正),如果大于0,那么说明字符串1大于字符串2,如果小于0,就说明字符串2大,等于0说明相等

下面是一些例子,通过这些例子我们就可以知道了一些错误了。
字符串1: 99999
字符串2:222222222222
那么如果调用方法compareTo,那么从左到右开始遍历,第一个字符没有相同,返回‘9’ - ‘2’ ,差值是大于0的,此时就说明了字符串1大于字符串2,但是实际是字符串1小于字符串2,所以这里不可以调用方法compareTo,而是新建一个方法进行比较

package myStructucreTest;

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        int len ,len2;
        len = str1.length();
        len2 = str2.length();
        int max = len > len2? len : len2;//获取两个字符串的最长长度
        String[] result = new String[max + 1];//表示两个字符串进行加法之后的结果,其中结果的长度要比max大1
        getAddCount(result,str1,str2);//进行高精度运算---加法
        System.out.print(str1 +" + " + str2 +"的运算结果为: ");
        for(String a:result)//遍历字符串数组,将结果输出
            if( a!= null)//这一步必须要的,因为有可能会出现有一个字符为null的情况,比如188 + 3,那么result的数组的长度为4,而运算结果只要3为数,有了这一步,就避免了输出null,从而导致错误
                System.out.print(a);
        System.out.println();
    }
    /**
    *将两个字符串进行比较
    */
     public static boolean compare(String str1,String str2){
         boolean con = true;//假设str1大于等于str2
         if(str1.length() > str2.length())
             return true;//如果字符串1的长度大于字符串2的长度,说明字符串1大于字符串2,返回true
         else if(str1.length() < str2.length())
             return false;//如果字符串1的长度小于字符串2的长度,说明字符串1小于字符串2,返回false
         else if(str1.compareTo(str2) < 0)
             return false;//在字符串长度相等的情况下,通过调用compareTo方法,如果返回的是小于0的数,那么说明str1小于str2,返回false,否则返回true
         else
             return true;
     }
    /**
     * 高精度的加法
     * @param string  结果的字符串
     * @param str1  字符串1
     * @param str2  字符串2,这两个字符串表示的是进行运算的两个字符产
     */
    public static void getAddCount(String[] string, String str1,String str2){
        if(!compare(str1,str2)){
            //调用方法compare,从而将两个字符串进行比较,如果返回的是true,那么说明了str1大于等于str2,否则小于str2,此时那么将两者互换
            String t = str1;
            str1 = str2;
            str2 = t;
        }
        int i = str1.length() - 1,j = str2.length() - 1;
        int index = string.length;
        int con = 0;//表示进位
        while(i >= 0 && j >= 0){
            //当两个没有遍历完的时候
            int num1 = Integer.parseInt(str1.substring(i,i+1));//将每一个数位上的数字转换成整形,然后进行相加
            int num2 = Integer.parseInt(str2.substring(j,j+1));
            int total = num1 + num2 + con;//这一步十分重要,因为考虑到最后两个数的和如果大于10,那么这两个数的前面要加上这个进位,所以每次进行相加的时候都要加上进位
            con = total >= 10 ? 1:0; //将两个数进行相加,然后将两个数的和进行比较,如果大于10,那么进位为1,否则为0,然后他们的和要%10
            total %= 10;
            String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
            string[--index] = num;
            i--;//将两个字符串前移
            j--;
        }
        //因为经过了比较,那么这时候两个字符串中字符串1是最大的数,那么这时候只要判断字符串1是否已经遍历完即可,如果没有遍历完,就将剩余的字符存放到字符串数组
        while(i >= 0){
            int num1 = Integer.parseInt(str1.substring(i,i+1));
            int total = num1 + con;
            con = total >= 10 ? 1:0; //将两个数进行相加,然后将两个数的和进行比较,如果大于10,那么进位为1,否则为0,然后他们的和要%10
            total %= 10;
            String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
            string[--index] = num;
            i--;
        }
        //注意这种情况最关键了,如果到最后con还是为1,那么就将这个con储存到字符串数组中
        if(con != 0)
            string[0] = String.valueOf(con);
    }
}

上面的代码显得太麻烦了,通过参考其他大佬的代码,觉得更加简便了。

方法二:

1、输入两个字符串,表示要进行运算的两个数字。然后分别获得他们的长度,从而可以更好地将他们的倒序存放到两个整形数组中。

1、定义两个整形数组,首先是用来存储两个字符串的倒序的,从而就可以从左到右遍历两个整形数组进行运算了,其次其中的一个数组用来存储两个字符串运算后的结果

2、从左到右遍历整形数组,从而实现将字符串倒序存放到整形数组的中。

java 中加法运算 java加法计算_数组


3、实现步骤2之后,从左到右遍历两个数组,然后将对应下标的值进行相加,获得他们的和total,然后判断他们的和是否大于等于10,如果是,那么获得进位total / 10,然后其中一个用来存放结果的数组后一个下标的值加上进位,那么就将total %= 10,重复步骤3,直到所有的数组都遍历完了。

4、完成操作3之后,从右到左遍历存放结果的数组,但有一点需要注意的是最高位是0的情况

代码:

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        int len ,len2;
        len = str1.length();
        len2 = str2.length();
        int max = len > len2? len : len2;//获取两个字符串的最长长度
        int[] arr1 = new int[250];
        int[] arr2 = new int[250];//将两个字符串的倒序储存到数组中
        for(int i = 0; i<len; i++){
            arr1[i] = Integer.parseInt(str1.substring(len - i - 1,len - i));//将字符串1倒序的字符赋给数组
        }
        for(int i = 0; i<len2; i++){
            arr2[i] = Integer.parseInt(str2.substring(len2 - i - 1,len2 - i));//将字符串2倒序的字符赋给数组
        }
        for(int i = 0; i<max; i++){
            arr1[i] += arr2[i];//将两个字符串的每一个数位上的数进行相加
            arr1[i + 1] += arr1[i] / 10;//获取进位,当i = max - 1的时候,那么max + 1 = max
            arr1[i] %= 10;//如果arr1[i]大于等于10,那么将1进位之后,就是小于10的了,所以要%10
        }
        while(arr1[max] == 0 && max >= 1){//去除最高位为0的数
            max --;
        }
        for(int i = max; i>=0;i--)
            System.out.print(arr1[i]);
        System.out.println();
    }
 }

方法三:
基本思路:
1、对两个字符串a,b进行遍历,不过注意的遍历的条件是两个字符串中长度最长的,因此为了不进行比较两个字符串的长度大小,因此如果从i = 0开始遍历,那么这里的循环条件是i < a.length() || i < b.length()
2、在每一次的循环中,都要将字符串的最后的数字进行加法运算,因为是从i = 0开始遍历的,因此最后的字符的下标为a.length() - i - 1,b.length() - i - 1。将得到的结果用carry来表示。
3、将结果放到一个StringBuilder中的时候,必须要将carry % 10,因为有可能carry大于等于10,如果没有将carry%10,那么就有可能导致结果的错误。
4、最后还要将carry / 10,从而表示进1。通过2、3、4步可以发现,carry这个变量既充当了运算的结果,同时充当了进位
5、重复2、3、4步,知道两个字符串都已经遍历完了。
6、这一步至关重要,因为如果当两个字符串都已经遍历完了,但是进位carry还是大于0或者说等于1,那么就要将这个进位添加到StringBuilder这个变量中
7、调用StringBuilder的reverse方法,从而将结果倒序,从而得到正确的结果。

public class AddTest {
     public static void main(String[] args) {
    	 Scanner sc = new Scanner(System.in);
    	 //输入两个数字字符的字符串,从而进行高精度运算
    	 String a = sc.next();
    	 String b = sc.next();
    	 StringBuilder sb = new StringBuilder();//新建一个StringBuilder ,从而用于存放最后的结果
    	 int carry = 0;
    	 //遍历两个字符串,注意的是有可能两者的长度是不一样的情况,因此判断条件用||
    	 for(int i = 0; i < a.length() || i < b.length(); i++) {
    		 //进行运算之前必须要判断a/b是否已经遍历完了,如果遍历完了,那么就相当于加0
    		 carry += i < a.length() ? a.charAt(a.length() - i - 1) - '0' : 0;
    		 carry += i < b.length() ? b.charAt(b.length() - i - 1) - '0' : 0;
    		 sb.append(carry % 10 + "");//将结果添加到字符串中,不过不是carry,而应该是carry % 10,因为有可能carry大于等于10
    		 carry /=  10;//这一步十分的重要,因为如果两个数的和大于2,那么就要进1,此时就要/2
    	 }
    	 if(carry == 1) {
    		 //如果两个字符串都已经遍历完了,并且进位还是大于0的,那么还要将这个进位添加
    		 sb.append(carry);
    	 }
    	 //将字符串倒转,从而得到运算结果
    	 String str = sb.reverse().toString();
    	 System.out.println(a +" + " + b +" = " + str);
     }
}

2.高精度的减法

高精度的减法的思路:
1、准备工作:两个字符串,表示即将要进行运算的两个数字;然后新建一个字符串数组,用来存放每一个数位上的数字进行运算后的结果,这个字符串数组的长度是两个字符串最大长度max + 1,因为考虑到负号的存在(两个数进行运算,有可能结果是一个负数);定义一个变量,表示借位con

2、比较两个字符串的大小,如果字符串1小于字符串2,那么两者进行交换,从而保证了字符串1是最大的。为什么要比较呢?这里的道理和上面的道理是不一样的,因为相减的情况不同,那么运算也就不同。
比如
字符串1:999
字符串2:222
此时字符串1大于字符串2,所以按照通常的运算来计算,如果字符串1(被减数)的数位的数小于字符串2(减数)的对应数位上的数字,那么就要向前面的数字借1,从而得到结果。

字符串1:222
字符串2:999
两者相减,并没有像上面的情况一样,如果字符串1(被减数)的数位上的数字小于字符串2(减数)对应数位上的数字,就要像前面借1,相反,他们的结果是字符串2-字符串1的结果的相反数,所以需要将两个字符串进行交换以后,进行运算,结果的相反数就是所求的。

3、从右到左开始遍历,因为最先开始计算的是个位,然后是十位、百位~~~,如果他们的差小于0,那么就要向前面借位,然后再次计算他们的结果。将对应的数位上的数字进行相减,得到他们的差total,如果他们的差total小于0,那么说明了字符串1(被减数)对应数位上的数字小于字符串2(减数)对应数位上的数字,那么就将字符串1当前的数位向前面的数字借1,然后将他们的差加上10就是正确的运算结果,同时将标记借位
比如22 - 8,从右到左开始遍历,total = 2 - 8 = -6,那么小于0,2向前面借1,从而将total += 10 ----total = 4,运算是正确的。

4、将他们的运算结果存放到字符串数组中,然后重复操作3,直到字符串2已经遍历完了(因为字符串2是两者中最小的)。

5、当字符串2已经遍历完以后,判断字符串1是否已经遍历完了,如果没有,那么将剩余的字符插入到字符串数组中,此时并不能直接插入,要考虑到借位是否为0,如果不为0,那么还要将这个借位减去呢

代码:

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        int len ,len2;
        len = str1.length();
        len2 = str2.length();
        int max = len > len2? len : len2;//获取两个字符串的最长长度
        String[] result1 = new String[max + 1];//表示两个字符串进行减法之后的结果,其中结果的长度要比max 大1,比如222 - 999 = -777,考虑到负号的存在
        gerDividCount(result1,str1,str2);//进行高精度的运算---减法
        System.out.print(str1 +" - " + str2 +"的运算结果为: ");
        for(String a:result1)
            if( a!= null)//这一步必须要的,因为有可能会出现有一个字符为null的情况,999 - 222的结果是777 ,如果没有这一步,那么字符串数组result的长度为4,那么有一个为null,从而导致错误
                System.out.print(a);
        System.out.println();
    }

    /**
     * 进行高精度的减法:
     * 思路:
     * 1)先比较两个数字的大小,如果减数小于被减数,那么得到的结果是被减数减于减数的差的相反数,比如222-999 的结果是 999 - 222= 777 的相反数-777
     * 2)定义一个变量,表示是否减数小于被减数,如果是,那么到最后的时候,将符号押入到字符串数组,否则就不用
     * 2)进行调整之后,那么就将进行运算,将从右到左进行运算,然后将每一个数位上的数字相减,得到的结果为负数,那么就要借位
     * @param string    获取结果的字符串数组
     * @param str1      进行运算的字符串1
     * @param str2      进行运算的字符串2
     */
     public static void gerDividCount(String[] string,String str1,String str2){
         boolean flag = true;//标记字符串str1是否大于字符串str2,如果是就为true,否则为false
         if(!compare(str1,str2)){
             //调用方法compare,从而将两个字符串进行比较,如果返回的是true,那么说明了str1大于等于str2,否则小于str2,此时那么将两者互换,同时将flag变为false,说明str1小于str2
             String t = str1;
             str1 = str2;
             str2 = t;
             flag = false;
         }
         int i = str1.length() - 1,j = str2.length() - 1;
         int index = string.length;
         int con = 0;//表示借位
         while(i >= 0 && j >= 0){
             //当两个字符串没有遍历完的时侯
             int num1 = Integer.parseInt(str1.substring(i,i+1));//将每一个数位上的数字转换成整形,然后进行相减
             int num2 = Integer.parseInt(str2.substring(j,j+1));
             int total = num1 - num2 + con;//这一步十分重要,因为考虑到最后两个数的差如果小于0,那么这两个数的前面要像减的时候还要减1,所以每次进行相减的时候都要加上借位
             if(total < 0) {
                 total +=10;//如果他们的差小于0,那么在原来的基础上加10
                 con = -1;//为-1表示向前面借1了
             }else{
                 con = 0;//为0表示没有向前面借1
             }
             String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
             string[--index] = num;
             i--;//将两个字符串前移
             j--;
         }
         //由于字符串1是最大的,那么这时候就不用在考虑字符串2没有遍历完的情况了,只要考虑字符串1有没有遍历完即可
         while(i >= 0){
             int num1 = Integer.parseInt(str1.substring(i,i+1));
             int total = num1 + con;
             if(total < 0) {
                 total +=  10;
                 con = -1;
             }else{
                 con = 0;
             }
             String num = String.valueOf(total);//将结果转化成为字符串的类型,然后将其存储再字符串数组中
             string[--index] = num;
             i--;
         }
         if(flag != true)//如果原来的str1小于str2,运算结果为str2 - str1的相反数,所以flag为false在最高位前面加上负号
             string[0] = "-";
     }
     public static boolean compare(String str1,String str2){
         boolean con = true;//假设str1大于等于str2
         if(str1.length() > str2.length())
             return true;//如果字符串1的长度大于字符串2的长度,说明字符串1大于字符串2,返回true
         else if(str1.length() < str2.length())
             return false;//如果字符串1的长度小于字符串2的长度,说明字符串1小于字符串2,返回false
         else if(str1.compareTo(str2) < 0)
             return false;//在字符串长度相等的情况下,通过调用compareTo方法,如果返回的是小于0的数,那么说明str1小于str2,返回false,否则返回true
         else
             return true;
     }
}

通过两个数组来实现高精度的减法代码:

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        System.out.print(str1 +" - " + str2 +"的运算结果为: ");
        getDividCount2(str1,str2);
    }
    
     public static boolean compare(String str1,String str2){
         boolean con = true;//假设str1大于等于str2
         if(str1.length() > str2.length())
             return true;//如果字符串1的长度大于字符串2的长度,说明字符串1大于字符串2,返回true
         else if(str1.length() < str2.length())
             return false;//如果字符串1的长度小于字符串2的长度,说明字符串1小于字符串2,返回false
         else if(str1.compareTo(str2) < 0)
             return false;//在字符串长度相等的情况下,通过调用compareTo方法,如果返回的是小于0的数,那么说明str1小于str2,返回false,否则返回true
         else
             return true;
     }
     
    /**
     * 高精度的减法---通过两个数组来实现,更简单
     * @param str1
     * @param str2
     */
    public static void getDividCount2(String str1, String str2){
        boolean flag = true;//标记str1是否大于等于str2,如果是,那么为true,否则为false
        if(!compare(str1,str2)){
            //比较两个字符串,如果str1小于str2,那么就进行交换,否则不用进行交换
            String t = str1;
            str1 = str2;
            str2 = t;
            flag = false;
        }
        int len1 = str1.length();
        int len2 = str2.length();
        int max = len1;
        int[] arr = new int[250];
        int[] arr2 = new int[250];//新建两个整形数组,其中一个作用是用来存储字符串的倒序,另一个是长度较大的数组是也是用来存放结果的
        for(int i = 0; i<len1; i++)
            arr[i] = Integer.parseInt(str1.substring(len1 - i - 1, len1 - i));//获取字符串1的倒序
        for(int i = 0; i<len2; i++)
            arr2[i] = Integer.parseInt(str2.substring(len2 - i - 1,len2 - i));//获取字符串2的倒序
        //获取倒序之后,将从左到右开始遍历长度较长的数组,只有这样,才可以将字符串1遍历完,从而得到结果
        for(int i = 0; i<len1; i++){
            arr[i] -= arr2[i];//对应的数字进行相减,然后判断其是否大于0,如果大于0,那么后一个位数字就不用借1,否则要借1
            if(arr[i] < 0){
                arr[i + 1] -= 1;
                arr[i] += 10;//借1之后,在arr[i]的基础上加上10,从而得到arr[i] - arr2[i]数位上的正确结果
            }
        }
        //两个字符串都已经遍历完了之后,将判断最高位是否是小于等于0的数,如果是,那么将其去掉
        while(arr[max] == 0 && max >= 1){
            max--;
        }
        //判断原来的字符串str1是否小于原来的字符串str2,如果是,那么flag为false,那么此时先输出负号,然后再遍历数组
        if(!flag){
            //如果字符串1小于字符串2,那么输出-号在遍历数组arr
            System.out.print("-");
        }
        for(int i = max; i>=0; i--)
            System.out.print(arr[i]);
        System.out.println();
    }
}

3.高精度的乘法

思路:

1、首先对于字符串1,字符串2这两个字符串进行比较,从而保证了字符串1是最大的,从而方便了他们的遍历进行相乘。

java 中加法运算 java加法计算_java 中加法运算_02


2、新建两个整形数组,分别用来存放两个字符串的倒序,这样就可以从左到右遍历两个数组arr,arr2,开始运算个位、十位、百位、千位等数位的运算,同时新建一个整形数组arr3来存放他们的运算结果。因为考虑到两个数位上的数字的乘积大于等于10,那么就将新建一个变量表示进位

3、利用循环嵌套进行遍历,其中外部循环是字符串2(较小的数字)的遍历,内部循环是字符串1(较大的数字)的遍历,从而满足上面的图解。
如果两者的乘积大于等于10,那么就要进位,向前面进1,而他们的乘积变成了原来的乘积模10,即total % 10,并将这个结果存放到数组arr3

4、重复上面的步骤3,直到字符串2已经遍历完了
5、注意最高位对应的下标为len1 + len2 - 1,判断对应的值arr[len 1 + len2 - 1]是否为0,如果为0,那么就要将其去掉,否则就要从这里输出

代码:

/**
 * 学习高精度加法
 * 1、新建一个字符串数组,其中这个字符串数组的长度要大于这两个字符串数组的长度,将结果储存再这个数组中
 * 1、输入得是两个数字字符串
 * 2、然后从右到左遍历两个字符串,将每一个数位的数字进行相加,然后将这两个数字的和压入到数组中,但需要注意的
 * 是,两个数的和可能大于10,所以再定义一个变量,表示进位
 * 3、运算到最后的时候,还需要判断进位是否为0,如果不为0,还要将这个进位储存到字符串数组中,最后遍历这个数组就是两个字符串的结果
 */

package myStructucreTest;

import java.util.Scanner;

public class Count {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();//输入两个数字字符串,表示要进行运算的两个数字
        String str2 = sc.nextLine();
        getMultiply(str1,str2);//调用方法,进行高精度的乘法
    }
    //对字符串1、字符串2进行比较,如果返回false,那么表明字符串1小于字符串2,否则表明字符串1大于等于字符串2
     public static boolean compare(String str1,String str2){
         boolean con = true;//假设str1大于等于str2
         if(str1.length() > str2.length())
             return true;//如果字符串1的长度大于字符串2的长度,说明字符串1大于字符串2,返回true
         else if(str1.length() < str2.length())
             return false;//如果字符串1的长度小于字符串2的长度,说明字符串1小于字符串2,返回false
         else if(str1.compareTo(str2) < 0)
             return false;//在字符串长度相等的情况下,通过调用compareTo方法,如果返回的是小于0的数,那么说明str1小于str2,返回false,否则返回true
         else
             return true;
     }
    /**
     * 进行高精度运算的乘法
     * 思路:
     * 1、将两个字符串进行比较大小,如果字符串1小,那么将两个进行交换,然后将两者的倒序存放到数组中
     * 2、字符串存放完毕之后,利用循环嵌套遍历两个数组,然后将每一个数位上的数字进行相乘,注意有可能两者的
     * 积大于等于10,所以还需要定义一个变量表示进位,然后在下一次的运算中要加上这个进位
     * 3、重复步骤2,直到字符串都已经遍历完了,那么此时可以得到结果了
     * @param str1    表示运算的字符串1
     * @param str2    表示运算的字符串2
     */
    public static void getMultiply(String str1,String str2){
        if(!compare(str1,str2)){
            //调用方法,将两个字符串进行比较,如果字符串1小于字符串2,那么就将两者进行交换
           swap(str1,str2);
        }
        int[] arr = new int[250];//用于存放字符串1
        int[] arr2 = new int[250];//用于存放字符串2
        int[] arr3 = new int[500];//用于存放结果
        int len1 = str1.length(), len2 = str2.length();//两个字符串的长度,从而方便下面两个字符串的遍历
        //调用方法,从而将两个字符串倒序之后存放到两个数组中
        getStringReverse(str1,arr);
        getStringReverse(str2,arr2);
        //遍历两个数组,将每一个数位上的数字相乘,如果得到的积大于等于10,那么就要像前进1,然后 % 10之后才是这个数位上的正确结果
        for(int i = 0; i<len2; i++){
        //外部循环是字符串2的遍历
            for(int j = 0; j<len1; j++){
            //内部循环是字符串1的遍历
                arr3[i + j] += arr2[i] * arr[j];//将每一个数位上的数字进行相乘
                if(arr3[i + j] >= 10){
                    //判断得到的积是否大于等于10,如果是,那么就将向前面进1,同时将这个积模10之后,存放在当前的下标,否则不用
                    int con = arr3[i + j] / 10;//表示进位
                    arr3[i + j + 1] += con;
                    arr3[i + j] %= 10;//运算结果是原来的结果%10
                }
            }
        }
        int max = len1 + len2 - 1;//这里是根据上面的循环遍历中可以直到最高位是len1 + len2 - 1(即当i = len1 - 1,j = len2 - 1,那么arr[i +j]大于等于10时,可以那么这个就是最高位arr3[i + j + 1],从而可以知道最高位下标len1 + len2 - 1
        //去除最高位为0的数字,然后才可以倒序遍历数组3,这样才是正确的结果
        if(arr3[max] == 0){
            max--;
        }
        //遍历数组3(倒序遍历),从而将结果输出
        for(int i = max; i>=0; i--)
            System.out.print(arr3[i]);
        System.out.println();
    }
    //将两个字符串进行交换
    public static void swap(String str1,String str2){
         String t = str1;
         str1 = str2;
         str2 = t;
    }
    //将字符串倒序存放到数组中
    public static void getStringReverse(String string ,int[] arr){
        int len = string.length();
        for(int i = 0; i<len; i++)
            arr[i] = Integer.parseInt(string.substring(len - i - 1, len - i));
    }
}