计算1^1+2^2+3^3+4^4+5^5+……+20^20 ,大数运算(加,乘)java实现

这个题目是明显的大数运算,不能直接使用int long double 早就超出范围了,要用数组结合字符串进行处理,分别实现大数的加法和乘法,

然后使用实现的加法和乘法写出来n的n次幂的实现,最后 把它们加起来

首先存进来就是要用string来存贮,运算的时候按位运算,charAt(i)-'0'来取值。

注意一点,string改成char[]数组的时候要变成反序操作,因为对于一个数组是要从左到右,相加放值的,所以我们也要从左向右操作,所以原数值要逆序存放,运算结束后,再逆序回来。

//计算1^1+2^2+3^3+4^4+5^5+……+20^20  
public class Main1 {  
  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
               
             String sum = "0";  
             //进行循环20次 从1的1次方 加到20的20次方  
               
            for(int i = 1;i<21;i++)  
            {  
                 sum = bigNumberAdd(sum, NCiOfN(i));  
            }  
            System.out.println(sum);  
    }  
  
     //这里实现 n的n次幂  
    public static String NCiOfN(int n)  
    {  
        String result = "1";  
        String value = String.valueOf(n);  
        for(int i=0;i<n;i++)  
        {  
             result = bigNumberSimpleMulti(result,value);  
        }  
        return result;  
    }  
      
    //这里用数组实现大数的相乘运算  
    public static String bigNumberSimpleMulti(String f, String s) {    
       // System.out.print("乘法:\n" + f + "*" + s + "=");    
        // 获取首字符,判断是否是符号位    
        char signA = f.charAt(0);    
        char signB = s.charAt(0);    
        char sign = '+';    
        if (signA == '+' || signA == '-') {    
            sign = signA;    
            f = f.substring(1);    
        }    
        if (signB == '+' || signB == '-') {    
            if (sign == signB) {    
                sign = '+';    
            } else {    
                sign = '-';    
            }    
            s = s.substring(1);    
        }    
        // 将大数翻转并转换成字符数组    
        char[] a = new StringBuffer(f).reverse().toString().toCharArray();    
        char[] b = new StringBuffer(s).reverse().toString().toCharArray();    
        int lenA = a.length;    
        int lenB = b.length;    
        // 计算最终的最大长度    
        int len = lenA + lenB;     //两个数相乘之后的最大位数不会超过原来两个数的长度之和,两数相加之后的最大位数是,最长的原数长度+1,见下
        int[] result = new int[len];     //用一个int数组按位存放结果(逆序的)
        // 计算结果集合    
        for (int i = 0; i < a.length; i++) {    
            for (int j = 0; j < b.length; j++) {    
                result[i + j] += (int) (a[i] - '0') * (int) (b[j] - '0');    //先将结果数组中所有位直接求值,进位之后再处理    
            }    
        }    
        // 处理结果集合,如果是大于10的就向前一位进位,本身进行除10取余    
        for (int i = 0; i < result.length; i++) {         //开始从头开始处理每一位结果
            if (result[i] > 10) {    
                result[i + 1] += result[i] / 10;    //从0位开始,i+1位放入i的进位
                result[i] %= 10;    //i只保留余数,这样结果数组肯定会继续变长,没关系就继续这样算就行,自己写到不用再进位
            }    
        }    
        StringBuffer sb = new StringBuffer();    
        // 该字段用于标识是否有前置0,如果是0就不需要打印或者存储下来    
        boolean flag = true;    
        for (int i = len - 1; i >= 0; i--) {    
            if (result[i] == 0 && flag) {      //数组后端的0有几位
                continue;    
            } else {    
                flag = false;    
            }    
            sb.append(result[i]);    
        }    
        if (!sb.toString().equals("")) {    
            if (sign == '-') {    //最开始提取的正负号,直接加入到结果的开头
                sb.insert(0, sign);    
            }    
        } else {    
            sb.append(0);    
        }    
        // 返回最终结果    
      //  System.out.println(sb.toString());    
        return sb.toString();  
    }    
      
  //这里实现大数的相加运算  
    public static String bigNumberAdd(String f, String s) {    
        //翻转两个字符串,并转换成数组    
        char[] a = new StringBuffer(f).reverse().toString().toCharArray();    
        char[] b = new StringBuffer(s).reverse().toString().toCharArray();    
        int lenA = a.length;    
        int lenB = b.length;    
        //计算两个长字符串中的较长字符串的长度    
        int len = lenA > lenB ? lenA : lenB;    //两数相加之后的最大长度,为最长的元数据长度+1,区别于相乘
        int[] result = new int[len + 1];    
        for (int i = 0; i < len + 1; i++) {    //还是先正常算出每一位的,不带进位操作的值
            //如果短的数到头了,就用0代替,和另一个字符数组中的数字相加    
            int aint = i < lenA ? (a[i] - '0') : 0;    
            int bint = i < lenB ? (b[i] - '0') : 0;    
            result[i] = aint + bint;    
        }    
        //处理结果集合,如果大于10的就向前一位进位,本身进行除10取余    
        for (int i = 0; i < result.length; i++) {        //再从头处理一遍进位的操作
            if (result[i] > 10) {    
                result[i + 1] += result[i] / 10;    
                result[i] %= 10;    
            }    
        }    
        StringBuffer sb = new StringBuffer();    
        //该字段用于标识是否有前置0,如果有就不要存储    
        boolean flag = true;    
        for (int i = len; i >= 0; i--) {    
            if (result[i] == 0 && flag) {    
                continue;    
            } else {    
                flag = false;    
            }    
            sb.append(result[i]);    
        }    
        return sb.toString();    
    }    
      
}  

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值