鱼C论坛

 找回密码
 立即注册
查看: 6613|回复: 44

[已解决]Python:每日一题 293

[复制链接]
发表于 2019-12-23 20:52:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天的题目:


给定一个非负整数 n,返回所有小于 n 的质数的数量。

示例 1:

输入:10
输出:4
解释:小于 10 的质数一共有 4 个,它们是 2、3、5、7。


欢迎大家一起答题!
最佳答案
2019-12-23 21:05:10
本帖最后由 Croper 于 2019-12-23 23:34 编辑
  1. def func293(n):
  2.     if (n<=2):
  3.         return 0
  4.     primes=[2]
  5.     def isprime(num):
  6.         for i in primes:
  7.             if (i**2>num):
  8.                 return True
  9.             if (num % i==0):
  10.                 return False
  11.     i=3
  12.     while (i<n):
  13.         if isprime(i):
  14.             primes.append(i)
  15.         i+=2

  16.     return len(primes)
复制代码


...才想起这题leetcode上做过,当时用的C++写的,改成python的吧:
  1. def func293(n):
  2.     if (n<=2):
  3.         return 0;
  4.     s=[True]*n
  5.     s[0]=False
  6.     s[1]=False
  7.     for i in range(2,n):
  8.         if i**2>n:
  9.             break
  10.         if not s[i]:
  11.             continue
  12.         for j in range(i*2,n,i):
  13.             s[j]=False
  14.     return sum(s)
复制代码

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-12-23 20:53:38 | 显示全部楼层
本帖最后由 凌九霄 于 2019-12-23 22:22 编辑
  1. import math


  2. def count_prime(number):
  3.     if number < 2: return 0
  4.     K = 1
  5.     for i in range(3, number):
  6.         M = 1
  7.         if i % 2 == 0:
  8.             M = 0
  9.             continue
  10.         for j in range(3, int(math.sqrt(i) + 1), 2):
  11.             if i % j == 0:
  12.                 M = 0
  13.                 break
  14.         if M == 1:
  15.             K += 1
  16.     return K
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:05:10 | 显示全部楼层    本楼为最佳答案   
本帖最后由 Croper 于 2019-12-23 23:34 编辑
  1. def func293(n):
  2.     if (n<=2):
  3.         return 0
  4.     primes=[2]
  5.     def isprime(num):
  6.         for i in primes:
  7.             if (i**2>num):
  8.                 return True
  9.             if (num % i==0):
  10.                 return False
  11.     i=3
  12.     while (i<n):
  13.         if isprime(i):
  14.             primes.append(i)
  15.         i+=2

  16.     return len(primes)
复制代码


...才想起这题leetcode上做过,当时用的C++写的,改成python的吧:
  1. def func293(n):
  2.     if (n<=2):
  3.         return 0;
  4.     s=[True]*n
  5.     s[0]=False
  6.     s[1]=False
  7.     for i in range(2,n):
  8.         if i**2>n:
  9.             break
  10.         if not s[i]:
  11.             continue
  12.         for j in range(i*2,n,i):
  13.             s[j]=False
  14.     return sum(s)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +2 收起 理由
zltzlt + 3 + 3 + 2 350 ms

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-12-23 21:10:30 | 显示全部楼层
凌九霄 发表于 2019-12-23 20:53
占个位置先,又是效率题吧

是,看效率。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:12:13 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-12-24 00:31 编辑

抢地板。
我尽力了,暂时想不到怎样能更高效了。

                               
登录/注册后可看大图

大写的监介,刚刚忘记验证结果了……

                               
登录/注册后可看大图

代码:
  1. log = []
  2. def solve(n:'int 非负整数'):
  3.     if log:
  4.         primes = [x for x in log if x<n]
  5.         #print('调试',primes)
  6.         res = primes[-1] if primes else 2
  7.     else:
  8.         primes = []
  9.         res = 2
  10.         if res < n:
  11.             primes.append(res)
  12.         res = 3
  13.     for res in range(res,n,2):
  14.         out = False
  15.         for sub in primes:
  16.             if sub**2 > res:
  17.                 break
  18.             elif not res%sub:
  19.                 out = True
  20.                 break
  21.         if out:
  22.             continue
  23.         else:
  24.             primes.append(res)
  25.             if res not in log:
  26.                 log.append(res)
  27.     return len(primes)
  28. if __name__ == '__main__':
  29.     print('示例1 输出:',solve(10))

