有负数项的数列之和

问题:编写函数计算数列前n项之和,数列为1-2+3-4+5-6+7-8+......。

这个问题简单,编写一个计算数列之和的函数太容易了。

人们通常用计算解决问题,也就是编写程序解决问题。然而,编写程序解决问题,是多解的,即不同的程序可以计算出相同的结果。

解决这个问题,编写了3个不同的函数。

函数sum1(),遇到正数项则相加,遇到负数项则相减,使用逻辑判定来决定是做相加还是相减,即对于奇数项做加法计算,对于偶数项做减法计算。

函数sum2(),也是用一般累加求和的计算,对于每一项进行求和计算。其中使用了一个小技巧,用变量sign来控制项的正负。语句sign = -sign;每一次执行后,如果sign原先是1则变为-1,如果sign原先是-1则变为1。再通过乘法运算来改变一个数的符号。这种小技巧,许多地方都有可能使用,平时需要积累。

函数sum3(),则在对数列计算公式进行推导之后再进行计算,计算量是最小的。数列从小到大,两项两项相加都是-1,所以如果给定的n是为偶数时,其值为-n/2;若给定的n为奇数时,其值为前你项之和加上第n项,即-(n-1)/2+n。这个函数的计算效率是最高的。

源程序如下:

/* 编写函数计算数列前n项之和,数列为1-2+3-4+5-6+7-8+......。 */

#include <stdio.h>

/* 判断奇偶进行相加或相减计算,最后算出数列之和 */
long sum1(int n)
{
    long sum = 0;
    int i;

    for(i=1; i<=n; i++) {
        if(i % 2 == 1)
            sum += i;
        else
            sum -= i;
    }

    return sum;
}

/* 使用1和-1来乘,实现负数求和计算 */
long sum2(int n)
{
    long sum = 0;
    int i, sign=1;

    for(i=1; i<=n; i++) {
        sum += sign * i;

        sign = -sign;       // 每执行一次,1变-1,或-1变1
    }

    return sum;
}

/* 先进行数学推导,再用程序实现计算 */
long sum3(int n)
{
    if(n % 2 == 1)
        return - (n-1) / 2 + n;
    else
        return - n / 2;
}

int main(void)
{
    int i;

    for(i=1; i<=20; i++)
        printf("%d %ld %ld %ld\n", i, sum1(i), sum2(i), sum3(i));

    return 0;
}

测试计算结果(计算到前20项之和为止)如下:

1 1 1 1

2 -1 -1 -1

3 2 2 2

4 -2 -2 -2

5 3 3 3

6 -3 -3 -3

7 4 4 4

8 -4 -4 -4

9 5 5 5

10 -5 -5 -5

11 6 6 6

12 -6 -6 -6

13 7 7 7

14 -7 -7 -7

15 8 8 8

16 -8 -8 -8

17 9 9 9

18 -9 -9 -9

19 10 10 10

20 -10 -10 -10

时间: 2024-10-28 13:28:50

有负数项的数列之和的相关文章

7-49 求前n项的阶乘之和 (15 分)

从键盘输入一个整数n,求前n项的阶乘之和,1+2!+3!+...+n!的和 输入格式: 输入一个大于1的整数.例如:输入20. 输出格式: 输出一个整数.例如:2561327494111820313. 输入样例: 在这里给出一组输入.例如: 20 输出样例: 在这里给出相应的输出.例如: 2561327494111820313 def f(n): ans = 1 for i in range(1,n+1): ans *= i return ans n = int(input()) sum = 0

最大子数列之和问题

给定一个数组,数组长度为n,数组中每个元素为一个整数(其中有正数,负数,零),求一和最大的子数组 这是一道老生常谈的动态规划问题,也是我大一学算法时遇到的第一道动态规划问题,当时觉得解法非常精妙,从此爱上了算法. 题目的具体解法为是dp[i][0]表示前i项数列不含最后一项(第i项)时的子数列之和的最大值,dp[i][1]表示前i项数列含最后一项的子数列之和最大值 很明显dp[i][0]=max(dp[i-1][1],dp[i-1][1]),dp[i][1]=max(dp[i-1][1]+a[i

C语言之基本算法09—各位全是a的数列之和

/* ================================================================== 题目:数列为a,aa,aaa,--.求a+aa+aaa+--+aaaaaaa--. ================================================================== */ #include<stdio.h> main() { int a,i,n,x,Sn,flag=1; while(flag) { pri

C++求连续数列之和为S的数组里面所有组合(根据公式S=(x+y)*n/2优美实现)

//博主mingliang37的思想,我后来想明白了,整理了一下. #include <iostream> using namespace std; //输出所有和为S的连续整正数序列. //x.......y(这是一个连续序列) //x+.....+y=S; //还记得小时候老师要我们做的一道题吗?求1+2+3+...+100=? //(1+100).100/2=5050. //所以我们假设这个连续正整数序列是从x开始到y结束,总共有n个数字 //那么S=(x+y)*n/2,且y-x=n-1

软工 assignment 3 —— 求最大子数列之和

题目要求 最大连续子数组和(最大子段和) 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+-+a[j]},1<=i<=j<=n 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20. -- 引用自<百度

15 斐波那契数列数列之和

1 sum = 0 2 a,b = 0,1 3 while b < 4000000: 4 if b%2 == 0: 5 sum += b 6 a,b = b,a+b 7 print(sum) 原文地址:https://www.cnblogs.com/reaix/p/12651194.html

《程序设计技术》课程辅助学习资料

本文档提供课程相关的辅助学习资料. 阅读程序是提高程序设计水平的最为有效的方法,<程序设计技术>课程至少应该阅读后面提供链接博文中的基础部分.能够阅读完基础部分的博文,则可以给课程学习奠定一个坚实的基础. 自己编写程序也是学习编程必不可少的一个环节.自己编写是否正确可以通过OJ系统来验证.选做OJ的程序设计题方便于评价自己所写的程序是否正确.想要提高编写程序的能力并且达到更高的水平,从各个OJ中选做一些编程题是十分必要的. 文中提供了CCF-CSP认证考试历年 试题的第1题的题解.这些题解中都

斐波那契数列——摘自搜狗百科

1数列公式 递推公式 斐波那契数列:0.1.1.2.3.5.8.13.21.34.55.89.144... 如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式: F(0) = 0,F(1)=F(2)=1,F(n)=F(n-1)+F(n-2) (n≥3) 通项公式 通项公式的推导方法一:利用特征方程 线性递推数列的特征方程为: X^2=X+1 解得 X1=(1+√5)/2, X2=(1-√5)/2. 斐波拉契数列则F(n)=C1*X1^n + C2*X2^n ∵F(1)=F(2

2-06. 数列求和(20)(ZJUPAT 数学)

题目链接:http://pat.zju.edu.cn/contests/ds/2-06 给定某数字A(1<=A<=9)以及非负整数N(0<=N<=100000),求数列之和S = A + AA + AAA + - + AA-A(N个A).例如A=1, N=3时,S = 1 + 11 + 111 = 123. 输入格式说明: 输入数字A与非负整数N. 输出格式说明: 输出其N项数列之和S的值. 样例输入与输出: 序号 输入 输出 1 1 3 123 2 6 100 740740740