计算1^1+2^2+3^3+4^4+5^5+……+20^20 ,不使用BigDecimal。

计算1^1+2^2+3^3+4^4+5^5+……+20^20 ,不使用BigDecimal,不使用math.pow用数组和移位运算。
要求如上,很简单是不是!!!
本宝宝跨专业选了java的课,底子有点弱。
老师布置的作业里就这一条实在是没有思路惹~~~因为星期天就要交呜呜
他大概说了用数组,然后乘法运算,比如19^19=19*19*19*19...... 依次计算往前进一位?
求大神指点!
http://blog.csdn.net/lichong_87/article/details/6860329
好像是按这个里面的方法。

图片说明

图片说明
数组乘法我就不知道了,但是这个本方法应该可以

public class aaa {

public static double tot(int s){
    double n=1;
    switch (s) {
    case 1:

        break;
    case 2:
        n=s*s;
        break;
    case 3:
        n=s*s*s;
        break;
    case 4:
        n=s*s*s*s;
        break;
    case 5:
        n=s*s*s*s*s;
        break;
    case 6:
        n=s*s*s*s*s*s;
        break;
    case 7:
        n=s*s*s*s*s*s*s;
        break;
    case 8:
        n=s*s*s*s*s*s*s*s;
        break;
    case 9:
        n=s*s*s*s*s*s*s*s*s;
        break;
    case 10:
        n=s*s*s*s*s*s*s*s*s*s;
        break;
    case 11:
        n=s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 12:
        n=s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 13:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 14:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 15:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 16:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 17:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 18:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 19:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;
    case 20:
        n=s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s*s;
        break;

    default:
        break;
    }
    return n;
}

public static double sumtot(int ss){
    double sum=0;
    for (int i = 1; i <= ss; i++) {
        double s=tot(i);
        sum+=s;
    }
    return sum;
}

/**
 *【对方法功能进行描述说明】
 *@author   【作者】
 *@param   【参数1 说明】
 *@param   【参数2 说明】
 *@return   【返回值】
 *@since    【版本号】
 *@createTime【时间】
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.out.println(sumtot(20));
}

}

图片说明

@Test
public void run() {
    double rst = a(10);
    System.out.println(rst);
}

public double a(int n){
    double rst = 0;
    for(int i=0; i<n; i++){
        rst += m(i+1);
    }
    return rst;
}

public double m(int a){
    double rst = a;
    for(int i=0; i<a-1; i++){
        rst *= a;
    }
    return rst;
}

使用了数组和移位运算,不过移位是写死的,不知道有没有根据一个数解析出二进制位的通用方法,代码如下:
public static Long getWyLong(){
Long maxLong = 0L;
int [] arr = new int[20];
for(int i=1;i<=20;i++){
arr[i-1] = i;
}

    for(int j=0;j<arr.length;j++){
        Long val = 0L;
        Long base = 0L;
        if(arr[j] != 1){
            String rule = getRule(arr[j]); 
            String [] rules = rule.split("\\|");
            for(int t = 1;t<arr[j];t++){
                Long temp = base ==0 ? (long)arr[j] : base;
                for(int i=0 ;i <rules.length;i++){
                    switch(Integer.parseInt(rules[i])){
                    case 0:
                        val += temp;
                        break;
                    default:
                        val += temp << Integer.parseInt(rules[i]);
                        break;
                    }
                }
                base = val;
                val = 0L;
            }


        }else{
            maxLong += 1;
        }
            maxLong += base;
        }

    return maxLong;
}

public static String getRule(int val){
    String rule = "";
    switch(val){
    case 1:
        rule = "0";
        break;
    case 2:
        rule = "1";
        break;
    case 3:
        rule = "1|0";
        break;
    case 4:
        rule = "2";
        break;
    case 5:
        rule = "2|0";
        break;
    case 6:
        rule = "2|1";
        break;
    case 7:
        rule = "2|1|0";
        break;
    case 8:
        rule = "3";
        break;
    case 9:
        rule = "3|0";
        break;
    case 10:
        rule = "3|1";
        break;
    case 11:
        rule = "3|1|0";
        break;
    case 12:
        rule = "3|2";
        break;
    case 13:
        rule = "3|2|0";
        break;
    case 14:
        rule = "3|2|1";
        break;
    case 15:
        rule = "3|2|1|0";
        break;
    case 16:
        rule = "4";
        break;
    case 17:
        rule = "4|0";
        break;
    case 18:
        rule = "4|1";
        break;
    case 19:
        rule = "4|1|0";
        break;
    case 20:
        rule = "4|2";
        break;
    default:rule = "0";break;
    }
    return rule;
}

计算出来的结果是:1341379291727431088,为毛网上查到的是106876212200059554303215024

int num[20];
int sum=0;
for(int i=0;i<20;i++){
int N=i+1;
num[i]=1;
muliti=i+1;
while(N){
if(N%2==1)
num[i]*=muliti;
muliti*=muliti;
N>>1;
}
sum+=num[i];
}
num[i]存储的是(i+1)的(i+1)次幂,最后求出sum

应该是用快速幂运算吧,降低了时间复杂度,而且用到移位图片

由于计算的数据比较大,long型都不够,所以用了double,一般这种大数题目应该都是要取模的。

 public class Sum {
    public static void main(String[] args){
        double[] num = new double[20];
        int N;
        double muliti,sum=0;
        for(int i=0;i<20;i++){
            N=i+1;
            num[i]=1;
            muliti=i+1;
            while(N>0){
                if(N%2==1)
                    num[i]*=muliti;
                muliti*=muliti;
                N=N>>>1;
            }
            sum+=num[i];
        }
        System.out.println(sum);
    }
}

public class Sum {
public static void main(String[] args){
double sum,subSum = 1;
for(int j = 0; j < 20;j++){
for(int k = 0; k <= j; k++){
subSum = subSum *(J + 1);
}
sum = sum + subSum;
}
System.out.println(sum);
}
}

这道题不难,用数组会非常麻烦,除非对数组操作非常娴熟,其实巧用for循环会让解答过程更简单,工程级的解法是这样。

老衲普渡众生有6行关键代码便可施救施主于水火。望施主在迷茫中深知,苦海无涯,回头是岸。

//老衲这就把数组乘法献上,望施主牢记要诀(重复就是for多用for施主便能以不变应万变)。

public class Sum {
public static void main(String[] args){
double sum = 0,subSum = 1;

double array[20];
for(int a = 1;a < 21 ;a++){
array[a] = a;
}

for(int j = 0; j < 20;j++){
for(int k = 0; k <= j; k++){
subSum = subSum *array[a]
}
sum = sum + subSum;
}
System.out.println(sum);
}
}

老衲之过,请施主将:

subSum = subSum *array[a]

修改成

subSum = subSum *array[j];
就是完整的数组乘法了。

知错能改善莫大焉:以上最终全票通过的另种解法是:

1.for循环

public class Sum {
public static void main(String[] args){
double sum = 0,subSum = 1;

for(int j = 0; j < 20;j++){
subSum = 1;//这行代码是最后的关键代码,老衲的杀手锏。
for(int k = 0; k <= j; k++){
subSum = subSum *(j

  • 1) } sum = sum + subSum; } System.out.println(sum); } } 2数组乘法:

public class Sum {
public static void main(String[] args){
double sum = 0,subSum = 1;

double array[20];
for(int a = 1;a < 21 ;a++){
array[a] = a;
}

for(int j = 0; j < 20;j++){
subSum = 1;//这行代码是最后的关键代码,老衲的杀手锏。
for(int k = 0; k <= j; k++){
subSum = subSum *array[a]
}
sum = sum + subSum;
}
System.out.println(sum);
}
}

施主:总算功德圆满,望施主生活锦上添花,老衲后会有期。

subSum = subSum *(j + 1 ) 改成 subSum = subSum *(j + 1);

subSum = subSum *array[a] 改成 subSum = subSum *array[j];

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

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;  
        int[] result = new int[len];  
        // 计算结果集合  
        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;  
                result[i] %= 10;  
            }  
        }  
        StringBuffer sb = new StringBuffer();  
        // 该字段用于标识是否有前置0,如果是0就不需要打印或者存储下来  
        boolean flag = true;  
        for (int i = len - 1; i >= 0; i--) {  
            if (result[i] == 0 && flag) {  
                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;  
        int[] result = new int[len + 1];  
        for (int i = 0; i < len + 1; i++) {  
            //如果当前的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();  
    }  

}

结果是124267103559737127756824517910134524

实在不行用long试试
public long getSumNum(int n){
long sum=0;
for(int i=1;i<=n;i++){
long column=1;
for(int j=1;j<=n;j++){
column*=n;
}
sum+=column;
}
return sum;
}

虽然很久了,但还是要发一下
注意:用string那个是错的,string也不适合运算
System.out.println(1 + 2 * 2 + 3 * 3 * 3 + 4 * 4 * 4 * 4 + 5 * 5 * 5 * 5 * 5 + 6 * 6 * 6 * 6 * 6 * 6);
是50069
自己可以验证一下
具体实现已发博文:https://blog.csdn.net/weimingjue/article/details/101760480