Python 求约化分数的个数
过去两天我一直在研究这个问题。我觉得我离得太近了;但有些东西不太合适。我希望有一双新的眼睛来看完这篇文章——接受任何建议 任务是找到任何分母的完全约化分数的数目。 蛮力在一定程度上起作用,但我需要能够找到10^10以上的结果。最大的挑战在于: 我的代码当前所在的位置:Python 求约化分数的个数,python,Python,过去两天我一直在研究这个问题。我觉得我离得太近了;但有些东西不太合适。我希望有一双新的眼睛来看完这篇文章——接受任何建议 任务是找到任何分母的完全约化分数的数目。 蛮力在一定程度上起作用,但我需要能够找到10^10以上的结果。最大的挑战在于: 我的代码当前所在的位置: def proper_fractions(n): if n < 1: return 0 numbers = set(range(int(n * 0.5), 1, -1)) prim
def proper_fractions(n):
if n < 1:
return 0
numbers = set(range(int(n * 0.5), 1, -1))
primes = []
while numbers:
p = numbers.pop()
primes.append(p)
numbers.difference_update(set(range(p * 2, n + 1, p)))
counter = n
for num in primes:
if n % num == 0:
counter = counter - (n//num)
n = n//num
if num >= (n ** 0.5):
break
if n == 1:
return counter
elif n > 1:
return counter - (counter // n)
def正确分数(n):
如果n<1:
返回0
数字=设置(范围(整数(n*0.5),1,-1))
素数=[]
而数字:
p=numbers.pop()
素数追加(p)
数字。差异_更新(设置(范围(p*2,n+1,p)))
计数器=n
对于素数中的num:
如果n%num==0:
计数器=计数器-(n//num)
n=n//num
如果num>=(n**0.5):
打破
如果n==1:
返回计数器
如果n>1:
返回计数器-(计数器//n)
您只需检查提供的分母,查看gcd是否为1,是否输出到列表,然后返回该列表的长度
def proper_fractions(n):
def gcd(x,y):
while y:
(x, y) = (y, x % y)
return x
if n <= 1:
return 0
else:
count = 0
for num in range(1,n):
denom = gcd(n,num)
if denom == 1:
count += 1
return count
def正确分数(n):
def gcd(x,y):
而y:
(x,y)=(y,x%y)
返回x
如果调用了n您需要计算的数字,则n
的数字在1
和n
之间进行共线性
如果n
的素数分解为:
,
其欧拉惯性函数为:
在伪代码中计算它的算法:
φ=1
m=n
- 对于每个素数
p
小于或等于sqrt(n)
:
- 如果
m
除以p
:
- 将
φ
乘以p-1
- 将
m
除以p-1
- 而
m
除以p
:
- 将
φ
乘以p
- 将
m
除以p
- 如果
m>1
:
- //注意,此时
m
必须是n
大于sqrt(n)
- 将
φ
乘以m-1
您应该使用Euler的toticent函数,正如用户Anton已经说过的那样。这里有一个解决问题的方法。我在代码中添加了一些注释
def proper_fractions(n):
distinct_prime_factors = set() # use set to avoid duplicates
totient_function = n
if n == 1:
totient_function = 0
else:
i = 2
while i*i <= n:
if n % i == 0:
distinct_prime_factors.add(i)
n = n/i
else:
i += 1
if n > 1:
distinct_prime_factors.add(n) # picks up prime factors > sqrt(n)
if len(distinct_prime_factors) == 0: # empty set means denominator is prime
totient_function = n - 1
else:
for p in distinct_prime_factors:
totient_function = (totient_function*(p - 1))/p
return totient_function
def正确分数(n):
distinct_prime_factors=set()#使用set避免重复
ToClient_函数=n
如果n==1:
ToClient_函数=0
其他:
i=2
而i*i 1:
不同的素数因子。添加(n)#选取素数因子>sqrt(n)
如果len(不同的素数因子)=0:#空集表示分母为素数
ToClient_函数=n-1
其他:
对于不同的素数因子中的p:
totient_函数=(totient_函数*(p-1))/p
返回到客户端函数
Euler的toticent函数使用不同的素因子。这就是为什么最好使用集合而不是列表,因为集合不允许重复的元素
此外,在while循环之后,如果n大于1,则将n添加到素数因子集中是很重要的。这是因为只要素数因子大于n的平方根,while循环就会终止。例如,考虑数字77。while循环将拾取7,因为7*7=49,小于77。但是,它不会拾取11,因为11*11=121,大于77。为什么您认为您的距离很近?您尝试过哪些测试用例,哪些失败了?所有测试用例都是正确的-n=1、2、4、8、15。然而,n=25返回16,当它应该返回20时。谢谢你,凯尔,我感谢你的快速响应!我的第一次尝试就是沿着这些路线;(您的运行速度要快得多…)但我在遍历超过10亿个字符的范围时遇到了内存错误。对于在不遍历整个范围的情况下查找结果,有什么建议吗?