计算给定范围内偶数的最简单方法
计算无符号整数范围内偶数的最简单方法是什么?
例如:如果范围是[0 … 4]那么答案是3(0,2,4)
我很难想到任何简单的方法。 我提出的唯一解决方案涉及几个if语句。 是否有一行简单的代码可以在没有if语句或三元运算符的情况下执行此操作?
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中的整数除法有些不正确的定义(整数除法向下截断正数而向上截断为负数)当start为负奇数时,此公式将不起作用。
编辑3:用户’iPhone初学者’正确观察到如果begin % 2
被替换为begin & 1
这将适用于所有范围。
提示1:模运算符将返回当前数字的余数
提示2:您不需要for循环
提示3:范围是连续的
提示4:连续范围内偶数的数量是偶数的一半(有时是一半+ 1,有时是一半 – 1)
提示5:建立在Hint1上:还要考虑(%+ end + 1)%2给出的内容
提示6:此主题中的大部分或全部答案都是错误的
提示7:确保您尝试使用负数范围的解决方案
提示8:确保您尝试的解决方案的范围涵盖负数和正数
int start, stop; start = 0; stop = 9; printf("%d",(stop-start)/2+((!(start%2) || !(stop%2)) ? 1 : 0));
开始和停止可以保持任何价值。 无需迭代来确定此数字。
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的情况,结果将不是[ a / 2]。
这应该是最简单的计算; 也适用于负数。 (但需要m > = n 。)不包含s和?:
s。
如果不考虑负数,则可以使用m/2 - (n+1)/2 + 1
,否则为floor(m/2.0) - floor((n-1)/2.0)
即使对于负数的范围,这也可以解决问题。
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
答案是使用二进制AND。
所以数字在0和1的内存中表示。比如说4和5。
4 = 0000 0100
5 = 0000 0101
每个偶数最后都有一个零,每个奇数最后都有1个;
in c’1’表示true,’0’表示false。
所以:让代码;
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。
这完全有效。
我有点惊讶迭代试图解决这个问题。 一个范围内可能的偶数最小数量等于数字数组长度的一半,或者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
范围始终是[2a + b,2c + d],b,d = {0,1}。 做一张桌子:
bd | #even 0 0 | c-a+1 0 1 | c-a+1 1 0 | ca 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)
。
我会说
(max - min + 1 + (min % 2)) / 2
编辑:呃好吧因为某些原因我认为(min%2)为偶数数字返回1 …. :)。 正确的版本是
(max - min + 1 + 1 - (min % 2)) / 2
更确切地说
(max - min + 2 - (min % 2)) / 2
范围中的第一个偶数是: (begin + 1) & ~1
(round begin
to even number)。
范围中的最后一个偶数是: end & ~1
(round end
to even number)。
因此,该范围内的偶数总数为: (end & ~1) - ((begin + 1) & ~1) + 1
。
int num_evens = (end & ~1) - ((begin + 1) & ~1) + 1;
让我们从逻辑上看一下……
我们有四个案例……
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++;
希望这可以帮助。
哦,好吧,为什么不呢:
#include 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 ); }
答案:
(max - min + 2 - (max % 2) - (min % 2)) / 2
一个简短的解释:
- 甚至……平均收益率(长度+ 1)/ 2
- even..odd产生长度/ 2
- 奇数…甚至产量长度/ 2
-
奇数…收益率(长度 – 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
。 总结并简化以获得上述答案。
在开始和长度方面:
(length >> 1) + (1 & ~start & length)
如果开始是偶数且长度是奇数,则长度的一半加1。
在开始和结束方面:
((end - start + 1) >> 1) + (1 & ~start & ~end)
如果开始是偶数且结束是偶数,则一半长度加1。
这根本不需要任何条件:
evencount = floor((max - min)/2) + 1
伪代码(我不是C编码器):
count = 0; foreach(i in range){ if(i % 2 == 0){ count++; } }