zoukankan      html  css  js  c++  java
  • 从用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
    



  • 相关阅读:
    计划给予心脏公式
    平原绫香 Hirahara Ayaka-Jupiter
    legend---十一、thinkphp事务中if($ans1&&$ans2){}else{}方式和try{}catch{}方式事务操作的区别在哪里
    chrome控制台常用技巧有哪些
    js中console强大之处体现在哪
    Pocket英语语法---五、形式主语是怎么回事
    智课雅思词汇---十二、vent是什么意思
    英语影视台词---八、the shawshank redemption
    Pocket英语语法---四、should的同义词是谁
    m_Orchestrate learning system---二十七、修改时如何快速找到作用位置
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4298730.html
Copyright © 2011-2022 走看看