鱼C论坛

 找回密码
 立即注册
楼主: 欧拉计划

题目10:计算两百万以下所有质数的和

[复制链接]
发表于 2016-11-12 15:42:57 | 显示全部楼层
  1. def isPrime(n):
  2.     if n <= 1:
  3.         return False
  4.     else:
  5.         half = int(n ** 0.5)
  6.         for i in range(2,half + 1):
  7.             if n % i == 0:
  8.                 return False
  9.         return True
  10.    
  11. def SumOfPrimesBelow(n):
  12.     SumPrm = 0
  13.     for i in range(2, n):
  14.         if isPrime(i):
  15.             SumPrm += i
  16.     return SumPrm

  17. n = int(2E6)
  18. Sum = SumOfPrimesBelow(n)
  19. print('小于%d的质数的和为%d'%(n, Sum))
复制代码


>>>
小于2000000的质数的和为142913828922
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-12 16:06:32 | 显示全部楼层
jerryxjr1220 发表于 2016-10-10 19:23
最快的求质数的方法:
142913828922
[Finished in 1.8s]

果然好快啊!能解释一下的话就更完美了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-12 16:08:05 | 显示全部楼层
jerryxjr1220 发表于 2016-10-10 19:23
最快的求质数的方法:
142913828922
[Finished in 1.8s]

果然好快啊!能解释一下的话就更完美了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-12 16:58:31 | 显示全部楼层
梦想绘制者 发表于 2016-11-12 16:08
果然好快啊!能解释一下的话就更完美了。

用的是标记法,先建一个列表,列表的项数等于要求的最大质数,内容都为True。
然后第0,1项设为False,因为0和1都不是质数。
从第2项开始,是2的倍数的项都是设为假,因为都不是质数。然后只要是列表内还没有设为假的数,从它开始,它的倍数都设为假,直到列表内全部为真的数,那就是质数。
原理就是这样。
利用列表的项数和列表值的对应关系。这样可以减少判断次数,当然速度就是最快的了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-11-16 08:54:10 From FishC Mobile | 显示全部楼层
谢谢,这是以空间换时间的好方法啊,可以进一步优化的,先判断奇偶性,偶数不存储只判断奇数。哈哈,网上看了一下。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-18 10:39:51 | 显示全部楼层
  1. import math
  2. import time
  3. t=time.clock()
  4. def isprime(n):
  5.     if (n%2 == 0 and n!=2) or n == 1: return False
  6.     for x in range(3,int(math.sqrt(n))+1,2):
  7.         if n%x==0: return False
  8.     else: return True
  9. def euler10(count=2000000):
  10.     result = []
  11.     for n in range(count):
  12.         if isprime(n): result.append(n)
  13.     return sum(result)
  14. print (euler10(),'--time: ',time.clock()-t)
复制代码


142913828922 --time:  9.045785321932144
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-19 07:47:02 | 显示全部楼层
梦想绘制者 发表于 2016-11-16 08:54
谢谢,这是以空间换时间的好方法啊,可以进一步优化的,先判断奇偶性,偶数不存储只判断奇数。哈哈,网上看 ...

一开始也想过,但是我建立列表的时候没有办法只建立奇数列表而没有偶数,如果要每次判断奇偶的话,其实计算时间就不见得比我短了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-20 11:04:50 | 显示全部楼层
jerryxjr1220 发表于 2016-11-19 07:47
一开始也想过,但是我建立列表的时候没有办法只建立奇数列表而没有偶数,如果要每次判断奇偶的话,其实计 ...

嗯,有可能。这要看追求的是什么了。如果是仅仅速度快的话,你的完全可以。但又要快又要耗得空间少的话,分奇偶还是很可观的,毕竟一下都可以去掉一半的存储空间了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-9 11:28:25 | 显示全部楼层
purplenight 发表于 2016-8-7 08:03
# 修改自我的另一份代码, 部分代码或差劲, 能出结果就行.

这是过筛子的方法啊,好快
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-9 11:31:09 | 显示全部楼层
  1. # encoding:utf-8
  2. from math import sqrt
  3. from time import time

  4. def euler010(N=2000000):
  5.     l_pn = [2, 3]
  6.     result = 0

  7.     for n in range(5, N, 2):
  8.         # 标志位
  9.         ispm = True
  10.         sqr_n = int(sqrt(n))
  11.         for t in l_pn:
  12.             if n % t == 0:
  13.                 ispm = False
  14.                 break
  15.             if t > sqr_n:
  16.                 break
  17.                
  18.         if ispm:
  19.             l_pn.append(n)
  20.     print('小于 %d 的所有质数之和是: %d' % (N, sum(l_pn)))
  21.     return result

  22. start = time()            
  23. euler010()
  24. print('cost %.3f sec' % (time() - start))

