繁体   English   中英

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

[英]IndexError: list index out of range while index exists

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

我的程序从标准输入接收一个 3 到 17 之间的偶数 N。 然后它生成一个包含 N/2 个零和 N/2 个 1 的数组(如 [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 < N < 17 的所有其他值,它正在工作

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

在迭代列表时不要从列表中删除项目。

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

我用一个简单的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 值的最终列表,你会看到......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM