什么是分别在奇数和偶数位置总结数字的最短方法

时间:2014-12-08 07:51:59

标签: c# math for-loop

我总是喜欢通过简单但智能的数学方法减少代码行数。这种情况似乎是需要这种方法的情况之一。所以我基本上需要的是用最少的代码分别在奇数和偶数位置加总数字。到目前为止,这是我能够想到的最佳方式:

string number = "123456789";
int sumOfDigitsInOddPlaces=0;
int sumOfDigitsInEvenPlaces=0;
for (int i=0;i<number.length;i++){
   if(i%2==0)//Means odd ones
     sumOfDigitsInOddPlaces+=number[i];
   else
     sumOfDigitsInEvenPlaces+=number[i];    
{
//The rest is not important

你有更好的主意吗?无需使用if else

的东西

6 个答案:

答案 0 :(得分:3)

int* sum[2] = {&sumOfDigitsInOddPlaces,&sumOfDigitsInEvenPlaces};

for (int i=0;i<number.length;i++)
{
    *(sum[i&1])+=number[i];
}

答案 1 :(得分:2)

您可以使用两个单独的循环,一个用于奇数索引数字,另一个用于偶数索引数字。 您的模数条件也可能是错误的,您将偶数索引数字(0,2,4 ...)放在奇数累加器中。可能只是因为您正在考虑将数字作为基于1的索引,数字数组基于0(可能是您的意图),但出于算法考虑,我会将数字视为从0开始。 这是我的主张

number = 123456789;
sumOfDigitsInOddPlaces=0;
sumOfDigitsInEvenPlaces=0;

//even digits
for (int i = 0; i < number.length; i = i + 2){
    sumOfDigitsInEvenPlaces += number[i];
}

//odd digits, note the start at j = 1
for (int j = 1; i < number.length; i = i + 2){
    sumOfDigitsInOddPlaces += number[j];    
}

在大规模上,这不会提高效率,仍然是O(N)算法,但它消除了分支

答案 2 :(得分:2)

由于您在问题中添加了C#

        var numString = "123456789";

        var odds = numString.Split().Where((v, i) => i % 2 == 1);
        var evens = numString.Split().Where((v, i) => i % 2 == 0);

        var sumOfOdds = odds.Select(int.Parse).Sum();
        var sumOfEvens = evens.Select(int.Parse).Sum();

答案 3 :(得分:1)

你喜欢Python吗?

num_string = "123456789"

odds  = sum(map(int, num_string[::2]))
evens = sum(map(int, num_string[1::2]))

答案 4 :(得分:1)

这个Java解决方案不需要if / else,没有代码重复,而且是O(N):

number = "123456789";
int[] sums = new int[2]; //sums[0] == sum of even digits, sums[1] == sum of odd

for(int arrayIndex=0; arrayIndex < 2; ++arrayIndex) 
{
    for (int i=0; i < number.length()-arrayIndex; i += 2)
    {
       sums[arrayIndex] += Character.getNumericValue(number.charAt(i+arrayIndex));
    } 
}

答案 5 :(得分:1)

假设number.length是偶数,则非常简单。如果数字不均匀,那么角落的情况是考虑最后一个元素。

int i=0;
while(i<number.length-1)
{
    sumOfDigitsInEvenPlaces += number[ i++ ];
    sumOfDigitsInOddPlaces += number[ i++ ];
}

if( i < number.length )
    sumOfDigitsInEvenPlaces += number[ i ];
  • 因为循环超过i 2乘2,如果number.length是偶数,则删除1不会执行任何操作。 如果number.length不均匀,则删除最后一项。
  • 如果number.length不均匀,则退出循环时i的最后一个值是尚未访问的最后一个元素的值。
  • 如果number.length不均匀,则通过模2推理,您必须将最后一项添加到sumOfDigitsInEvenPlaces。

这似乎比Anonymous&#39;更加冗长,但也更具可读性。 (接受)回答。但是,基准来了。


好吧,编译器似乎认为我的代码也更容易理解,因为如果我不打印结果,他会删除所有代码(这解释了为什么我一直都是0的时间......)。其他代码虽然对编译器来说已经足够混淆了。

最后,即使使用巨大的数组,clock_t也难以分辨出两者之间的区别。在第二种情况下,你得到的指令少了三分之一,但由于缓存中的所有内容(以及即使在寄存器中的运行总和)也没有多大意义。

对于好奇的人,我在这里放了两个版本的反汇编(从C编译):http://pastebin.com/2fciLEMw