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

Что самый простой путь состоит в том, чтобы вычислить количество четных чисел в диапазоне целых чисел без знака?

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

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

13
задан Fdr 27 June 2014 в 13:33
поделиться

15 ответов

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

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

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

РЕДАКТИРОВАТЬ: Это может дополнительно упрощено до:

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

РЕДАКТИРОВАТЬ2: Из-за, на мой взгляд, несколько неправильного определения целочисленного деления в C (целочисленное деление усекает вниз для положительных чисел и вверх для отрицательных чисел) эта формула не будет работать, если begin отрицательное нечетное число.

РЕДАКТИРОВАТЬ 3: Пользователь «iPhone новичок» правильно замечает, что если begin% 2 заменить на begin & 1 , это будет работать правильно для всех диапазонов.

14
ответ дан 1 December 2019 в 20:56
поделиться

Ответ:

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

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

  • четное .. четное дает (длина + 1) / 2
  • четное ... нечетное дает длину / 2
  • нечетное .. четное дает длину / 2
  • odd..odd дает (длина - 1) / 2

  • длина = max - min + 1

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

0
ответ дан 1 December 2019 в 20:56
поделиться

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

count = 0;
foreach(i in range){
    if(i % 2 == 0){
      count++;
    }
}
-3
ответ дан 1 December 2019 в 20:56
поделиться

Число четных чисел от 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 и ?: s.

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

2
ответ дан 1 December 2019 в 20:56
поделиться

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

7
ответ дан 1 December 2019 в 20:56
поделиться

Я бы сказал

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

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

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

или, скорее,

(max - min + 2 - (min % 2)) / 2
0
ответ дан 1 December 2019 в 20:56
поделиться

С точки зрения начала и длины:

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

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

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

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

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

0
ответ дан 1 December 2019 в 20:56
поделиться

Я немного удивлен, что эту итерацию пытались решить. Минимальное возможное количество четных чисел в диапазоне равно половине длины массива чисел, или, 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
1
ответ дан 1 December 2019 в 20:56
поделиться

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

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
2
ответ дан 1 December 2019 в 20:56
поделиться

А почему бы и нет:

#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 );
}
0
ответ дан 1 December 2019 в 20:56
поделиться

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

b d | #even
0 0 | c-a+1
0 1 | c-a+1
1 0 | c-a
1 1 | c-a+1

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

Итак int nEven = max / 2 - min / 2 + 1 - (мин.% 2) .

1
ответ дан 1 December 2019 в 20:56
поделиться
int start, stop;
start = 0;
stop = 9;
printf("%d",(stop-start)/2+((!(start%2) || !(stop%2)) ? 1 : 0));

Где start и stop могут содержать любое значение. Нет необходимости повторять, чтобы определить это число.

2
ответ дан 1 December 2019 в 20:56
поделиться

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

evencount = floor((max - min)/2) + 1
0
ответ дан 1 December 2019 в 20:56
поделиться

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

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

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

int num_evens = (end & ~1) - ((begin + 1) & ~1) + 1;
0
ответ дан 1 December 2019 в 20:56
поделиться

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

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

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

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

0
ответ дан 1 December 2019 в 20:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: