Самый простой способ рассчитать количество четных чисел в заданном диапазоне - PullRequest
13 голосов
/ 21 апреля 2010

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

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

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

Ответы [ 16 ]

14 голосов
/ 21 апреля 2010
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;

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

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

7 голосов
/ 21 апреля 2010

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

2 голосов
/ 21 августа 2018

Ответ заключается в использовании двоичного И.

, поэтому число представлено в памяти в 0 и 1. скажем, 4 и 5.

4 = 0000 0100

5 = 0000 0101

и каждое четное число имеет ноль в конце, а каждое нечетное число имеет 1 в конце;

в c '1' означает истину, а '0' означает ложь.

так: позволяет код;

function isEven(int num){
     return ((num & 0x01) == 0) ? 1 : 0;
}

Здесь 0x01 означает 0000 0001. таким образом, мы идем 0x01 с данным номером.

представьте, что нет 5

5    |0000 0101 

0x01 |0000 0001

---------------

      0000 0001

поэтому ответ будет «1».

представьте, что нет 4

4    |0000 0100 

0x01 |0000 0001

---------------

      0000 0000

поэтому ответ будет «0».

сейчас

return ((num & 0x01) == 0) ? 1 : 0;

расширено до:

if((num & 0x01) == 0){// means  the number is even
      return 1;
}else{//means no is odd
      return 0;
}

Так вот и все.

Конец - бинарные операторы очень важны в мире программистов.

счастливое кодирование.

первый ответ здесь.

РЕДАКТИРОВАТЬ 1:

Общее количество вечера

totalEvens = ((end - start) / 2 + ((((end - start) & 0x01 ) == 0) ? 0 : 1 ));

здесь (end - start)/2 дает половину от общего числа.

это работает, если один четный, а другой нечетный.

но

((((end - start) & 0x01 ) == 0) ? 0 : 1 )

можно просто заменить на (!isEven(end-start))

Итак, если общее число четное, не добавляйте 1, а добавляйте 1.

это полностью работает.

2 голосов
/ 21 апреля 2010

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

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 голосов
/ 21 апреля 2010

Количество четных чисел от 0 до n равно [ n / 2] + 1. Следовательно, число четных чисел между ( n + 1) ) и m is ([ m / 2] + 1) - ([ n / 2] + 1) = [ m / 2] - [ n / 2].

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

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

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

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

2 голосов
/ 21 апреля 2010
int start, stop;
start = 0;
stop = 9;
printf("%d",(stop-start)/2+((!(start%2) || !(stop%2)) ? 1 : 0));

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

1 голос
/ 21 апреля 2010

Я немного удивлен, что итерация пыталась решить эту проблему. Минимальное число четных чисел, возможных в диапазоне, равно половине длины массива чисел или 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 голос
/ 21 апреля 2010

Диапазон всегда [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 - (min%2).

0 голосов
/ 22 апреля 2010

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

evencount = floor((max - min)/2) + 1
0 голосов
/ 21 апреля 2010

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

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

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

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

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

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

...