Подтвердить что ты не робот

Изменить решение для использования одного цикла

Я новичок в java. Одна из проблем моего преподавателя заключалась в следующем:

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

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

б. Распечатайте сумму всех целых чисел от 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 петли, с которыми я боролся. но ОДИН ЛОП? Я не знаю, как улучшить код. Пожалуйста, помогите мне.

4b9b3361

Ответ 1

Это проблема 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

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

ИЗМЕНИТЬ:

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

Ответ 2

Это должно сделать это:

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: Лучший способ математики:

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;

}

Ответ 3

Я нашел хорошее решение с потоками 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);
});

Ответ 4

Сделайте один цикл, итератируя весь диапазон, и используйте индексы, чтобы решить, добавлять ли, reset или печатать свои суммы.

Надеюсь, это даст вам правильную идею, если вы все еще не знаете, я могу проиллюстрировать ее немного больше.