复制代码


小于 2000000 的所有质数之和是: 142913828922
cost 4.122 sec
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-13 16:39:58 | 显示全部楼层
此代码使用matlab编程
Problem10所用时间为54.8729秒
Problem10的答案为142913828922
  1. %题目10:计算两百万以下所有质数的和
  2. function Output=Problem10(Input)
  3. tic
  4. if nargin==0
  5.     Input=2000000;
  6. end
  7. Sum=2;
  8. Temp=3:Input;
  9. Temp1=4:2:Input;%筛选2的倍数
  10. Temp2=6:3:Input;%筛选3的倍数
  11. Temp3=10:5:Input;%筛选5的倍数
  12. Temp4=14:7:Input;%筛选7的倍数
  13. Temp5=22:11:Input;%筛选11的倍数
  14. New1=setdiff(Temp,Temp1);
  15. New2=setdiff(New1,Temp2);
  16. New3=setdiff(New2,Temp3);
  17. New4=setdiff(New3,Temp4);
  18. New5=setdiff(New4,Temp5);
  19. for ii=New5
  20.     if isprime(ii)==1
  21.         Sum=ii+Sum;
  22.     end
  23. end
  24. Output=Sum;
  25. toc
  26. disp('此代码使用matlab编程')
  27. disp(['Problem10所用时间为',num2str(toc),'秒'])
  28. disp(['Problem10的答案为',num2str(Output)])
  29. end
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-2 21:35:43 | 显示全部楼层
  1. import time

  2. def sum_of_primes(number):
  3.     '筛法找出所有质数,并求和'
  4.     result = 0
  5.     list_primes = [True] * (number + 1)
  6.     list_primes[0] = False
  7.     list_primes[1] = False
  8.     for i in range(2, number):
  9.         if list_primes[i]:
  10.             for j in range(i ** 2, number, i):
  11.                 list_primes[j] = False
  12.     list_result = []
  13.     for k in range(2, number):
  14.         if list_primes[k]:
  15.             list_result.append(k)

  16.     for each in list_result:
  17.         result += each
  18.     return result

  19. start = time.clock()
  20. print(sum_of_primes(2000000))
  21. end = time.clock()
  22. print('程序执行了%fs。' %(end - start))
复制代码

执行结果:
142913828922
程序执行了1.113385s。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-17 16:41:08 | 显示全部楼层
本帖最后由 piperacillin 于 2017-2-17 16:42 编辑
  1. def ifprime(n):
  2.     k = 0
  3.     if n == 1 or n == 0:
  4.         k = 1
  5.     elif n % 2 == 0 and n != 2:
  6.         k = 1
  7.     else:
  8.         from math import sqrt
  9.         maxi = int(sqrt(n))
  10.         for i in range(3,maxi+1,2):
  11.             if n % i == 0:
  12.                 k = 1
  13.                 break
  14.     if k == 0:
  15.         return True
  16.     if k == 1:
  17.         return False
  18. k = 0
  19. for i in range(1,2000001):
  20.     if ifprime(i):
  21.         k +=i
  22. print(k)
  23.    
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-23 15:08:54 | 显示全部楼层
效率有点低
  1. /*计算200万以内所有质数的和*/
  2. #include <stdio.h>
  3. #include <math.h>

  4. int IsPrime(int x)
  5. {
  6.         int i, flag;
  7.     flag = 1;
  8.         for (i=2; i<=(int)sqrt(x); i++)
  9.         {
  10.                 if (x%i == 0)
  11.                 {
  12.                         flag = 0;
  13.                         break;
  14.                 }
  15.         }
  16.         return flag;
  17. }

  18. int main()
  19. {
  20.     int i;
  21.     long long sum = 2;
  22.     for(i=3; i<=2000000; i+=2)
  23.     {
  24.         sum = IsPrime(i) ? sum + i : sum;
  25.     }
  26.         printf("sum = %lld", sum);
  27.         return 0;
  28. }
复制代码

sum = 142913828922
Process returned 0 (0x0)   execution time : 11.465 s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-14 18:00:03 | 显示全部楼层
  1. import time
  2. start = time.clock()
  3. list_prime=[2,3]
  4. s=num=5
  5. while num<2000000:
  6.     f=1
  7.     for i in range(2,int(num**0.5)+1):
  8.         if num%i==0:
  9.             f=0
  10.     if f:
  11.         s+=num
  12.     num+=2
  13. print(s)
  14. end = time.clock()
  15. print("read:%f s" %(end - start))
