如果python中的语句仅通过更改条件位置而起作用,

问题描述

我刚在python中遇到一个奇怪的问题: 下面是对合并排序算法的一种表示,如果尝试运行它,它会给我一个索引错误。

def mergesort(s1,s2,S):
    i,j = 0,0
    while i+j < len(s1)+len(s2):
        if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
            S.append(s1[i])
            i += 1
        else:
            S.append(s2[j])
            j += 1
    return S

s2 = [1,5,7]
s1 = [2,3,4,6,8]
S = []
print(mergesort(s1,S))

该程序的输出为:

Traceback (most recent call last):
  File "new.py",line 15,in <module>
    print(mergesort(s1,S))
  File "new.py",line 4,in mergesort
    if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
IndexError: list index out of range

现在只需在j == len(s2)语句中键入if即可,程序运行正常:

def mergesort(s1,0
    while i+j < len(s1)+len(s2):
        if j == len(s2) or (i < len(s1) and s1[i] < s2[j]):
            S.append(s1[i])
            i += 1
        else:
            S.append(s2[j])
            j += 1
    return S

s2 = [1,S))

输出:[1,2,7,8]

这真让我感到惊讶,因为这两个程序完全相同,但是前一个给我一个错误。

此外,有问题的程序在c ++中可以正常运行:

#include <iostream>

using namespace std;

int main() { 
    int s1[10] = { 2,8 },s2[10] = { 1,7 },s[20],i = 0,x = 0;
    while (i + j < 8) {
        if ((i < 5 && s1[i] < s2[j]) || j == 3) {
            s[x++] = s1[i];
            i++;
        } else {
            s[x++] = s2[j];
            j++;
        }
    }
    for (int i = 0; i < 8; i++) {
        cout << s[i];
    }
     return 0;
}

输出:12345678

为什么在python中给我一个错误的程序在c ++中运行完全正常? python的if语句与c ++的if语句工作不同吗?

解决方法

第一个python程序确实不正确:如果if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):s2[j]之前达到j的长度,s2将导致对i的无限制访问。到达s1的结尾。

解决方法是在您正确发现自己之前,先测试j == len(s2) 之前 (i < len(s1) and s1[i] < s2[j])

C ++程序具有相同的问题,但是C ++不会检测到超出范围的访问。读s2[3]只是具有未定义的行为,在您的情况下,只会返回未指定的值。无论如何,由于j == 3,该测试将评估为true,因此算法将输出预期结果。

未定义的行为有时会产生预期的结果,而不会引起注意。但是在更大的分配数组上使用该算法可能会产生明显的副作用,例如分段错误。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...