复制代码
我自行测试的结果:
  1. >>> import time
  2. >>> for n in range(20):
  3.         num = 10**n
  4.         a = time.perf_counter()
  5.         get = solve(num)
  6.         b = time.perf_counter()
  7.         print(get,'用时',b-a,'s',n)

  8.         
  9. 0 用时 9.300000000322939e-06 s 0
  10. 4 用时 1.6600000000366322e-05 s 1
  11. 25 用时 0.00010729999999981032 s 2
  12. 168 用时 0.0009782000000004842 s 3
  13. 1229 用时 0.02421449999999936 s 4
  14. 9592 用时 0.9459274999999998 s 5
  15. 78498 用时 52.4094105 s 6
复制代码


时间复杂度的话,应该大约是 O(n^2)


评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:31:43 | 显示全部楼层
  1. def fun(num):
  2.     if num <= 2:
  3.         return 0
  4.     prime = [2]
  5.     for i in range(3, num, 2):
  6.         for j in prime:
  7.             if i % j == 0:
  8.                 break
  9.         else:
  10.             prime.append(i)
  11.     return len(prime)
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
zltzlt + 2 + 2 输入 499979 超时

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:34:34 | 显示全部楼层
  1. def fun293(n):
  2.     if n==1 or n==2:
  3.         return f'小于{n}的质数不存在'
  4.     k=[i for i in range(2,n) for j in range(2,i) if 0 in [i%j]]
  5.     return f'小于{n}的质数数量有{n-2-len(set(k))}个'
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1 没考虑 n 为 0 的情况

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:47:06 From FishC Mobile | 显示全部楼层
本帖最后由 hrp 于 2019-12-24 23:45 编辑

实在想不到高效算法,输入大数据都是超时
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:49:44 | 显示全部楼层
本帖最后由 TJBEST 于 2019-12-23 22:36 编辑

很惭愧 10000个数居然算了100毫秒 10万大概 8秒 真的太差劲了
  1. def fun293(n):
  2.     if 0 <= n <=2:
  3.         return 0
  4.     else:
  5.         selectlist = [2]
  6.         for eachNum in range(3,n):
  7.             status = 1
  8.             for eachSu in selectlist:
  9.                 if eachNum % eachSu ==0:
  10.                     status = 0
  11.                     break
  12.             if status == 1:
  13.                 selectlist.append(eachNum)
  14.         return len(selectlist)
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1 输入 499979 超时

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 21:51:52 | 显示全部楼层
本帖最后由 danteer 于 2019-12-24 09:32 编辑

那我也抢个位置吧
  1. def solve(n):
  2.     def generator():
  3.         list1 = [2]
  4.         number = 3
  5.         while True:
  6.             yield list1[-1]
  7.             flag = True
  8.             while flag:
  9.                 flag = False
  10.                 for each in list1:
  11.                     if ((2*each) > number):
  12.                         break
  13.                     if (number % each == 0):
  14.                         number += 2
  15.                         flag = True
  16.                         break
  17.             list1.append(number)
  18.             number += 2
  19.     x = generator()
  20.     result = 0
  21.     while next(x) < n:
  22.         result += 1
  23.     return result
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +1 收起 理由
zltzlt + 2 + 2 + 1 输入 499979 超时

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-23 22:11:33 | 显示全部楼层
本帖最后由 Stubborn 于 2019-12-24 04:58 编辑
  1. def fun293(n):
  2.     if n == 1: return 0
  3.     primes = [True] * n
  4.     primes[0], primes[1] = False, False
  5.     for (i, prime) in enumerate(primes):
  6.         if prime:
  7.             for j in range(i * i, n, i): primes[j] = False
  8.     return len([k for (k, trueprime) in enumerate(primes) if trueprime])

  9. import time
  10. for n in range(10):
  11.         num = 10**n
  12.         a = time.perf_counter()
  13.         get = fun293(num)
  14.         b = time.perf_counter()
  15.         print(get,'用时',b-a,'s',n)
复制代码


上了10**9就搞不定了

  1. 0 用时 1.0259999999595593e-06 s 0
  2. 4 用时 1.2316000000012206e-05 s 1
  3. 25 用时 3.746000000004468e-05 s 2
  4. 168 用时 0.0003412480000000162 s 3
  5. 1229 用时 0.00341709699999998 s 4
  6. 9592 用时 0.037514688999999934 s 5
  7. 78498 用时 0.376490329 s 6
  8. 664579 用时 4.567675358 s 7
  9. 5761455 用时 48.727864815 s 8
复制代码


