Самый простой способ рассчитать количество четных чисел в заданном диапазоне

Каков самый простой способ вычисления количества четных чисел в диапазоне целых чисел без знака?

Пример: если диапазон равен [0... 4], тогда ответ равен 3 (0,2,4)

Мне сложно найти какой-либо простой способ. Единственное решение, с которым я столкнулся, включало пару if-утверждений. Есть ли простая строка кода, которая может делать это без if-операторов или тройных операторов?

Ответы

Ответ 1

int even = (0 == begin % 2) ? (end - begin) / 2 + 1 : (end - begin + 1) / 2;

Что можно преобразовать в:

int even = (end - begin + (begin % 2)) / 2 + (1 - (begin % 2));

EDIT: Это может быть дополнительно упрощено:

int even = (end - begin + 2 - (begin % 2)) / 2;

EDIT2:. По-моему, несколько неправильное определение целочисленного деления в C (целочисленное деление усекает вниз для положительных чисел и вверх для отрицательных чисел) эта формула не будет работать, когда начало отрицательное нечетное число.

EDIT3: Пользователь "iPhone beginner" правильно отмечает, что если begin % 2 заменяется на begin & 1, это будет корректно работать для всех диапазонов.

Ответ 2

Подсказка 1: Оператор modulo вернет остаток текущего номера
Подсказка 2: вам не нужен цикл for

Подсказка 3: Диапазон непрерывный
Подсказка 4: число четных чисел в непрерывном диапазоне половины половины (иногда половина + 1, иногда половина - 1)
Подсказка 5: построение на подсказке1: рассмотрите также, что (будучи + конец + 1)% 2 дает Подсказка 6: Большинство или все ответы в этой теме неверны
Подсказка 7: убедитесь, что вы попробовали свое решение с отрицательным диапазоном чисел
Подсказка 8: убедитесь, что вы попробовали свое решение с диапазонами, охватывающими как отрицательные, так и положительные числа.

Ответ 3

int start, stop;
start = 0;
stop = 9;
printf("%d",(stop-start)/2+((!(start%2) || !(stop%2)) ? 1 : 0));

Если начало и остановка могут содержать любое значение. Не нужно итерации, чтобы определить это число.

Ответ 4

Число четных чисел между 0 и n равно [n/2] + 1. Поэтому число четных чисел между (n + 1) и m равно ([m/2] + 1) - ([n/2] + 1) = [m/2] - [n/2].

Для подсчета четных чисел между m и n ответом будет [m/2] - [(n - 1)/2].

[x] берется в направлении -\infty. Помните, что обычное C-целое деление в нашем случае не действует правильно: a/2 округляется до нуля, а не -\infty, поэтому результат не будет [a/2] для случая отрицательного a.

Это должен быть самый простой расчет; работает и для отрицательных чисел. (Требуется, однако, что m >= n.) Не содержит if и ?: s.

Если вы не считаете отрицательные числа, вы можете использовать только m/2 - (n+1)/2 + 1, иначе floor(m/2.0) - floor((n-1)/2.0)

Ответ 5

Это сделает трюк даже для диапазонов с отрицательными номерами.

int even = (last - first + 2 - Math.abs(first % 2) - Math.abs(last % 2)) / 2;

Протестировано следующим кодом:

public static void main(String[] args) {
    int[][] numbers = {{0, 4}, {0, 5}, {1, 4}, {1, 5}, {4, 4}, {5, 5},
                       {-1, 0}, {-5, 0}, {-4, 5}, {-5, 5}, {-4, -4}, {-5, -5}};

    for (int[] pair : numbers) {
        int first = pair[0];
        int last = pair[1];
        int even = (last - first + 2 - Math.abs(first % 2) - Math.abs(last % 2)) / 2;
        System.out.println("[" + first + ", " + last + "] -> " + even);
    }
}

Вывод:

[0, 4] -> 3
[0, 5] -> 3
[1, 4] -> 2
[1, 5] -> 2
[4, 4] -> 1
[5, 5] -> 0
[-1, 0] -> 1
[-5, 0] -> 3
[-4, 5] -> 5
[-5, 5] -> 5
[-4, -4] -> 1
[-5, -5] -> 0

Ответ 6

Я немного удивлен, что итерацию пытались решить. Минимальное число четных чисел, доступных в диапазоне, равно половине длины массива чисел, или rangeEnd - rangeStart.
Добавьте 1, если первое или последнее число четное.

Таким образом, метод: (с использованием javascript)

