2013-08-25 60 views
1

我想知道爲什麼當從int類型移動到long類型時,基於模運算的以下代碼解決方案爲什麼不起作用。給定正數在Java中類型長的所有數字的總和

例如給出111111111111L我想返回12L

我該如何實現在下面的問題中描述的相同的預期行爲(這隻適用於int類型值)? Sum of all digits for a given Positive Number

我也專注於性能問題,所以我正在尋找一個有效的解決方案。

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); 
} 

感謝

+0

不要依賴異地資源在您的問題。如果你喜歡,可以鏈接它們,但總是引用你問題中的相關位。 –

+0

爲什麼你會期望'12'作爲輸出。你連接的這個問題,找到[數字根](http://en.wikipedia.org/wiki/Digital_root),通過總和數字減少數字,直到你得到一個數字。所以,對於'12',它會再次被減少到'1 + 2 = 3'。 –

+0

@dasblinkenlight。 '111111111111L'可以被認爲是小數? –

回答

1

我經過一些不同數目的測試後出來以下解決方案š比較涉及3種不同的方法3個不同的功能:

  • toCharArray()和循環,
  • 基本的數學計算和循環,
  • 遞歸。

我根據他們的時間維度使用System.nanoTime()比較了3種不同的方法。

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; 
} 
3

的解決方案不起作用,因爲它是一個不同的問題的解決方案,即:

反覆加起來數量的數字,直到你實現個位數的結果。

換句話說,它計算111111111111 - >12 - >3

當你考慮它時,n % 9不可能返回12(這就是你所說的你期望的)。

+0

好吧,我很困惑2個不同的問題,謝謝你突出顯示它。現在我仍然試圖找出哪個是解決問題的最有效的方法,例如,給出這個輸入「111111111111」,我想得到其數字的總和,即「12」。 – TPPZ

1

這可能不是最有效的選擇的擊打它,我可以在我的頭頂想到的只有一個:

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; 
} 
+0

請注意'n = Long.MIN_VALUE'的'Math.abs(n)== n'。最好跳過'-'字符,或者簡單地用'IllegalArgumentException'拒絕負面輸入。 – Boann

+0

@Boann好吧......我不知道。我在想,因爲他想要高效率,每個角色運行if語句可能會非常糟糕。謝謝(你的)信息! – initramfs

+0

無論如何,這實際上是效率最低的可能解決方案,所以... – Boann

2

遞歸,高效的解決方案:

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

只有當JVM可以將它變成一個循環時它纔有效,它可能不會。 – Boann

2

關於高效你會得到它:

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; 
} 
相關問題