首页 > 解决方案 > 应用 random.sample() 大整数输入时如何修改代码以避免溢出错误?

问题描述

对于大整数输入,程序显示“OverflowError: Python int too large to convert to C ssize_t”(这是测试所有边界情况下程序效率所必需的)。我该如何处理这个错误?

import random
import sys
 
sys.setrecursionlimit(10**6)

t=int(input())

N =[]
K =[]
B =[]
while 1<=t<=20 :
    n,k,b= input().split()
    n,k,b = [int(n), int(k),int(b)]
    t=t-1
    N.append(n)
    K.append(k)
    B.append(b)
if b >= 1 and b <= (10**5) and n >= 1 and k <= (10**18) and b <= k :
   i1=0
   for val in K:
        n=N[i1]
        k=K[i1]
        b=B[i1]
        i1=i1+1
        print('i entered for loop')
        if sum(list(range(1, k+1))) >= n:
            print(' i entered if loop')
            def possibilities():
                     p = random.sample(range(1, k+1), b)
                     if sum(p) == n:
                        for i in range(0,b):
                            print(p[i],end=" ")
                        print("\r")
                     else:
                         possibilities()
             
            possibilities()         
            
                        
        else:
          print(-1)

       

标签: pythonrandominput

解决方案


根据文档random.randrange有效

在任意大的范围内

所以不要这样做:

    p = random.sample(range(1, k+1), b)

您可以执行以下操作:

    p = [random.randrange(1, k+1) for _ in range(b)]

并让它适用于任意大的k. 请注意,当k小于2**63-1(假设您使用的是 64 位机器)时,使用sample可能会更快。

作为您的代码显然失败的示例,random.sample(range(2**63), 1)给出

溢出错误:Python int 太大而无法转换为 C ssize_t

while[random.randrange(2**63) for _ in range(10)]给了我一个包含一个大数字的列表。

我还注意到:

  1. 您的代码中涉及的分布似乎可以让您及时给出一个很好的分析O(t)答案
  2. 您可能还想改进您的检查以使其永远停止运行,例如n,k,b = [2,2,2]似乎通过了所有检查但将永远旋转
  3. 鉴于 Python 不是“尾递归”,使用for循环将比递归更有效

推荐阅读