Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 求约化分数的个数_Python - Fatal编程技术网

Python 求约化分数的个数

Python 求约化分数的个数,python,Python,过去两天我一直在研究这个问题。我觉得我离得太近了;但有些东西不太合适。我希望有一双新的眼睛来看完这篇文章——接受任何建议 任务是找到任何分母的完全约化分数的数目。 蛮力在一定程度上起作用,但我需要能够找到10^10以上的结果。最大的挑战在于: 我的代码当前所在的位置: def proper_fractions(n): if n < 1: return 0 numbers = set(range(int(n * 0.5), 1, -1)) prim

过去两天我一直在研究这个问题。我觉得我离得太近了;但有些东西不太合适。我希望有一双新的眼睛来看完这篇文章——接受任何建议

任务是找到任何分母的完全约化分数的数目。 蛮力在一定程度上起作用,但我需要能够找到10^10以上的结果。最大的挑战在于:

我的代码当前所在的位置:

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亿个字符的范围时遇到了内存错误。对于在不遍历整个范围的情况下查找结果,有什么建议吗?