2016-11-11 46 views
13

我是java中的新手。一個從我的講師的問題是:修改解決方案以使用單個循環

  1. 給定一個範圍從1到一些指定的最大整數n,它必須是整除某個給定的整數Q,則:

一個。打印每批數字q的總和;和

b。打印出所有整數的1之和的最後一個號碼在該批次

示例: 對於n = 1000,Q = 50的程序將輸出:

Sum from 1 to 50: 1275 
Sum from 1 to 50: 1275 
Sum from 51 to 100: 3775 
Sum from 1 to 100: 5050 
Sum from 101 to 150: 6275 
Sum from 1 to 150: 11325 
Sum from 151 to 200: 8775 
Sum from 1 to 200: 20100 
Sum from 201 to 250: 11275 
Sum from 1 to 250: 31375 
Sum from 251 to 300: 13775 
Sum from 1 to 300: 45150 
Sum from 301 to 350: 16275 
Sum from 1 to 350: 61425 
Sum from 351 to 400: 18775 
Sum from 1 to 400: 80200 
Sum from 401 to 450: 21275 
Sum from 1 to 450: 101475 

我設法解決這個問題,下面是我的解決方案:

public class ProblemA001k { 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    int sum1 = 0; 
    int sum2 = 0; 
    int maxN, divQ; 

    Scanner key = new Scanner(System.in); 

    System.out.println("Please enter the maximum value, n"); 
    maxN = key.nextInt(); 

    System.out.println("Please enter the divisor of n, q"); 
    divQ = key.nextInt(); 

    int p, i; 
    int q = divQ; 
    int newQ = 1; 
    for(int j = 0; j < maxN/q; j++) { 

     for(i = newQ; i <= divQ; i++) { 
      sum1 += i; 
     } 
     System.out.println("Sum from " + newQ + " to " + divQ + ":" + sum1); 

     for(p = 1; p <= divQ; p++) { 
      sum2 += p; 
     } 

     System.out.println("Sum from 1" + " to " + divQ + ":" + sum2); 
     System.out.println(); 
     divQ += q; 
     newQ += q; 
     sum1 = 0; 
     sum2 = 0; 
     } 

key.close(); 
} 

}

現在有人告訴我,以便它僅使用一個循環來修改我的解決方案。 我在上面的代碼中有3個循環,即使當我嘗試只使用2個循環時,我掙扎着。但一個循環?我不知道如何改進我的代碼。請幫幫我。

+7

只是一些數學,找到從1到X的總和,不需要循環,'X *(X + 1)/ 2'會做我t;) – AxelH

+2

謝謝你實際向我們展示你自己的一些工作,而不是隻提交講師給你的問題。我們在這裏看不到太多:) –

+0

@AxeIH你能用一個嗎? ,我不得不使用ONE循環。 –

回答

12

這是一個Mathematic問題。

如果你知道你可以找到從1X的所有整數的總和,你只需要做X * (X+1)/2

您可以輕鬆找到所有批次值。

Sum from 1 to 400: 80200 
Sum from 401 to 450: 21275 
Sum from 1 to 450: 101475 

會發現這樣的:

450 * 451/2 = 101475 (1 to 450) 
400 * 401/2 = 80200 (1 to 400) 
101475 - 80200 = 21275 (401 to 450) 

有了這個,你可以通過q

和快速代碼遞增循環纔算值限制從qn做到這一點:

static void sum(int n, int q){ 
    int i = q; 
    int sum, tmp=0; 
    while(i < n){ 
     sum = i * (i+1)/2; 
     System.out.println(String.format("Sum from %d to %d : %d", i-q+1 , i, sum - tmp)); 
     System.out.println(String.format("Sum from %d to %d : %d", 1, i, sum)); 
     tmp = sum; 
     i += q; 
    } 
} 

和我一起

public static void main(String[] args){ 
    sum(500, 50); 
} 

運行產生這樣的結果

Sum from 1 to 50 : 1275 
Sum from 1 to 50 : 1275 
Sum from 51 to 100 : 3775 
Sum from 1 to 100 : 5050 
Sum from 101 to 150 : 6275 
Sum from 1 to 150 : 11325 
Sum from 151 to 200 : 8775 
Sum from 1 to 200 : 20100 
Sum from 201 to 250 : 11275 
Sum from 1 to 250 : 31375 
Sum from 251 to 300 : 13775 
Sum from 1 to 300 : 45150 
Sum from 301 to 350 : 16275 
Sum from 1 to 350 : 61425 
Sum from 351 to 400 : 18775 
Sum from 1 to 400 : 80200 
Sum from 401 to 450 : 21275 
Sum from 1 to 450 : 101475 

該好好想想這個解決方案是循環的數量,這將通過q代替1

注意增加:解決方案是一個快速實施,這可以做得更好。

編輯:

由於瑪格麗特·布魯姆在評論中指出這個公式:)欲瞭解更多信息的名稱,歡迎您來看看Triangular Number

+0

AleIH可以請你用一個循環嗎? ,我不得不使用ONE循環。 –

+0

@NkosieMaphumulo這裏是 – AxelH

+1

雖然正確和專業我不認爲這是OP的正確解決方案。海事組織的練習旨在教導有關變量管理的循環和推理。如果這是真的,這個答案完全沒有提到這一點。 –

1

做一個迭代循環整個範圍並使用索引來決定是否添加,重置或打印您的總和。

希望這會給你正確的想法,如果你還不知道我可以多說明一點。

7

這應做到:

int totalSum = 0; 
int batchSum = 0; 

for (int i = 1; i <= n; i++) { 
    totalSum += i; 
    batchSum += i; 
    if (i % q == 0) { 
     System.out.println("Sum from " + (i - q + 1) + " to " + i + ":" + batchSum); 
     System.out.println("Sum from 1 to " + i + ":" + totalSum); 
     batchSum = 0; 
    } 

} 

編輯: 更好的數學方法:

int lastTotalSum = 0; 
for (int i = 1; i <= n/q; i++) { 
    int top = i * q; 
    int totalSum = top * (top + 1)/2; 
    int batchSum = totalSum - lastTotalSum; 
    System.out.println("Sum from " + (top - q + 1) + " to " + top + ":" + batchSum); 
    System.out.println("Sum from 1 to " + top + ":" + totalSum); 
    lastTotalSum = totalSum; 

} 
+0

謝謝。 :)欣賞它。 –

+0

快樂。希望這是可以理解的。 –

+1

它不應該是top + 1而是top-1嗎? – MikeMB

2

我發現java8流的很好的解決方案:

int n=1000; 
int q=50; 
int length = n/q -1;   
int[] previousSum={0}; 
IntStream.range(0, length).map(i -> (i+1)*q).forEach(s -> { 
    int sum=(s*(s+1))/2; 
    int batch = sum - previousSum[0]; 
    previousSum[0] = sum; 
    System.out.println("Sum from " + (s - q + 1) + " to " + s + ":" + batch); 
    System.out.println("Sum from 1 to " + s + ":" + sum); 
}); 
+2

最初的想法!那麼你在這裏有很多循環(隱藏在Arrays.stream中)。如果你可以在一個流中做到這一點,這將是更好:)仍然2循環(如果你打印這樣的話3)。 – AxelH

+0

是的,即使它不是OP所要求的單個循環,我仍然想要發佈它,因爲這是一個很好的解決方案。感謝您指出這一點。 – user6904265

+0

我有時間在java8 Streams的「唯一一個循環」解決方案上工作,這個解決方案很好嗎? :) – user6904265