从1加到n算法的几种算法(普通,递归,数学,前缀和)

作者提醒

在本文中最推荐前缀和算法,也就是第四种,不仅看起来高大上一点,并且性能和耗时都是比较优秀的。

一、普通算法

普通算法就是用for循环,设置一个变量sum,每一次都累加一个数。时间复杂度为O(n),不是很推荐的一个算法。
代码

#include<cstdio>

using namespace std;

int main() {
	int sum = 0;			//从1加到n的和,初始值为0
	int n;					//从1加到n
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		sum += i;
	}
	printf("%d", sum);
}

如果想控制一个范围,比如10加到100,那么只要把for循环的起始条件换成i=10

二、递归算法

没啥好说的,一个简简单单的入门递归,从n开始加,每次递归减1,n到1的时候即退出。也不是很推荐使用,数据量过大的话内存消耗会过于严重。
代码

#include<cstdio>

using namespace std;

int func(int n) {
	if (n == 1)return 1;
	return func(n - 1) + n;
}

int main() {
	int sum = 0;			//从1加到n的和,初始值为0
	int n;					//从1加到n
	scanf("%d", &n);
	sum = func(n);
	printf("%d", sum);
}

如果想控制一个范围,比如10加到100,那么只要把递归条件的n1换成n10即可,这也是我为什么不用n == 100停止递归,并且不是func(n+1)的原因

三、数学方法

一种就是高斯算法,一种就是前n项和,都是简单的套用数学公式即可,这两种方法推荐前一种,时间复杂度较低。后一种方法本文就不写啦。
高斯公式:在这里插入图片描述
如果想控制一个范围,那么可以把1换成起始的数
前n项和公式在这里插入图片描述

高斯公式代码

#include<cstdio>

using namespace std;

int main() {
	int sum = 0;			//从1加到n的和,初始值为0
	int n;					//从1加到n
	scanf("%d", &n);
	sum = (n + 1) * n / 2;
	printf("%d", sum);
}

另一种方式略,简单的公式搬上去即可

四、前缀和

这种方式是用了高中所学的一种方法如下:
在这里插入图片描述
把前1项,前2项,前3项…的和全部求出来放到数组s[n]中,之后就可以直接求出指定区间的数的和,并且时间复杂度为O(1),可谓是相当的快,并且具体的数的范围也能确定。
代码

#include<cstdio>

const int N = 100010;
int n, m;
int a[N], s[N];

using namespace std;

int main() {
	scanf("%d %d", &n, &m);		//n为有几个数,m为前n项的和
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	for (int i = 1; i <= m; i++) {
		s[i] = s[i - 1] + a[i];			//求出每一个前n项和,s[0]未赋值为0
	}
	int l = 2, r = 4;					//这里是需要求和的区间段,从第二个数到第四个数相加的和是多少
	while (m--) {
		printf("%d", s[r] - s[l - 1]);
	}
}

同时值得注意的,这个算法还可以更加精简,后面可以通过多进程并发的方式运行,设置锁等方式,上面的for运行一条数据,下面的for也立即运行一条数据,这样子,速度将会愈发的快。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值