我试图通过在while循环中使用for循环来获取用户输入并通过针对预定义素数元组的循环运行它。如果我们检查的数字使用modulo的余数为零,我们知道它是数字的一个因子。
我要做的是输出一个数字的所有因子,将这些因子附加到数字列表,最后输出素数以及将素数附加到数字列表。
该程序适用于某一点。但是,当我尝试使用82之类的数字时,它表示只有一个因素,实际上,我的目标是让它说因子是2和41,作为一个例子。
我的问题是我在代码中出错以防止这种情况发生?
#Global tuple and list
prime = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31)
numbers = []
# main function
def main():
# while loop to check on input, and catch value errors
while True:
try:
j = int(input("Enter a positive integer between 1 and 1,000:"))
j = abs(j)
break
except ValueError:
print("Please enter an integer.")
main()
# call factor function, and pass j variable to function
l = factors(j)
#return values from factors function, and print output
print("The factors of {0} are :".format(j), " ".join(map(str, numbers)))
#def factors function
def factors(j):
should_restart = True
#while the loop is running perform calculations
while should_restart:
should_restart = False
for i in prime:
# if j is evenly divided, continue
if j % i == 0:
print("Output: {0}".format(i))
#if j divided by i equals 1, must be prime
if j/i == 1:
numbers.append(i)
continue
#set j to j//i and restart the loop
else:
j = j//i
numbers.append(i)
should_restart = True
break
else:
continue
# call the main function
main()
答案 0 :(得分:1)
几个问题:
您声明要在找到新素数时添加到 prime 元组。但是元组是不可变的,所以你最好把它定义为一个列表。另一方面,添加素数没有太多用处,因为你不需要它们用于低于1000的输入:无论 j 在除以所有其他因素之后将是1还是素数。足够了。在列表中添加另一个素数是没有用的。
对main
的递归调用是不必要的,并且一旦您使用无效输入回答,将使输入提示出现太多次。只需离开该呼叫 - while
循环将完成所需的操作。
由于数字是函数因子产生的列表,最好让它成为函数的返回值,而不是将其定义为全局变量
变量 should_restart ,以及它上面的循环导致不必要的许多比较:你应该只在循环中坚持使用相同的除数,直到除数不再除以给定的数字。你也应该总是进行分工。有了这样的算法,就不需要再次尝试以前的除数。
条件j/i == 1
很奇怪,因为它等同于j == i
。虽然这意味着 j 是素数,但它可以与其他情况相结合。相反,只要j > i
,就可以通过退出循环来节省一些费用。然后,在循环之后,您仍然具有大于1的 j 值,您可以假设它是一个因素(参见下一点)。
由于 prime 列表中没有所有素数,因此必须保护代码不会产生错误的结果,因为这些数字只包含不在该列表中的素因子。这是通过将最大输入限制设置为1,000来实现的。但是您需要强制执行此限制,并拒绝违反此限制的输入。您还可以通过拒绝大于 prime 列表中最大连续素数(+2)的乘积的输入来使其更通用。
以下是改编的代码:
prime = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31)
# define the maximum value that can be input
max_input = (prime[-1]+2)**2-1
# don't define numbers as global
def main():
while True:
try:
j = int(input("Enter a positive integer between 1 and {}:"
.format(max_input)))
if j >= 1 and j <= max_input: # check the input is in valid range
break # OK!
except ValueError:
print("Please enter an integer.")
# don't call main recursively here, just let the loop do its job
numbers = factors(j) # return value is list of factors
print("The factors of {0} are :".format(j), " ".join(map(str, numbers)))
def factors(j):
numbers = [] # don't make this a global, but a return value
for i in prime:
if i > j: # exit when there is no probability for finding another factor
break
# if i is divisor of j, log and remove that factor
while j % i == 0: # keep repeating
# i is prime and a divisor, so add it as a factor
numbers.append(i)
# always set j to j//i and try again with the same divisor
j = j//i
if j > 1 and j not in prime: # need to add this non-listed prime as factor
numbers.append(j)
return numbers # return the list of factors
main() # call the main function