想想还可以提速一半, 提速成功

  1. def test(n: int):
  2.     if n < 3: return 0
  3.     count = 0
  4.     primes = [True] * (n//2)
  5.     for i in range(3, n, 2):
  6.         if primes[i//2]:
  7.             count += 1
  8.             for j in range((i * i)//2, n//2, i): primes[j] = False
  9.     return count + 1
复制代码

  1. 0 用时 7.700000000006313e-07 s 0
  2. 4 用时 5.7779999999979514e-06 s 1
  3. 25 用时 1.2270999999997728e-05 s 2
  4. 168 用时 0.00027523900000000004 s 3
  5. 1229 用时 0.001398563999999998 s 4
  6. 9592 用时 0.011049376999999999 s 5
  7. 78498 用时 0.10091913899999999 s 6
  8. 664579 用时 1.1721501019999998 s 7
  9. 5761455 用时 12.463232227 s 8
复制代码

评分

参与人数 2荣誉 +5 鱼币 +6 贡献 +5 收起 理由
zltzlt + 3 + 3 + 2 300 ms
阴阳神万物主 + 2 + 3 + 3 强,无敌

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2019-12-23 22:25:42 | 显示全部楼层
本帖最后由 Unicorn# 于 2019-12-23 22:31 编辑

估计不行
  1. def solve(num):
  2.     primes = []
  3.     for i in range(2, num):
  4.         isprime = True
  5.         for prime in primes:
  6.             if i % prime == 0:
  7.                 isprime = False
  8.                 break
  9.         if isprime:
  10.             primes.append(i)
  11.     return len(primes)
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +1 收起 理由
zltzlt + 2 + 2 + 1 输入 499979 超时

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 01:30:38 | 显示全部楼层
Stubborn 发表于 2019-12-23 22:11
上了10**9就搞不定了,

嗯,会超出内存限制
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 01:39:52 | 显示全部楼层

没报错,但是慢,卡在哪里,估计是爆内存了 10亿的 list  估计内存吃紧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 02:00:42 | 显示全部楼层
  1. def func(n):
  2.         if n < 2:
  3.             return 0
  4.         s = [1] * n
  5.         s[0] = s[1] = 0
  6.         for i in range(2, int(n ** 0.5) + 1):
  7.             if s[i] == 1:
  8.                 s[i * i:n:i] = [0] * len(s[i * i:n:i])
  9.         return sum(s)
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +2 收起 理由
zltzlt + 3 + 3 + 2 188 ms

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-12-24 09:06:26 | 显示全部楼层
我表示我的答案好像五位数就搞不定了,要着,看大佬们发挥了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 09:24:25 | 显示全部楼层
  1. #输出一个数有多少素数
  2. #输入 10--> 输出4,小于10的素数有2,3,5,7,总共4个素数,所以答案是4。

  3. import math

  4. def is_prime(n):  #第一个程序,判断是否为素数
  5.     for i in range(2, int(math.sqrt(n))+1):
  6.         if n % i == 0:
  7.             return False
  8.     return True

  9. def solution(n): # 查找小于n的整数有多少个素数
  10.     if n <= 10 and n >= 2:
  11.         res = [i for i in range(2, n+1) if is_prime(i)]
  12.     elif n <2:
  13.         return False
  14.     else:
  15.         res = [2, 3, 5, 7] + [i for i in range(10, n+1) if i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0]
  16.     #对于大于10的数,为了减少运算次数,去除2,3,5,7。。。的倍数。
  17.         for each in res:
  18.             if not is_prime(each):
  19.                 res.remove(each)
  20.     return len(res)
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 10:18:28 | 显示全部楼层
本帖最后由 沙里爬 于 2019-12-24 10:35 编辑
  1. import math
  2. def is_prime(num):
  3.     for i in range(2,int(math.sqrt(num))+1):
  4.         if num % i ==0:
  5.             return False
  6.     return True

  7. def solution(n):
  8.     a=0
  9.     if n <= 2:
  10.         print(0)
  11.     elif n == 3:
  12.         print(1)
  13.     else:
  14.         for i in range(2,n):
  15.             if is_prime(i):
  16.                 a += 1
  17.         print(a)
复制代码

评分

参与人数 1荣誉 +2 鱼币 +2 贡献 +1 收起 理由
zltzlt + 2 + 2 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 13:30:27 | 显示全部楼层
Stubborn 发表于 2019-12-23 22:11
上了10**9就搞不定了,     

岂止提速一半,看这架势速度比之前几乎快了四倍啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-24 13:53:30 | 显示全部楼层
  1. def p293(n):
  2.     if n > 2:
  3.         l = [2]
  4.         for i in range(3, n):
  5.             for j in l:
  6.                 if i % j == 0:
  7.                     break
  8.             else:
  9.                 l.append(i)
  10.         return len(l)
  11.     elif n == 2:
  12.         return 1
  13.     else:
  14.         return 0
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-5 08:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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