查找三元组代码无法调试其抛出的垃圾值

Finding triplets code fails in debugging its throwing garbage value

我已经编写了一个测试脚本来在 python 列表中查找三元组 这样在一个列表中,如果任何两个项目的总和&有总和作为列表的项目存在于列表中 必须注意那对是三胞胎 现在我的任务是计算列表中存在多少个三胞胎 关于这个问题的更多解释可以参考here

现在可以通过两个循环(O(n^2))方法轻松完成,但为了使时间复杂度接近 O(n),即仅遍历列表项 n 次 其中 n 是没有。元素列表有

Mine Approach is:

我正在使用 while 循环 i 是从 0 到 n 而 j 将从 i+1 到 n 如果引用第二个元素索引的 j 交叉到 n(最后一个元素)然后更新 我已经完成了,所以现在我可以跳过当前元素,因为没有三元组,现在要注意 i+1 到 n 而 j 已经是 i+1 使它 j 总是领先 j=i+1

Respective python code for Approach Is:

def check(A,n):
 i=0
 j=i+1
 count=0
 while i<n:
  if j==n:
   i+=1
   j=i+1
  temp=A[i]+A[j]
  if temp in A:
   count+=1
   j+=1  #updation for not going to same loop secondth time
  else:
   j+=1
 return count 

def main():
 A=[]
 n=int(input('Define length:'))
 for a in range(0,n):
  x=int(input('Array[{}]'.format(a)))
  A.append(x)

 c=check(A,n)
 print(c)



main()

方法很好,但代码不起作用,只是为了解决它而滞后我调试了代码here 并发现 count 变量最终返回垃圾值 local-variable-debugged-output & full-o/p

Note:(Optional)原题缺少Count的正确取值,count变量以垃圾回收的形式返回(可以看调试图o/p posted) 在得到用户@PeterdeRivaz 的建议后 很明显,由于循环是 运行 我们没有更新 i 索引以向前移动并最终处于永无止境的情况,因为我只是在 j 变为 == n 时更新,即最后一个索引(用于比较所有对) 并且其他条件也不是真的 所以根据建议,我将 j+=1 更新为两个条件,即使它失败了,即使它通过了这些方式,遍历是肯定的 然后在我遇到超出索引的问题后,我 post 在我落后的地方解决了这个问题,但这个问题的真正解决者是@PeterdeRivaz 对你的一个巨大的呼喊,我知道在 post 可能会违反荣誉守则我不确定 但我写这篇笔记是为了让其他成员能够理解问题是什么以及它变成了什么,所以我 post 编辑了这个答案。

如果找到解决方案,即 temp in A 为真,那么您将增加计数,但不会更改循环变量 i 或 j。这意味着循环将在完全相同的位置重复下一次迭代,因此不会取得任何进展。

我建议更改代码,使 j+=1 不在 else 分支中,但总是会发生。

顺便说一下,为了加速 temp in A 测试,您可能应该将 A 转换为集合 B=set(A)

最后,通过大量的调试会话,我终于知道我的代码在哪里滞后了 在最后几次迭代中,当 j 位于最后一个索引而 i 位于倒数第二个索引 condition j==n 变成:n==n 然后我更新到最后一个索引,而 j 比最后一个索引交叉更多(见下文)

if j==n:
 i+=1
 j=i+1

无法再处理迭代,因为我已经成为最后一个元素,由 j=i+1 超出索引 由于下一条语句 temp=A[i]+A[j] 被执行,并且由于列表中不存在 j 索引,它会抛出错误 为了解决它,我只需要容忍这种特殊情况,当遇到 j 是最后一个索引时,但是由于列表遍历逻辑 i+=1,j=i+1(i 的唯一更新)j 索引被更新为不存在的索引数组A 结果,我创建了一个嵌套的 if 来仔细检查是否遇到上述条件,当它做我唯一需要做的就是使用 break

跳出循环
if j==n:
 i+=1
 j=i+1
 if j==n:
  break

通过这个小小的改进,代码现在 运行 非常好 这是完整的代码片段

def check(A,n):
 i=0
 j=int(i+1)
 n=int(n)
 count=0
 
 while i<n:  
  if j==n:
   i+=1
   j=i+1
   if j==n:
       break
   
  temp=A[i]+A[j]
  if temp in A:
   count+=1
   j+=1
  else:
   j+=1
 return count 

def main():
 A=[]
 n=int(input('Define length:'))
 for a in range(0,n):
  x=int(input('Array[{}]'.format(a)))
  A.append(x)
 c=check(A,n)
 print(c)



main()

它工作得很好,如果此代码在任何异常情况下失败,请告诉我

Note: 还有那些建议的成员,说将 list 转换为 Set 以将时间复杂度提高到 O(1) 好吧我确实尝试过这个但是因为 Set 数据结构是无序的 DS 所以使用索引值 i,j 访问它时 它会抛出错误 这是显而易见的,所以如果你知道如何去做 post 下面的答案,但即使在最坏的情况下,答案仍然是 O(n) ,但它应该是 O(nlog n) 但是O(n^2) 不可接受