近期做了浙大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. 玩转Web之Jsp(一)-----jsp中的静态包含(<%@include file="url"%>)与动态包含(<jsp:include>)

    在jsp中include有两种形式,其中<%@include file="url"%>是指令元素,<jsp:include page="" f ...

  2. unity3d 各功能的运行秩序,打回来,订购,的次数

    Update 当MonoBehaviour启用时,其Update在每一帧被调用. 仅调用一次(每帧) LateUpdate 当Behaviour启用时,  每帧调用一次: FixedUpdate 当M ...

  3. Hibernate在关于一对多,多对一双向关联映射

    [Hibernate]之关于一对多,多对一双向关联映射 因为一对多.和多对一的双向关联映射基本上一样,所以这里就一起写下来! Annotations配置 @Entity @Table(name=&qu ...

  4. 容易centos配置docker维修

    首先.由于docker实施需要linux某些组件支持本身和内核特性.所以一定要确保centos版本号大于6,和内核版本号大于2.6.32-431.可轻松升级centos6到最新的版本号. sudo y ...

  5. SQL Server高可用——日志传送(4-1)——概论

    原文:SQL Server高可用--日志传送(4-1)--概论 本文作为学习总结,部分内容出自联机丛书及其他书籍 日志传送是什么? SQLServer 2012之前(2012出现了AlwaysOn), ...

  6. JAVA 统计字符串中中文,英文,数字,空格的个数

    面试题:输入一行字符,分别统计出其中英文字母.中文字符.空格.数字和其它字符的个数 可以根据各种字符在Unicode字符编码表中的区间来进行判断,如数字为'0'~'9'之间,英文字母为'a'~'z'或 ...

  7. hadoop-HBase-observer的一个样例

    hbase(main):021:0> describe 'users' DESCRIPTION                                                   ...

  8. Jquery在线咨询地址

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type=&quo ...

  9. 【JAVA】【NIO】5、Java NIO Scatter / Gather

    标题手段Java NIO该分散体浓缩 Java NIO内置支持分散与收集.的概念主要用于信道分散聚集的读写. 读出的分散体的一个通道被读多个数据buffer在.因此.数据分散到多个buffer中. 对 ...

  10. 怎么样CSDN Blog投机和增加流量?

    所谓推测装置,以提高它们的可见性,最近比较顾得上,这样一来打字游戏.一方面,练习打字速度 .在又一个方面中,以了解诱导的理论 版权声明:本文博客原创文章,博客,未经同意,不得转载.