• 从用python做zoj1011发生Non-zero Exit Code错误说起


            近期做了浙大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
    



  • 相关阅读:
    java经典面试题
    用OpenSSL把二进制的Cer证书转换程Base64格式的PEM格式的证书
    JVM中java实例对象在内存中的布局
    高级加密标准(英语:Advanced Encryption Standard,缩写:AES)
    中断和中断处理程序
    CS 寄存器 和 IP 寄存器
    Gson通过借助TypeToken获取泛型参数的类型的方法
    Tomcat 的 JDBC 连接池
    Google Guava官方教程(中文版)
    阿里DRUID数据源
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4298730.html
Copyright © 2020-2023  润新知