在Python3中输入所有数字的最快方法?

时间:2014-08-18 10:22:02

标签: python python-3.x

对于SPOJ上的问题,我的问题是“超出时间限制”错误。因为我认为这个错误是因为输入很大,所以我需要你的帮助来找到处理大输入的最佳方法。

让我解释输入和我的代码。

  

输入

     

输入的第一行包含测试用例t(1 <= t <= 100)。它是   然后是2 * t行,每个测试用例2行。第一行输入   对于每个测试用例,包含数n(0 <= n <= 10 ^ 6),然后是n   下一行中的元素。每个数字从-10 ^ 3到+ 10 ^ 3

以下是输入

的示例
3 #number of test cases (t)

4 #number of elements that will come to next line (n) (this can be 10^6)

2 1 2 2 #this line may have 10^6 numbers

6 

1 1 1 2 2 2

5

1 2 4 5 1

问题是询问一个数字是否超过n // 2次。 示例输出

YES 2  #because 2 appears 3 times.

NO     # no number occurs more than n//2 times

NO     # no number occurs more than n//2 times.

有关此问题的更多信息

  

添加者:Troika ::字节日期:2010-02-18时间限制:1s来源   限制:50000B内存限制:256MB集群:金字塔(Intel Pentium III   733 MHz)语言:除了以下所有内容:PERL 6

http://www.spoj.com/problems/MAJOR/

最后我的代码。

from collections import Counter
import re

def major(n):
    s = input().split() # get all the numbers one by one
    y = (Counter(s)).most_common()[0]  # Count how many times a number occurs in the input and return the most occurence with its value in a pair.
    if y[1]> n//2: #if the most occurence is more than half of the "n"
        return "YES " + y[0] # return the value belongs to the most occurence
    else:
        return "NO"

for i in range(int(input())): #get the number of test cases
    print(major(int(input()))) # calling the function to get the "n"

我想知道s = re.findall(r'\d+', input())是否对于像一百万的数字来说速度太慢,我已将输入部分更改为s = input().split()但是,我再次收到“时间限制超出“错误。它可能与Counter函数有关吗?

1 个答案:

答案 0 :(得分:2)

您可以通过以下方式对其进行优化:

  • 禁用垃圾回收:

    import gc
    gc.disable()
    
  • 避免string.split并使用re.finditer

  • 避免使用range并使用while循环。

  • 使用sys.stdin.readline()代替input(速度更快)和sys.stdout.write打印内容。

  • 当数字的出现次数大于n // 2时停止(同样,仅计算一次)。您可以使用collections.defaultdict并在更新前检查事件。

  • 避免使用这些功能,只需将所有内容放在一个循环中。

  • 有时在main函数中导入库可以节省时间。

不幸的是,Martijn Pieters指出,Python 3.x没有可接受的解决方案,Python 2.x只有一个解决方案,并且根据解决它的内存量,numerix可能已经使用{ {1}}(PyPy所基于的库,比CPython快得多)。不幸的是,由于psyco已经停止,它的支持已被删除在集群上,问题被执行,因此可能没有人会设法发送已接受的解决方案,直到他们重新启用psyco或PyPy支持。

实施例

psyco

修改

我发送了一封电子邮件给 numerix ,他确认他的解决方案使用了import gc gc.disable() # import psyco # psyco.full() def main(): from collections import defaultdict from sys import stdin, stdout import re pattern = re.compile(r'\d+') times = int(stdin.readline()) while times: times -= 1 threshold = int(stdin.readline()) // 2 vals = defaultdict(int) for x in pattern.finditer(stdin.readline()): n = int(x.group(0)) rep = vals[n] + 1 if rep > threshold: stdout.write('YES ' + str(n) + '\n') break else: vals[n] = rep else: stdout.write('NO\n') if __name__ == '__main__': main()

  

是的,我的MAJOR解决方案使用psyco。我没有尝试没有psyco,但由于没有其他的AC Python解决方案,我想它不可能或只有重度i / o优化。