简体   繁体   English

Java中long类型的给定正数的所有数字的总和

[英]Sum of all digits for a given Positive Number of type long in Java

I was wondering why the following code solutions based on the modulo operation do not work when moving from the int type to the long type. 我想知道为什么以下基于模运算的代码解决方案在从int类型转换为long类型时不起作用。

For example given 111111111111L I would like to get returned 12L . 例如给定111111111111L我想返回12L

How can I achieve the same expected behaviour described at the following question (that is working only for int type values)? 如何获得以下问题所述的相同预期行为(仅适用于int类型值)? Sum of all digits for a given Positive Number 给定正数的所有数字之和

I am also focused on performance issues so I am looking for an efficient solution. 我也关注性能问题,因此我正在寻找有效的解决方案。

public static long sumTheDigitsVersion1(long inputValue){
    long sum = inputValue % 9L;
        if(sum == 0){
            if(inputValue > 0)
                return 9L;
        }
    return sum;
}

public static long sumTheDigitsVersion2(long inputValue){
    return inputValue - 9L * ((inputValue - 1L) / 9L);
}

Thanks 谢谢

The solution does not work because it's a solution to a different problem, namely: 该解决方案不起作用,因为它是另一个问题的解决方案,即:

repeatedly add up the number's digits until you achieve an single-digit result. 反复将数字的位数相加,直到获得一位数的结果。

In other words, it computes 111111111111 -> 12 -> 3 . 换句话说,它计算111111111111 > 12 > 3

When you think about it, n % 9 cannot possibly return 12 (which is what you say you're expecting). 考虑一下, n % 9可能无法返回12 (这就是您所期望的)。

Recursive, efficient solution: 递归高效的解决方案:

public static long digitSum(long n) {
    if (n == 0)
        return 0;
    return n%10 + digitSum(n/10);
}

About as efficient as you'll get it: 大约和您获得的效率一样:

private static final int PART_SIZE = 1000;
private static final int[] digitSums = new int[PART_SIZE];
static {
    for (int i = 0; i < digitSums.length; i++) {
        for (int n = i; n != 0; n /= 10) digitSums[i] += n % 10;
    }
}

public static long digitSum(long n) {
    int sum = 0;
    do {
        sum += digitSums[(int)(n % PART_SIZE)];
    } while ((n /= PART_SIZE) != 0);
    return sum;
}

This may not be the most efficient option buts its the only one I can think of on the top of my head: 这可能不是最有效的选择,但它是我想到的唯一一个选择:

public static long getDigitalSum(long n){
    n = Math.abs(n); //This is optional, remove if numbers are always positive. NOTE: Does not filter Long.MIN_VALUE

    char[] nums = String.valueOf(n).toCharArray();
    long sum = 0;

    for(char i:nums){
        sum = sum + Integer.parseInt(String.valueOf(i)); //Can use Long.parseLong() too
    }

    return sum;
}

I came out with the following solution after some tests with different numbers comparing 3 different functions involving 3 different approaches: 经过一些不同数量的测试后,我得出了以下解决方案,比较了涉及3种不同方法的3种不同功能:

  • toCharArray() and loops, toCharArray()和循环,
  • basic mathematical computations and loops, 基本的数学计算和循环,
  • recursion. 递归。

I compared the 3 different approaches according to their time dimension using System.nanoTime() . 我使用System.nanoTime()根据时间维度比较了三种不同的方法。

public static long sumTheDigits(long currentIterationValue){

    long currentDigitValue;
    long sumOutputValue = 0;

    while(currentIterationValue != 0) {
        currentDigitValue = currentIterationValue % 10;
        currentIterationValue = currentIterationValue / 10;
        sumOutputValue = sumOutputValue + currentDigitValue;
    }
    return sumOutputValue;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM