繁体   English   中英

如何找到 GCD 等于 1 并且这些数字小于 python 中给出的数字

[英]How to find numbers which GCD equal to 1 and those numbers are less than given in python

我正在尝试编写代码,它给你的数字小于给定或输入的数字,它们的 GCD 等于 1。我写了这段代码,但我不知道是否有效或为什么不有效。 例如,我选择了数字 6。数组将类似于 [1,2,3,4,5]。 我的观点是过滤 GCD 等于 1 的数字。所以它将是 [1,5]。 他们的数量是两个。

a是输入数字, b是小于输入 1 且不等于 0 的列表数字。 然后打印出来。

a = int(input("enter number \n"))
b = list(range(1,a))
print (b)

然后我将列表转换为数组

for i in range(1, len(b)):
        b[i] = int(b[i])

然后这个

        r = a % b[i]

        q = int ( a / b[i])

        while(r!=0):
            
            a = b[i]

            b[i] = r

            q = int ( a / b[i])

            r = a - (b[i] * q)


            print ( a , b[i], r )
            break

我是初学者。

关于您的代码的一些评论:

  • 您应该始终将这样的代码封装在 function 中; 写一个 function find_coprimes它接受一个参数n并返回你想要的列表;
  • 为了测试你的 function 的正确性,写一个参考 function find_coprimes_ref它做同样的事情,但使用库函数来确保没有错误; 这将教你寻找相关的库函数,你可以比较两个函数的结果;
  • for i in range(1, len(b)): b[i] = int(b[i])的初始循环是错误的,原因有二; 1) 它没有效果,因为b已经是一个整数列表。 2) 列表是 0 索引的,因此对b的每个元素的正确迭代将是for i in range(0, len(b)):或简单地for i in range(len(b)):
  • 您的代码有两个嵌套循环:一个while循环在for循环中重复执行; 每当有这样的嵌套循环时,您必须确保变量在外部循环开始时按照您希望它们的方式重新初始化; 在您的情况下,变量awhile循环内被修改,因此,它的值在for循环的下一次迭代开始时是错误的。
  • while循环末尾的break语句没有意义; 通常, break语句仅在封装在if条件中才有意义,并且它们充当循环条件的替代品; 但是总是可以在不使用break的情况下编写循环,我建议你完全忘记break
  • 使用qr执行 gcd 计算后,您的代码缺少一些东西来告诉它是否在最终结果中保留b[i]
  • 对于 python 中的 integer 划分,最好使用//而不是int(... /...)

代码

import math

def find_coprimes_ref(n):
  return [x for x in range(1,n) if math.gcd(x,n) == 1]

def find_coprimes(n):
  result = []
  for x in range(1, n):
    a = n
    b = x
    r = a % b
    q = a // b
    while (r > 1):
      a = b
      b = r
      q = a // b
      r = a - b * q
    if (r == 1):
      result.append(x)
  return result

# TESTING

for n in range(1, 31):
  coprimes_ref = find_coprimes_ref(n)
  coprimes = find_coprimes(n)
  if coprimes_ref != coprimes:
    print(n, coprimes_ref, coprimes)

请注意我的代码如何从不修改循环中的nx 相反,我制作了名为ab的副本并修改了这些副本。

进一步封装

请注意 function find_coprimes_ref 如何比find_coprimes find_coprimes_ref容易阅读? 这不仅仅是因为我们使用了库 function math.gcd 这是因为库 function math.gcd是一个干净封装的 function,其名称清楚地解释了它的作用。 您的代码在 for 循环中包含一个 while 循环,并且很难跟踪每个变量和正在发生的所有事情,并且不会丢失我们的子目标和总体目标。

为了使您的 function 更易于阅读、编码和调试,您应该将 gcd 计算封装在名为gcd的 function 中:

def gcd(a, b):
  r = a % b
  q = a // b
  while (r > 1):
    a = b
    b = r
    q = a // b
    r = a - b * q
  return r

def find_coprimes(n):
  result = []
  for x in range(1, n):
    if gcd(a, b) == 1:
      result.append(x)
  return result

# TESTING GCD

for b in range(1, 31):
  for a in range(b, 31):
    r1 = math.gcd(a, b)
    r2 = gcd(a, b)
    if r1 != r2:
      print(a, b, r1, r2)

# TESTING FIND_COPRIMES

for n in range(1, 31):
  coprimes_ref = find_coprimes_ref(n)
  coprimes = find_coprimes(n)
  if coprimes_ref != coprimes:
    print(n, coprimes_ref, coprimes)

代码现在更容易调试的原因有两个:

  • gcdfind_coprimes的逻辑完全分开,这意味着您可以清楚地推理gcd而不会弄乱find_coprimes中使用的列表和其他变量的风险;
  • 您可以分别测试您的 function gcd和您的 function find_coprimes 如果某些东西不能正常工作,你会更准确地知道在哪里寻找问题,而不是仅仅想“好吧,代码中的某处有问题,但我不知道在哪里”。

您的代码中有一些错误,例如在 while 循环中break 我重构了您的代码并添加了内置math.gcd function 来比较结果。

import math

def math_inbuilt_gcd(a, b):
    gcd_one = []
    for x in b:
        if math.gcd(x, a) == 1:
            gcd_one.append(x)
    print("gcd_one_math_fun:", gcd_one)


def gcd_my_fun(a, b):
    gcd_arr = []
    for i in range(len(b)):
        x, y = a, b[i] # taking x, y just to make things clear
        r = x % y # remainder
        q = int(x / y) # quotient

    while(r != 0):
        x = y
        y = r
        q = int(x/y)
        r = x % y

    if y == 1:
        gcd_arr.append(b[i])

    print("gcd_one_my_fun:", gcd_arr)


a = int(input("Enter number: "))
b = list(range(1, a))
print("b:", b)

math_inbuilt_gcd(a, b)
gcd_my_fun(a, b)

Output:

Enter number: 10
b: [1, 2, 3, 4, 5, 6, 7, 8, 9]
gcd_one_math_fun: [1, 3, 7, 9]
gcd_one_my_fun: [1, 3, 7, 9]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM