将奇数和偶数位的数字分别相加的最短方法是什么

本文关键字:是什么 方法 数字 | 更新日期: 2023-09-27 18:33:41

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

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的东西

将奇数和偶数位的数字分别相加的最短方法是什么

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

您可以使用两个单独的循环,一个用于奇数索引数字,另一个用于偶数索引数字。此外,您的模条件可能是错误的,您将偶数索引数字(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( 算法,但它消除了分支

既然你在这个问题中添加了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();

你喜欢Python吗?

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

这个 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));
    } 
}

假设 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。

对我来说,这似乎比匿名者(接受的(答案更冗长,但也更具可读性。然而,基准即将到来。


好吧,编译器似乎也认为我的代码更容易理解,因为如果我不打印结果,他会将其全部删除(这解释了为什么我一直得到 0 的时间......不过,其他代码对于编译器来说也足够模糊。

最后,即使有巨大的阵列,clock_t也很难分辨两者之间的区别。在第二种情况下,您得到的指令减少了大约三分之一,但由于所有内容都在缓存中(甚至在寄存器中也是如此(,因此这并不重要。

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