面试题 - C# 交错序列求和
试题
求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+.....+m?最好用C#代码实现。
分析
这个表达式是一个交错序列的和,其中正数和负数交替出现。通常我们可以使用循环来实现这个计算,但面试官更青睐效率高的方式实现。
直观循环法
这种方法简单易懂,适合初学者理解和实现,但它并未挖掘序列本身的规律,因此在处理大规模数据时效率可能不是最优。
public static int CalculateAlternatingSum(int m)
{
int sum = 0;
for (int i = 1; i <= m; i++)
{
if (i % 2 == 1) // 如果是奇数位置(正数)
sum += i;
else // 如果是偶数位置(负数)
sum -= i;
}
return sum;
}
优化一
public static int CalculateAlternatingSum(int m)
{
// 计算偶数对的数量,因为每对的和为-1
int pairCount = m / 2;
// 如果m是奇数,需要加上最后一个数(正数)
int lastNumberToAdd = m % 2 == 1 ? m : 0;
// 计算总和
int sum = -1 * pairCount + lastNumberToAdd;
return sum;
}
优化二
public static int CalculateAlternatingSum(int m) => ((m & 1) * 2 - 1) * (m + 1) / 2;
这是一个使用lambda表达式定义的简单函数,其输入参数为一个整数m,返回一个基于m计算得到的整数值。让我们一步步分析这个函数的逻辑:
(m & 1)
:这部分使用了位与操作符&
,作用是取出m
的最低位(即二进制表示下的最右边一位)。如果m
是奇数,这一位为1;如果是偶数,则为0。因此,这步的结果实质上是在判断m的奇偶性。((m & 1) * 2 - 1)
:基于上一步的结果,如果m是奇数,(m & 1)
得到1,经过* 2 - 1
后结果仍为1;如果m是偶数,(m & 1)
得到0,经过* 2 - 1
后结果为-1。所以,这部分代码的作用是根据m的奇偶性返回1或-1,可以看作是一个符号决定器,奇数时为正,偶数时为负。* (m + 1)
:将上一步得到的结果(1或-1)与m + 1
相乘。这会根据m的奇偶性和大小进一步调整结果的值。注意这里的加1操作是为了确保当m
为0时,避免除法运算出现除以0的情况。/ 2
:最后,将上述结果除以2。结合前面的步骤,整个表达式实际上在根据m
的奇偶性执行不同的计算路径,并且利用了数学上的技巧来简化计算过程。
综上所述,这个函数的逻辑可以概述为:
当m为偶数时,计算结果为-(m + 1) / 2
;
当m为奇数时,计算结果为(m + 1) / 2
。