function evenInRange(rangeStart, rangeEnd)
{
  return
    Math.floor(rangeEnd - rangeStart) + 
    ((rangeStart % 2 == 0) || (rangeEnd % 2 == 0) ? 1 : 0)
}


Tests:
0 1 2 3 4 5 6 7 8
8 - 0 = 8
8 / 2 = 4
4 + 1 = 5
Even numbers in range:
0 2 4 6 8

11 12 13 14 15 16 17 18 19 20
20 - 11 = 9
9 / 2 = 4
4 + 1 = 5
Even numbers in range
12 14 16 18 20

1 2 3
3 - 1 = 2
2 / 2 = 1
1 + 0 = 1
Even numbers in range
2

2 3 4 5
5 - 2 = 3
3 / 2 = 1
1 + 1 = 2
Even numbers in range
2 4

2 3 4 5 6
6 - 2 = 4
4 / 2 = 2
2 + 1 = 3
Even numbers in range
2 4 6

Ответ 7

Я бы сказал

(max - min + 1 + (min % 2)) / 2

Edit: Erm хорошо по какой-то причине я думал, что (min% 2) возвращает 1 для четных чисел....:). Правильная версия

(max - min + 1 + 1 - (min % 2)) / 2

или скорее

(max - min + 2 - (min % 2)) / 2

Ответ 8

Диапазон всегда [2a + b, 2c + d] с b, d = {0,1}. Сделать таблицу:

b d | #even
0 0 | с-а + 1
0 1 | с-а + 1
1 0 | с-а
1 1 | с-а + 1

Теперь a = min/2, b = min% 2, c = max/2 и d = max% 2.

So int nEven = max/2 - min/2 + 1 - (min%2)

Ответ 9

Первое четное число в диапазоне: (begin + 1) & ~1 (круглый begin до четного числа).

Последнее четное число в диапазоне: end & ~1 (круглый end до четного числа).

Таким образом, общее число четных чисел в диапазоне: (end & ~1) - ((begin + 1) & ~1) + 1.

int num_evens = (end & ~1) - ((begin + 1) & ~1) + 1;

Ответ 10

Давайте посмотрим на это логически...

У нас есть четыре случая...

odd -> odd     eg.  1 -> 3  answer: 1
odd -> even    eg.  1 -> 4  answer: 2
even -> odd    eg.  0 -> 3  answer: 2
even -> even   eg.  0 -> 4  answer: 3

Первые три случая можно обрабатывать просто как...

(1 + last - first) / 2

Четвертый случай не так хорошо вписывается в это, но мы можем немного потренироваться для него довольно легко...

answer = (1 + last - first) / 2;
if (both first and last are even)
    answer++;

Надеюсь, что это поможет.

Ответ 11

Хорошо, почему бы и нет:

#include <cassert>

int ecount( int begin, int end ) {
    assert( begin <= end );
    int size = (end - begin) + 1;
    if ( size % 2 == 0  || begin % 2 == 1 ) {
        return size / 2;
    }
    else {
        return size / 2 + 1;
    }
}

int main() {
    assert( ecount( 1, 5 ) == 2 );
    assert( ecount( 1, 6 ) == 3 );
    assert( ecount( 2, 6 ) == 3 );
    assert( ecount( 1, 1 ) == 0 );
    assert( ecount( 2, 2 ) == 1 );
}

Ответ 12

Ответ:

(max - min + 2 - (max % 2) - (min % 2)) / 2

Краткое объяснение:

  • even..even yields (length + 1)/2
  • even..odd дает длину /2
  • odd.. даже дает длину /2
  • odd..odd дает (длина - 1)/2

  • length = max - min + 1

Следовательно, ответ равен (length - 1) / 2 plus 1/2 для четного min plus 1/2 для четного max. Обратите внимание, что (length - 1) / 2 == (max - min) / 2, а "бонусы" - (1 - (min % 2)) / 2 и (1 - (max % 2)) / 2. Суммируйте все это и упростите, чтобы получить ответ выше.

Ответ 13

В терминах начала и длины:

(length >> 1) + (1 & ~start & length)

половина длины плюс 1, если начало четное, а длина нечетная.

В терминах начала и конца:

((end - start + 1) >> 1) + (1 & ~start & ~end)

половина длины плюс 1, если начало четное, а конец - четный.

Ответ 14

Это не требует никаких условий:

evencount = floor((max - min)/2) + 1

Ответ 15

Псевдокод (я не кодер C):

count = 0;
foreach(i in range){
    if(i % 2 == 0){
      count++;
    }
}