近期做了浙大oj的第1011道题,遇见一件奇怪的事。这道题我用c++和php做,提交后都正确。可是用全然同样的逻辑改写成python代码提交后却产生了Non-zero Exit Code的判题结果。python的这一判题结果大多表示程序在执行过程发生了未捕捉的异常。经重复提交排查后确定未捕捉的异常是IndexError,也就是数组下标越界异常。进一步排查后确定应该是由于在測试用例的树结点中有超过第一行所给的參数k的范围的字母存在。解决方法是在使用结点作为的下标之前先推断该下标是否越界,若越界,则直接return
0。

可是让我奇怪的是为什么这一错误没有在c++和php代码中体现出来?原因是由于在这些语言中根本没有下标越界这一说法!比方以下的c++代码是能够执行,全然没有问题的,仅仅是输出的结果可能是不确定的而已。

#include <iostream>
using namespace std;
int main()
{
int a[2];
cout << a[-1];
return 0;
}

这里数组名a事实上相当于一个常量地址值,a[-1]代码表示的是a这个地址值偏移一个整型变量大小的地址处的内容所表示的整型值。相同以下的php代码也是能够执行的:

<?php
$a = [1,2];
print $a[-1];
?>

输出的结果是一个字符串空串,或许在php中,对于下标越界的元素默认返回空串。

也就是说c++和php代码能通过全然靠的是“幸运的巧合”,c++中越界地址处恰好储存着null,php则恰好返回空串,这种值在后面的推断中恰好可以使得函数终于返回正确的结果。而事实是,在c++和php代码中相同是须要检查是否越界的!

这件事让我又一次认识到了主动检查一些异常,做逻辑保护的重要性。像python,java这类较健壮的语言,对于程序执行时的异常还会自己主动检測和抛出。而像c和c++这类语言则非常可能让程序在错误的状态下“悄无声息”地执行,这样在得到错误的结果后,去确定错误的地方都非常难。编程须要谨小慎微,用户输入的数据是什么都有可能,仅仅有尽可能提前考虑周全,才干避免日后bug的发生。

最后附上我的zoj1011的python代码:

import sys
class React:
leftSig = 0
rightSig = 0
def __init__( self, leftSig, rightSig ):
self.leftSig = leftSig
self.rightSig = rightSig reactTable = [ [ [] for col in range(10) ] for row in range(15) ]
tree = [ 0 for x in range(2100) ]
signalNum = 0
acceptedNum = 0
elementNum = 0
nodeN = 0
def readTable():
global reactTable, tree, signalNum, acceptedNum, elementNum, nodeN
for i in range(signalNum):
for j in range(elementNum):
line = sys.stdin.readline().strip()
a = line.split()
reactTable[i][j] = []
for tmp in range( 0, len(a), 2 ):
reactTable[i][j].append( React( int(a[tmp]), int(a[tmp+1]) ) ) def readTree( level ):
global reactTable, tree, signalNum, acceptedNum, elementNum, nodeN
nodeN = 0
for i in range(level+1):
line = sys.stdin.readline().strip()
a = line.split()
for tmp in a:
tree[nodeN] = tmp
nodeN += 1 def displayTableAndTree( level ):
global reactTable, tree, signalNum, acceptedNum, elementNum, nodeN
print "--------------------"
for i in range(signalNum):
for j in range(elementNum):
for react in reactTable[i][j]:
print react.leftSig, react.rightSig,
print
c = 0
for i in range(level+1):
for j in range(1<<i):
print tree[c],
c += 1
print def judge( signal, eleIdx ):
global reactTable, tree, signalNum, acceptedNum, elementNum, nodeN
if eleIdx >= nodeN and signal >= signalNum-acceptedNum:
return 1
if eleIdx >= nodeN:
return 0
if tree[eleIdx] == '*' and signal >= signalNum-acceptedNum:
return 1
if tree[eleIdx] < 'a' or tree[eleIdx] >= chr(ord('a') + elementNum):
return 0
for react in reactTable[signal][ord(tree[eleIdx]) - ord('a')]:
#try:
if judge( react.leftSig, 2*eleIdx+1 ) and judge( react.rightSig, 2*eleIdx+2 ):
return 1
#except IndexError:
#return 0
return 0 kcase = 1
while 1:
line = sys.stdin.readline().strip()
a = line.split()
signalNum = int(a[0])
acceptedNum = int(a[1])
elementNum = int(a[2])
if signalNum == 0 and acceptedNum == 0 and elementNum == 0:
break
if kcase > 1:
print
print "NTA%d:" %(kcase) readTable()
while 1:
line = sys.stdin.readline().strip()
level = int(line)
if level == -1:
break
readTree( level )
#displayTableAndTree( level )
if judge( 0, 0 ):
print "Valid"
else:
print "Invalid"
kcase += 1

