2016-11-11 5 views
13

Я новичок в java. Одна из проблем, с моего лектора был:Изменить решение для использования одного цикла

  1. Учитывая диапазон от 1 до некоторого заданного максимального целого числа п, которое должно быть кратны некоторым заданным целым числом д, то:

а. Распечатайте сумму каждой партии чисел q; и

b. Вывести сумму всех целых чисел от 1 до последнего числа в этой партии

Пример: Для п = 1000 и д = 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

Просто некоторые Math, чтобы найти сумму от 1 до X, нет необходимости в цикле, 'X * (X + 1)/2' будет делать i t;) – AxelH

+2

Спасибо, что на самом деле показывали нам некоторые из ваших собственных работ, а не отправляли только тот вопрос, который дал вам лектор. Мы не видим слишком часто здесь :) –

+0

@AxeIH вы можете использовать его? , Я вынужден использовать ОДИН цикл. –

ответ

12

Это проблема Mathematic.

Если вы знаете, что вы можете найти сумму всех целых чисел от 1 до X, вам просто нужно сделать 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 в n приращением по q

и быстрый код для сделайте это:

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

Примечание: Решение является быстрой реализацией, это можно сделать лучше.

EDIT:

Благодаря Маргарет Блум в комментариях, чтобы указать на имя этой формулы :) Для получения дополнительной информации Вы можете посмотреть на Triangular Number

+0

AleIH вы могли бы использовать один цикл? , Я вынужден использовать ОДИН цикл. –

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

} 

Edit: Лучший способ Math:

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

Не должен ли он быть сверху + 1 вместо вершины - 1? – MikeMB

2

Я нашел хорошее решение с java8 Streams:

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, это хорошее решение? :) – user6904265

 Смежные вопросы

  • Нет связанных вопросов^_^