给定一个n,计算1-n之间偶数数字的和(不包括n)

博客给出一段Python代码,用于计算给定数字n(不包括n)以内所有偶数的和。代码通过输入n,利用while循环和取模运算判断偶数并累加求和,最后输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#给定一个n,计算1-n之间偶数数字的和(不包括n)
n=int(input())
sum1=0
i=0

while i<n:
    if i%2==0:#取模取余
        sum1+=i
    i+=1

print(sum1)
 

<think>我们被要生成1到n范围内所有质数的算法或代码实现。根据提供的引用,有几种同的方法可以实现这个目标。1.最简单的方法是使用试除法:对于每个数i(从2到n),检查它是否能被2到i-1之间的任何整数整除。如果能,则它是质数。但这种方法效率较低,时间复杂度为$O(n^2)$。2.改进的试除法:在检查i是否为质数时,只需要检查2到$\sqrt{i}$之间的整数即可,因为如果i有一个大于$\sqrt{i}$的因子,那么必然有一个小于或等于$\sqrt{i}$的因子。这样可以将内层循环的次数减少到$O(\sqrt{i})$,总时间复杂度约为$O(n\sqrt{n})$。3.埃拉托斯特尼筛法(SieveofEratosthenes):这是一种更高效的方法,特别适用于生成一定范围内的所有质数。其基本思想是从2开始,将每个质数的倍数都标记为非质数。当到达n时,未被标记的数就是质数。这种方法的时间复杂度为$O(n\log\logn)$。根据引用[5]中提到的埃拉托斯特尼筛法,我们可以使用这种方法来生成1到n范围内的所有质数。下面我们分别给出这两种方法的代码实现(以Java为例),分析其优缺点。###方法1:试除法(改进版)```javaimportjava.util.ArrayList;publicclassPrimeNumbers{publicstaticArrayList<Integer>getPrimesByTrialDivision(intn){ArrayList<Integer>primes=newArrayList<>();if(n<2){returnprimes;}//2是质数,先加入primes.add(2);//从3开始,只考虑奇数for(inti=3;i<=n;i+=2){booleanisPrime=true;intsqrt=(int)Math.sqrt(i);//检查从3到sqrt(i)的奇数(因为i是奇数,所以需要检查偶数因子)for(intj=0;j<primes.size();j++){intprime=primes.get(j);if(prime>sqrt){break;}if(i%prime==0){isPrime=false;break;}}if(isPrime){primes.add(i);}}returnprimes;}}```###方法2:埃拉托斯特尼筛法```javaimportjava.util.ArrayList;publicclassPrimeNumbers{publicstaticArrayList<Integer>sieveOfEratosthenes(intn){//创建一个布尔数组,初始值都为false,表示是质数。数组下标0到n,01用。boolean[]isComposite=newboolean[n+1];//默认false,表示质数。true表示合数。ArrayList<Integer>primes=newArrayList<>();if(n>=2){primes.add(2);}//从3开始,遍历所有奇数for(inti=3;i<=n;i+=2){if(!isComposite[i]){primes.add(i);//注意:为了避免溢出,判断i*i<=nif(i<=Math.sqrt(n)){//从i*i开始标记,因为更小的倍数已经被之前的质数标记过了for(intj=i*i;j<=n;j+=i){isComposite[j]=true;}}}}returnprimes;}}```注意:在埃拉托斯特尼筛法中,我们通常从2开始,但这里为了优化,我们只考虑奇数(除了2)。我们创建了一个布尔数组`isComposite`,其索引代表数字,值为`true`表示该索引对应的数是合数,值为`false`表示质数。我们首先将2加入质数列表,然后从3开始遍历所有奇数,如果当前数`i`没有被标记为合数(即`isComposite[i]`为`false`),则将其加入质数列表,标记它的倍数(从`i*i`开始,步长为`i`)为合数。###性能比较-试除法在小范围内(比如n<10000)可以接受,但当n较大时(如n=1000000),效率会明显低于筛法。-埃拉托斯特尼筛法在生成大范围内的质数时效率更高。###示例调用```javapublicstaticvoidmain(String[]args){intn=100;ArrayList<Integer>primes1=getPrimesByTrialDivision(n);System.out.println("试除法得到的质数:"+primes1);ArrayList<Integer>primes2=sieveOfEratosthenes(n);System.out.println("筛法得到的质数:"+primes2);}```###注意事项-在试除法中,我们只检查到$\sqrt{i}$,且只使用已经找到的质数作为除数,这样效率更高。-在筛法中,我们只标记从`i*i`开始,因为更小的倍数(如`i*2`,`i*3`等)已经被更小的质数标记过了。§§相关问题§§1.埃拉托斯特尼筛法的时间复杂度是多少?如何推导?2.除了埃拉托斯特尼筛法,还有哪些高效的质数筛选算法?3.如何处理非常大的n(例如10亿)来生成质数?4.如何用计算优化质数生成算法?5.质数生成算法在实际应用中的例子有哪些?</think>### 生成1到n范围内所有质数的算法及实现 #### 1. **基础试除法(直接判断)** **原理**:对每个数 $i$($2 \leq i \leq n$),检查是否能被 $2$ 到 $\sqrt{i}$ 之间的整数整除。 ```java public static List<Integer> getPrimesBasic(int n) { List<Integer> primes = new ArrayList<>(); for (int i = 2; i <= n; i++) { boolean isPrime = true; for (int j = 2; j <= Math.sqrt(i); j++) { if (i % j == 0) { isPrime = false; break; } } if (isPrime) primes.add(i); } return primes; } ``` - **时间复杂度**:$O(n \sqrt{n})$ - **缺点**:效率低,适合小范围($n < 10^4$)[^4]。 --- #### 2. **埃拉托斯特尼筛法(高效推荐)** **原理**:标记非质数,未标记的即为质数。 1. 初始化布尔数组 `isPrime[0..n]`,默认全为 `true`。 2. 从 $2$ 开始,若 `isPrime[i]` 为 `true`,则将所有 $i$ 的倍数标记为 `false`。 3. 收集所有未被标记的数。 ```java public static List<Integer> sieveOfEratosthenes(int n) { boolean[] isPrime = new boolean[n + 1]; Arrays.fill(isPrime, true); // 初始化为true isPrime[0] = isPrime[1] = false; // 01是质数 for (int i = 2; i * i <= n; i++) { if (isPrime[i]) { // 标记i的倍数(从i*i开始优化) for (int j = i * i; j <= n; j += i) { isPrime[j] = false; } } } // 收集质数 List<Integer> primes = new ArrayList<>(); for (int i = 2; i <= n; i++) { if (isPrime[i]) primes.add(i); } return primes; } ``` - **时间复杂度**:$O(n \log \log n)$ - **优势**:适合大范围($n \leq 10^7$)[^5]。 --- #### 3. **优化试除法(跳过偶数)** **原理**:除 $2$ 外,只检查奇数。 ```java public static List<Integer> getPrimesOptimized(int n) { List<Integer> primes = new ArrayList<>(); if (n >= 2) primes.add(2); // 单独处理2 for (int i = 3; i <= n; i += 2) { // 只遍历奇数 boolean isPrime = true; for (int j = 3; j <= Math.sqrt(i); j += 2) { // 只用奇数试除 if (i % j == 0) { isPrime = false; break; } } if (isPrime) primes.add(i); } return primes; } ``` - **效率提升**:减少 $50\%$ 的循环次数[^3]。 --- ### 性能对比 | 算法 | 时间复杂度 | 适用场景 | |------------------|------------------|------------------| | 基础试除法 | $O(n \sqrt{n})$ | $n < 10^4$ | | 优化试除法 | $O(n \sqrt{n})$ | $n < 10^5$ | | 埃拉托斯特尼筛法 | $O(n \log \log n)$ | $n \leq 10^7$ | > **建议**:$n < 10^5$ 时用优化试除法;$n \geq 10^5$ 时用筛法。 ### 示例调用 ```java public static void main(String[] args) { int n = 100; List<Integer> primes = sieveOfEratosthenes(n); System.out.println("1到" + n + "的质数:" + primes); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值