从用python做zoj1011发生Non-zero Exit Code错误说起的更多相关文章

  1. Python 3.6安装yaml时报"AttributeError: module 'pip' has no attribute 'main'"和“Non-zero exit code”错误

    1.Python 3.6安装yaml时一开始报AttributeError: module 'pip' has no attribute错误,根据网上提供的解决方法修改Pycharm安装目录D:\Pr ...

  2. [转]使用 mitmproxy + python 做拦截代理

    使用 mitmproxy + python 做拦截代理   本文是一个较为完整的 mitmproxy 教程,侧重于介绍如何开发拦截脚本,帮助读者能够快速得到一个自定义的代理工具. 本文假设读者有基本的 ...

  3. 使用python做科学计算

    这里总结一个guide,主要针对刚开始做数据挖掘和数据分析的同学 说道统计分析工具你一定想到像excel,spss,sas,matlab以及R语言.R语言是这里面比较火的,它的强项是强大的绘图功能以及 ...

  4. 12岁的少年教你用Python做小游戏

    首页 资讯 文章 频道 资源 小组 相亲 登录 注册       首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...

  5. [原创博文] 用Python做统计分析 (Scipy.stats的文档)

    [转自] 用Python做统计分析 (Scipy.stats的文档) 对scipy.stats的详细介绍: 这个文档说了以下内容,对python如何做统计分析感兴趣的人可以看看,毕竟Python的库也 ...

  6. 这几天有django和python做了一个多用户博客系统(可选择模板)

    这几天有django和python做了一个多用户博客系统(可选择模板) 没完成,先分享下 断断续续2周时间吧,用django做了一个多用户博客系统,现在还没有做完,做分享下,以后等完善了再慢慢说 做的 ...

  7. 用python做中文自然语言预处理

    这篇博客根据中文自然语言预处理的步骤分成几个板块.以做LDA实验为例,在处理数据之前,会写一个类似于实验报告的东西,用来指导做实验,OK,举例: 一,实验数据预处理(python,结巴分词)1.对于爬 ...

  8. 《用Python做HTTP接口测试》学习感悟

    机缘巧合之下,报名参加了阿奎老师发布在"好班长"的课程<用Python做HTTP接口测试>,报名费:15rmb,不到一杯咖啡钱,目前为止的状态:坚定不移的跟下去,自学+ ...

  9. 使用Python做简单的字符串匹配

    由于需要在半结构化的文本数据中提取一些特定格式的字段.数据辅助挖掘分析工作,以往都是使用Matlab工具进行结构化数据处理的建模,matlab擅长矩阵处理.结构化数据的计算,Python具有与matl ...

随机推荐

  1. 【Java基础】选择排序、冒泡法排序、二分法查找

    1.选择排序: //改进后的选择排序,减少交换的次数 public static void sortSelect(int arr[]) { //用于存放最小数的下标 int s; for (int i ...

  2. 《学习opencv》笔记——矩阵和图像处理——cvGEMM,cvGetCol,cvGetCols and cvGetDiag

    矩阵和图像操作 (1)cvGEMM函数 其结构 double cvGEMM(//矩阵的广义乘法运算 const CvArr* src1,//乘数矩阵 const CvArr* src2,//乘数矩阵 ...

  3. Swift编程语言学习1.3——类型安全和投机型

    Swift 是类型安全(type safe )语言.类型安全的语言可以让你清楚地知道代码被处理值类型.假设你需要一个代码String.你绝对不能进去一个不小心传球Int. 因为 Swift 它是类型安 ...

  4. Linux管道通信

    1.Linux内部自己实现了管道的同步,但多个读或者多个写之间的互斥,还需要自己实现.

  5. java设计模式:观察者模式

    package Observer; public class Test { /** * client测试类别 * 观察者模式一般由四部分组成: * 1摘要观察员(教科书被称为一般"Subje ...

  6. hdu 5076 最小割灵活运用

    这意味着更复杂的问题,关键的事实被抽象出来:每个点,能够赋予既有的值(挑两个一.需要选择,设定ai,bi). 寻找所有和最大.有条件:如果两个点同时满足: 1,:二进制只是有一个不同之处.  2:中的 ...

  7. SQL Server 数据库没有有效全部者的三种解决的方法

    问题:     开发的过程中,操作系统出了问题.决定重装系统.可是没有将SQL Server中的数据库文件分离出来,直接将系统格了.在新系统数据库中附加了数据库文件,一切还算正常.但当打开数据库关系图 ...

  8. 超赞的CSS3进度条 可以随进度显示不同颜色

    原文:超赞的CSS3进度条 可以随进度显示不同颜色 现在的WEB已经不是以前的WEB了,传输更大的数据量,有着更加复杂的计算,这就需要利用进度条来提高用户体验,必要时可以让用户耐心等待,不至于因操作卡 ...

  9. android怎么在launcher改动内置apk的icon

    找到launcher下的IconCache中加入变量用来存储要改动apk的包名 及要改动成的icon private String[] className = {"com.google.an ...

  10. MTK6572横屏的调试过程

    电视剧集:系统MTK缺省的系统源代码,Phone模式.底部有三个虚拟按键.需求为,设置成默认横屏,设定一个合理的虚拟按键方案. ------------------------------------ ...