Reducing the running time in Python

时间:2015-06-15 14:35:27

标签: python

This Program checks how many prime integers between two ranges and their sum should also be prime. How can I reduce the running time?. HERE IS THE OPTIMIZED PRIME FUNC (eprime). BUT SILL IT EXCEEDES TIME WHICH IS 3 SEC HOW CAN I OPTIMIZE IT MORE? i really did my best but i cant find any other way.

import math
def eprime(num):
    if num < 2:
        return False
    if num % 2 == 0:
        return num == 2
    div = 3
    while div * div <= num:
        if num % div == 0:
            return False
        div += 2
    return True

x=input()
array=[]
count=0
counter=0
x=int(x)
for i in range(0,x):         # getting input from user and the ranges
    y=input().split()
    size=len(y)-1
    a=int((y[0]))
    b=int(y[size])+1

    for num in range(a,b):  # iterating on the ranges to check each number=prime?
        if eprime(num):
         num2=str(num)
         size3=len(num2)
         if(size3>=2):
          for j in range (0,size3):    # count= sum of num. if (11) then count=2
            count+=int(num2[j])
            num=count 
          if  eprime(num) and (num!=0):  # if count=prime then increment counter
            counter+=1

          count=0 
         else:
          counter+=1

    array.append(counter)
    counter=0
size2=len(array)
for i in range (0,size2):
   print(array[i])


////////////////////////////////////////////////////////////////   

Expected:

        sample input: 2
                      1 9
                      2 5
        sample output: 4
                       3

1 个答案:

答案 0 :(得分:1)

您提出两个我将在下面总结的问题:

  1. 素数测试的最快方法是什么? 答:嗯,这是this问题的副本。检查Alexandru的答案。

  2. 为什么您的代码没有长距离运行。检查你的身份。这太糟糕了。但请密切关注这段代码。

  3. (第33行附近):

    if  eprime(num)==True and (num!=0):
            counter+=1
            count=0
    

    只有当你的号码成为素数时才会计数0。嗯,这是错误的,因为在下一个循环中,计数值不应该是零。这句话应该是不合时宜的。

    if  eprime(num)==True and (num!=0):
            counter+=1
    
        count=0
    

    这解决了这个问题。

    我的其他想法:

    1. 查看此代码块:
    2. (第29行附近):

      for j in range (0,size3):
               count+=int(num2[j])
               num=count   <-- Value assigned to `num` 
      
      
      
      if  eprime(num)==True and (num!=0):
              counter+=1
              count=0 
      

      但是你已经为循环变量定义了num。 for num in range(a,b): 现在,您再次为num分配值。为什么?

      虽然在您的情况下这不会导致任何问题,但请使用尽可能多的变量。将其分配给其他变量numx。因为它使您的代码看起来更好并且错误的可能性更小。

      1. 在将代码发布到stackoverflow之前,您必须始终美化您的代码并使其更长。这使您的问题更容易理解并且更容易回答。
      2. 编辑(如何更快地检查你的素数):

        您的代码正在执行两项主要任务:

        1. 将数字除以下面的所有内容。例如6除以2,3,4和5.
        2. 添加数字位数以检查其总和是否为素数。
        3. 第二点没有经过很多循环,因此可以安全地忽略它。 (现在)。

          关于第一点,请执行以下操作:

          1. 你知道如果把东西除以2,那么检查4,6,8等等就浪费了。所以请立即避免检查任何偶数。
          2. 同样,如果数字已被3整除,则检查6,9等没有意义。步骤1和2中的模式是不要尝试检查基数的倍数。
          3. 只检查循环中数字的平方根。例如。如果你要检查的是40号。那么40的平方根大约就是7.所以如果任何数字直到7还没有划分40,那么它保证7之后的任何数字肯定不会除40。所以它的意义是超过7
          4. 我建议您尝试在某种程度上减少样本空间。例如。如果您的范围是1到100,请创建一个包含所有数字1到100的列表。然后启动循环并尝试从中删除一些数字。例如。如果你愿意,可以交叉1,2,3,5,7和更多的倍数。你添加的越多,你的机会就越大,因为那样你只会浪费时间进行相等测试而不是循环。最后,您手中的列表将仅包含那些更有可能成为素数的数字。 事实上,如果您打算多次运行此程序,您可以考虑预先编译结果,例如100,000,并在每次运行中使用此列表。

            然后还应用规则编号3.这应该使您的程序比现在快得多。

            第4点,这一切都变得非常严重: 现在,如果您仍需要更多功率,请注意检查素数的功能与程序无关。即你只是传递数字,它给你真假。因此,您可以在许多线程中运行此函数,这应该可以提高程序的速度。