问题描述
试题编号: 201312-2
试题名称: ISBN号码
时间限制: 1.0s
内存限制: 256.0MB
问题描述
每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。
编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出是正确的ISBN号码。
输入格式
输入只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。
输出格式
输出一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。
样例输入
0-670-82162-4
样例输出
Right
样例输入
0-670-82162-0
样例输出
0-670-82162-4
解题思路
- 去掉输入串中的分隔符“-”,得到有10位数字的字符串。这样便于计算。
- 按识别码的计算方法计算出识别码。余数为10则转换为字符’X’。
- 检查识别码是否正确。
参考答案
isbn_str = input()
#1. 去掉输入串中的分隔符“-”,得到有10位数字的字符串。
isbn_str_no_sp = ''
for s in isbn_str:
if s != '-':
isbn_str_no_sp += s
#2. 按识别码的计算方法计算出识别码。
total = 0
for i in range(9):
total += int(isbn_str_no_sp[i]) * (i + 1)
check_code = total % 11
if check_code == 10:
check_code = 'X'
else:
check_code = str(check_code)
#3. 检查识别码是否正确
if isbn_str[-1] == check_code:
print('Right')
else:
print(isbn_str[:12] + check_code)
测试用例
题目描述中给出的两组测试用例已经覆盖了识别码正确和识别码错误两种情形。通过这两组测试用例,基本上能够证明程序的正确性。下面给出的测试用例进一步验证识别码计算过程是否正确无误。
值得讨论的是:
- 是不是前9位数字的每一位都要分别测试?我的看法是,不用,毕竟计算规则足够简单。为此我验证了前3段数字中的第一位,即第1,2,5为数字。
- 如何快速构造测试用例?对策是在题目描述给出的测试用例基础上加以改造。
增加的测试用例如下。
- 在样例1的基础上修改第1位。最后一位识别码是’X’。识别码正确。
样例输入
6-670-82162-X
样例输出
Right - 在样例1的基础上修改第1位。最后一位识别码是’X’。识别码错误。
样例输入
6-670-82162-9
样例输出
6-670-82162-X - 在样例2的基础上修改第2位。识别码正确。
样例输入
0-770-82162-6
样例输出
Right - 在上一组测试用例基础上修改了第5位。识别码正确。
样例输入
0-770-92162-0
样例输出
Right
小结
- 熟练使用字符串操作,解答本题清晰明了。
- 改造已有测试用例,生成新的测试用例,是好办法。这一办法值得在CCF软件能力认证考试中采用。