goldbach的猜想算法在特定数字上方显示“列表索引超出范围”

时间:2017-09-02 15:58:57

标签: python list goldbach-conjecture

我正在创建一个程序,用户可以输入4到5000之间的偶数,程序将输出一对素数对列表,这些素数总和了输入中提供的数字。

我的程序可以很好地将所有素数放在一个列表中并检查输入是4到5000之间的偶数。对于小输入它可以很好地工作但是对于较大的输入它表示“列表索引不在范围“我不明白为什么。

这是我使用的代码:(添加评论以帮助)

ColorChangingLabel

对于少数人来说这很有效。例如

//
//  CustomLabel.swift
//  CustomLabel
//
//  Created by Duncan Champney on 4/20/17.
//  Copyright © 2017 Duncan Champney. All rights reserved.
//

import UIKit

let labelColorChangedNotice: NSNotification.Name  = NSNotification.Name("labelColorChangedNotice")
let textColorKey = "textColor"
let backgroundColorKey = "backgroundColor"

class CustomLabel: UILabel {
  static var classLabelColorChangeObserver: Any!

  static var startingTextColor: UIColor?
  static var startingTextBGColor: UIColor?

  override class func initialize() {

    //Have the CustomLabel class add an observer to record changes to the text color and/or background color even if there are no CustomLabel instances on-screen.
    classLabelColorChangeObserver = NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
       object: nil,
       queue: nil ) {
        notification in
        if let textColor = notification.userInfo?[textColorKey] as? UIColor {
          CustomLabel.startingTextColor = textColor
        }
        if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
          CustomLabel.startingTextBGColor = backgroundColor
        }
    }
  }

  var labelColorChangeObserver: Any?

  override init(frame: CGRect) {
    super.init(frame: frame)
    labelColorChangeObserver = addLabelColorChangedObserver()
  }

  required init?(coder: NSCoder) {
    super.init(coder: coder)
    labelColorChangeObserver = addLabelColorChangedObserver()
  }

  deinit {
    if let labelColorChangeObserver = labelColorChangeObserver {
      NotificationCenter.default.removeObserver(observer: labelColorChangeObserver)
    }
  }

  func addLabelColorChangedObserver() {
    if let startingTextColor = CustomLabel.startingTextColor {
      self.textColor = startingTextColor
    }
    if let startingTextBGColor = CustomLabel.startingTextBGColor {
      self.backgroundColor = startingTextBGColor
    }
    labelColorChangeObserver =  NotificationCenter.default.addObserver(forName: labelColorChangedNotice,
      object: nil,
      queue: nil ) {
        [weak self] //Use a capture list to avoid a retain cycle
        notification in

        //Once we're in the notification's closure, capture self strongly, or bail if it's nil.
        guard let strongSelf = self else {
          return
        }

        //If we've been given a textColor, install it in the label.
        if let textColor = notification.userInfo?[textColorKey] as? UIColor {
          strongSelf.textColor = textColor
        }
        //If we've been given a backgroundColor, install it in the label.
        if let backgroundColor = notification.userInfo?[backgroundColorKey] as? UIColor {
          strongSelf.backgroundColor = backgroundColor
        }
    }
  }
}

但是对于像800这样的更大的数字(实际上它的任何数字,如果有帮助的话,由于某种原因超过668)那么它会说“IndexError:list index out of range”

global prime_numbers
prime_numbers=[]
user_number=0
def start():
    for i in range(5000):
        prime_test(i)

def prime_test(a):
    global prime_numbers
    x = True 
    for i in range(2, a):
            while x:
               if a%i == 0:
                   x = False
                   break
               else:
                   x = True
                   break


if x==True and a!=0 and a!=1:
    prime_numbers.append(a)
    #print(prime_numbers[int(len(prime_numbers)-1)])#
    #prints last digit/\ /\ /\ (for testing purposes)#
    if a==4999:
        user_input()
def user_input():
    user_number=input('please enter a whole even number between 4 and 5000:   ')
    #checks if user input is valid#
    try:
        #checks for a number#
        user_number=float(user_number)
        #checks for an integar#
        if user_number!=int(user_number):
            print('that is not a whole number')
            user_input()
        #checks for an even number#
        a=(user_number/2)
        if a!=int(a):
            print('that is not an even number')
            user_input()
        #checks it is inbetween 4 and 5000#
        elif user_number<4:
            print('that is not greater than or equal to 4')
            user_input()
        elif user_number>5000:
             print('that is not less than or equal to 5000')
             user_input()
        #if it is a valid input it procedes to the next section#
        else:
            q=int(user_number)
            goldbergs_conjecture(q)
    #the bit that checks to see if it is a number#
    except ValueError:
        print('that is not a number')
        user_input()
def goldbergs_conjecture(q):
    global prime_numbers
    for i in range(q):
        #serches for the first prime number in the list then the second ect...#
        x=prime_numbers[i]
        #y= user input minus a prime number form the list#
        y=q-x
        #if y is also in the list then it must be prime also so these are printed#
        if y in prime_numbers and x<(q/2):
            print(str(x) + ' + ' + str(y))
        #had to add this seperatly because if they were the same then this /\/\ didnt catch them#
        if y==x:
            print(str(x) + ' + ' + str(y))
#gives the user something to look at whilst the list is generating#    
print('loading...')
start()

我不知道为什么在668之后这不起作用。

3 个答案:

答案 0 :(得分:2)

您正在goldbergs_conjecture()上方range(q)),x=prime_numbers[i],可以是4..5000。

但您正在寻找此值:prime_numbers这是prime_numbers列表的索引。

range(q)列表不能保证与prime_numbers一样长,因为(根据定义)更少素数而不是给定范围内的整数。

在请求输入之前,请尝试打印for prime in prime_numbers: if prime >= q: break ... do something with prime 列表的长度。我打赌它接近668.

相反,您可以尝试以下方式:

q

覆盖小于{{1}}的所有素数。

答案 1 :(得分:0)

它会中断,因为0到5000之间的素数小于5000(如果你在讲述错误的条件时没​​有犯错,那么它可能小于668)。我建议使用第59行使用范围(len(prime_numbers))而不是范围(q)(你也可以使用enumerate函数)

答案 2 :(得分:0)

所以,我最重要的建议:除非你真的需要,否则不要使用try。它会隐藏代码错误。除非你真的需要,否则避免全局变量。它会让你的大脑在一段时间后头晕。

在你的代码中,第二个罪是问题的根源。您正在运行范围(q)中的for循环,该循环指向prime_numbers [i]。绑定这些索引意味着两个列表需要具有相同的大小,或者primenumber应该小于q。在print(i)循环的开头写for i in range(q)并打印(len(prime_numbers))。当我&gt;你会看到脚本中断LEN(prime_numbers)

要避免尝试,请为输入编写正则表达式。 要避免全局,请将列表作为函数参数传递,或在prime_number列表上运行循环。

希望这有帮助。