计算无符号整数范围内偶数的最简单方法是什么?
一个例子:如果范围是[0 ... 4]则答案是3(0,2,4)
我很难想出任何简单的方法。我提出的唯一解决方案涉及几个if语句。是否有一行简单的代码可以在没有if语句或三元运算符的情况下执行此操作?
答案 0 :(得分:14)
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中的整数除法有些不正确的定义(整数除法向下截断正数而向上截断为负数)此公式在begin为a时不起作用负奇数。
EDIT3:用户“iPhone初学者”正确观察到,如果begin % 2
替换为begin & 1
,则此功能将适用于所有范围。
答案 1 :(得分:7)
提示1:模运算符将返回当前数字的剩余部分
提示2:您不需要for循环
提示3:范围是连续的
提示4:连续范围内偶数的数量是偶数的一半(有时是半+ 1,有时是半 - 1)
提示5:建立在提示1上:还要考虑(+结束+ 1)%2给出的内容
提示6:此主题中的大部分或全部答案都是错误的
提示7:确保您尝试使用负数范围的解决方案
提示8:确保您尝试的解决方案的范围涵盖负数和正数
答案 2 :(得分:2)
int start, stop;
start = 0;
stop = 9;
printf("%d",(stop-start)/2+((!(start%2) || !(stop%2)) ? 1 : 0));
开始,停止可以保留任何值。 无需迭代来确定此数字。
答案 3 :(得分:2)
0到 n 之间的偶数计数是[ n / 2] + 1.因此,( n + 1)和 m 是([ m / 2] + 1) - ([ n / 2] + 1)= [< em> m / 2] - [ n / 2]。
对于 m 和 n 之间的偶数计数,因此答案为[ m / 2] - [( n - 1)/ 2]。
[x]指向 - \ infty的方向。请注意,在我们的情况下,通常的C整数除法不正确:a/2
向零舍入,而不是 - \ infty,因此结果将不是[ a / 2]对于teh负面情况 a 。
这应该是最简单的计算;也适用于负数。 (但需要 m &gt; = n 。)不包含if
和?:
s。
如果您不考虑负数,则可以只使用m/2 - (n+1)/2 + 1
,否则floor(m/2.0) - floor((n-1)/2.0)
答案 4 :(得分:2)
即使对于负数范围也是如此。
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
答案 5 :(得分:2)
答案是使用二进制AND。
因此,数字以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。
这完全有效。
答案 6 :(得分:1)
范围始终是[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)
。
答案 7 :(得分:1)
我有点惊讶迭代试图解决这个问题。 一个范围内可能的偶数最小数量等于数字数组长度的一半,或者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
答案 8 :(得分:0)
我会说
(max - min + 1 + (min % 2)) / 2
编辑:呃好吧因为某种原因我认为(min%2)为偶数数字返回1 .... :)。正确的版本是
(max - min + 1 + 1 - (min % 2)) / 2
或者更确切地说
(max - min + 2 - (min % 2)) / 2
答案 9 :(得分:0)
范围中的第一个偶数是:(begin + 1) & ~1
(圆begin
到偶数)。
范围内的最后一个偶数是:end & ~1
(将end
舍入为偶数)。
因此,范围内的偶数总数为:(end & ~1) - ((begin + 1) & ~1) + 1
。
int num_evens = (end & ~1) - ((begin + 1) & ~1) + 1;
答案 10 :(得分:0)
让我们从逻辑上看这个......
我们有四个案例......
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 :(得分:0)
哦,好吧,为什么不呢:
#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 :(得分:0)
答案:
(max - min + 2 - (max % 2) - (min % 2)) / 2
一个简短的解释:
odd..odd yield(length - 1)/ 2
length = max - min + 1
因此,对于偶数最小值,答案为(length - 1) / 2
加1/2
即使最小值加1/2
。
请注意,(length - 1) / 2 == (max - min) / 2
和“奖金”为(1 - (min % 2)) / 2
和(1 - (max % 2)) / 2
。总结并简化以获得上述答案。
答案 13 :(得分:0)
就开始和长度而言:
(length >> 1) + (1 & ~start & length)
长度的一半加1。
就开始和结束而言:
((end - start + 1) >> 1) + (1 & ~start & ~end)
一半长度加1。
答案 14 :(得分:0)
这根本不需要任何条件:
evencount = floor((max - min)/2) + 1
答案 15 :(得分:-3)
伪代码(我不是C编码器):
count = 0;
foreach(i in range){
if(i % 2 == 0){
count++;
}
}