IndexError:存在索引时列出索引超出范围

时间:2018-08-29 19:08:09

标签: python python-3.x

对于NOI 2018(荷兰国家信息奥林匹克),我需要解决编码问题。

我的程序从stdin接收一个介于3和17之间的偶数N。 然后,它生成具有N / 2个零和N / 2个零的数组(例如[0,0,0,1,1,1]) 然后,它按字典顺序生成该数组的所有排列,并将其存储在另一个数组中。 然后它将删除重复项,因为我生成所有排列的函数都会生成重复项。

它会删除所有不满足以下条件的所有项目:彼此相邻的相同值不得超过两个。

然后返回剩余的项目数,然后输出每个项目。

这是我的代码:

N = int(input('N:'))

def genPermutations(num, index):

    if len(num) - 1 == index:

        if num not in rows:

            rows.append(num)

    for i in range(index, len(num)):

        newList = num[:]
        temp = newList.pop(i)
        newList.insert(index, temp)
        genPermutations(newList, index + 1)

num = []
rows = []

for j in range(2):

    for i in range(int(N) // 2):

        if j == 0 :

            num.append(0)

        else:

            num.append(1)

genPermutations(num, 0)
rows = list(set(map(tuple, rows)))

for i in reversed(range(len(rows))):
    rows[i] = list(rows[i])

    for j in range(len(rows[i]) - 2):

        if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:

            rows.pop(i)

        elif rows[i][j] == 0 and rows[i][j + 1] == 0 and rows[i][j + 2] == 0:

            rows.pop(i)

print(len(rows))

for i in reversed(range(len(rows))):

    string = ''

    for j in range(len(rows[i])):

        string += str(rows[i][j])

    print(string)

现在的问题是,当我输入N = 6时,程序将返回错误。 在3

2 个答案:

答案 0 :(得分:0)

for i in reversed(range(len(rows))):
    ...
        rows.pop(i)

在遍历列表时不要从列表中删除项目。

len()在循环的顶部仅计算一次,因此,在循环执行期间缩短列表时,最终会尝试迭代不再存在的项目。

答案 1 :(得分:0)

我用简单的print语句跟踪了问题:

for i in reversed(range(len(rows))):
    rows[i] = list(rows[i])
    for j in range(len(rows[i]) - 2):
        print("i=", i, "j=", j, len(rows), "rows;", len(rows[0]), "cols")
        if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:
            rows.pop(i)

输出:

i= 19 j= 0 20 rows; 6 cols
i= 19 j= 1 20 rows; 6 cols
i= 19 j= 2 20 rows; 6 cols
i= 19 j= 3 19 rows; 6 cols

...这是您的问题。您仍在尝试处理该行时从表中删除了该行。执行此操作时,还需要从break循环中退出j。在两个子句中:

    if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:
        rows.pop(i)
        break

    elif rows[i][j] == 0 and rows[i][j + 1] == 0 and rows[i][j + 2] == 0:
        rows.pop(i)
        break

这将产生14个排列的预期答案。

这仅在N=6上失败,因为这是唯一删除最终排列的集合。打印出每个N值的最终列表,您会看到...