复制代码

卧槽,跑下来都4分多钟了
答案:>>>
142913828922
read:255.466301 s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-30 14:30:06 | 显示全部楼层
本帖最后由 JonTargaryen 于 2017-3-30 14:51 编辑

秒出 142913828922

参考:http://blog.csdn.net/liukehua123/article/details/5482854

  1. #include <stdio.h>
  2. #include <math.h>

  3. #define MAX 2000000

  4. int is_prime(long num);

  5. int main(void)
  6. {
  7.     _Bool prime[MAX + 1] = {0};
  8.     long i = 3, j;
  9.     long sum = 2;

  10.     prime[2] = 1;
  11.     for(i = 3; i <= MAX; i += 2)
  12.     {
  13.         prime[i] = 1;
  14.     }

  15.     for(i = 3; i < sqrt(MAX); i += 2)
  16.     {
  17.         if(prime[i])
  18.         {
  19.             for(j = i + i; j <= MAX; j += i)
  20.             {
  21.                 prime[j] = 0;
  22.             }
  23.         }
  24.     }

  25.     for(i = 3; i <= MAX; i += 2)
  26.     {
  27.         if(prime[i])
  28.         {
  29.             sum += i;
  30.         }
  31.     }

  32.     printf("The sum of all the primes within 2,000,000 is: %ld\n", sum);

  33.     return 0;
  34. }
  35. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-30 15:06:46 | 显示全部楼层
本帖最后由 JonTargaryen 于 2017-3-30 15:11 编辑


python 慢一点 0.41595s

  1. import math

  2. MAX = 2000000

  3. def main():
  4.     global MAX
  5.     prime = [0]
  6.     prime = prime * (MAX + 1)
  7.     num = 3
  8.     result = 2

  9.     prime[2] = 1
  10.     for num in range(3, MAX + 1, 2):
  11.         prime[num] = 1;

  12.     for num in range(3, int(math.sqrt(MAX) + 1), 2):
  13.         if prime[num]:
  14.             for j in range(num + num, MAX + 1, num):
  15.                 prime[j] = 0

  16.     for num in range(3, MAX + 1, 2):
  17.         if prime[num]:
  18.             result += num

  19.     print(result)

  20. if __name__ == "__main__":
  21.     main()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-29 14:46:32 | 显示全部楼层
#求2百万一下所有质数的和

  1. import math
  2. import time


  3. start = time.time()
  4. def ifprime(n):
  5.         r = int(math.sqrt(n))
  6.         for i in range(2,r+1):
  7.             if n%i == 0:
  8.                 return 0
  9.         return 1


  10. sum = 2
  11. n = 3

  12. while n < 2000000:
  13.     if ifprime(n):
  14.         sum += n
  15.     n += 2

  16. print(sum)

  17. end = time.time()
  18. print(end-start)
复制代码


结果:142913828922
时间:33.8529691696167
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-1 00:46:51 | 显示全部楼层
本帖最后由 天之南 于 2017-5-1 01:18 编辑
  1. ##include<stdio.h>

  2. int main()
  3. {
  4.         const int L = 200000;
  5.         long long result = 5;
  6.         int arr[200000] = { 2,3 };
  7.         int i = 2;
  8.         for (int x = 5;i < L&&x < 2000000;x += 2)
  9.         {
  10.                 int j;
  11.                 for (j = 0;arr[j]* arr[j] <= x;j++)
  12.                 {
  13.                         if (x % arr[j] == 0)
  14.                         {
  15.                                 j = 0;
  16.                                 break;
  17.                         }
  18.                 }
  19.                 if (j)
  20.                 {
  21.                         arr[i] = x;
  22.                         result += x;
  23.                         i++;
  24.                 }
  25.         }
  26.         system("pause");
  27.         return 0;
  28. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-1 01:14:04 | 显示全部楼层
  1. #include<stdio.h>

  2. int main()
  3. {
  4.         const int L = 200000;
  5.         long long result = 5;
  6.         int arr[200000] = { 2,3 };
  7.         int i = 2;
  8.         for (int x = 5;i < L&&x < 2000000;x += 2)
  9.         {
  10.                 int j;
  11.                 for (j = 0;arr[j]* arr[j] <= x;j++)
  12.                 {
  13.                         if (x % arr[j] == 0) {
  14.                                 j = 0;
  15.                                 break;
  16.                         }
  17.                 }
  18.                 if (j) {
  19.                         arr[i] = x;
  20.                         result += x;
  21.                         i++;
  22.                 }
  23.         }
  24.         printf("%lld\n", result);
  25.         return 0;
  26. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 05:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表