题目描述
每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、11位识别码和 3位分隔符,其规定格式如"x−xxx−xxxxx−x",其中符号"−−"是分隔符(键盘上的减号),最后一位是识别码,例如 "0−670−82162−4" 就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 代表英语;第一个分隔符"−"之后的三位数字代表出版社,例如 670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2⋯以此类推,用所得的结果mod11,所得的余数即为识别码,如果余数为 10,则识别码为大写字母'X'。例如ISBN号码 "0−670−82162−4"中的识别码44是这样得到的:对 "067082162" 这 9个数字,从左至右,分别乘以 1,2,⋯,9,再求和,即0×1+6×2+⋯+2×9=158,然后取 158mod11 的结果 4作为识别码。
你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出"Right
";如果错误,则输出你认为是正确的 ISBN 号码。
输入
只有一行,是一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。
输出
共一行,假如输入的 ISBN 号码的识别码正确,那么输出"Right
",否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符"−")。
样例输入 复制
0-670-82162-4
样例输出 复制
Right
- 可能用到的函数:
stoi()
:将字符串转换为整数。string
的相关操作,如substr()
用于截取子字符串,length()
用于获取字符串长度。
- 考察知识点:字符串的处理,数字与字符串的转换,以及简单的数学计算,重点考察对 ISBN 码验证规则的理解和编程实现。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 定义一个字符串变量 isbn 用于存储输入的 ISBN 号码
string isbn;
// 使用 getline 函数从标准输入读取一行内容,将其存储到 isbn 变量中
getline(cin, isbn);
// 初始化加权和为 0,用于存储前 9 位数字按规则计算后的总和
int sum = 0;
// 初始化乘数为 1,根据规则,从左到右第 1 位数字乘 1,第 2 位乘 2,以此类推
int multiplier = 1;
// 遍历输入的 ISBN 号码,!!!!!!注意这里遍历到倒数第 2 个字符,避免把最后的识别码纳入计算
for (int i = 0; i < isbn.length() - 2; ++i) {
// 检查当前字符是否为分隔符 '-'
if (isbn[i] != '-') {
// 如果不是分隔符,将当前字符转换为对应的数字(字符减去 '0' 得到数字值)
// 并将该数字乘以当前的乘数,累加到加权和 sum 中
sum += (isbn[i] - '0') * multiplier;
// 乘数自增 1,为下一位数字的计算做准备
multiplier++;
}
}
// 计算加权和 sum 对 11 取模的结果,得到余数
int remainder = sum % 11;
// 定义一个字符变量 correctCheckDigit,用于存储正确的识别码
char correctCheckDigit;
// 如果余数为 10,根据规则,识别码为 'X'
if (remainder == 10) {
correctCheckDigit = 'X';
} else {
// 若余数不为 10,将余数转换为对应的字符(数字加上 '0' 得到对应的字符)
correctCheckDigit = remainder + '0';
}
// 从输入的 ISBN 号码中提取最后一位字符,即输入的识别码
char inputCheckDigit = isbn[isbn.length() - 1];
// 比较计算得出的正确识别码和输入的识别码
if (correctCheckDigit == inputCheckDigit) {
// 如果两者相等,说明输入的 ISBN 号码的识别码是正确的,输出 "Right"
cout << "Right" << endl;
} else {
// 若不相等,将输入的 ISBN 号码的最后一位替换为正确的识别码
isbn[isbn.length() - 1] = correctCheckDigit;
// 输出包含正确识别码的 ISBN 号码
cout << isbn << endl;
}
return 0;
}
思想:
1. 输入处理思想
- 完整读取:考虑到 ISBN 号码包含分隔符(
-
),为了确保能完整获取输入的信息,使用getline
函数读取一整行输入。这样可以避免因分隔符导致输入被截断的问题,将整个 ISBN 号码作为一个完整的字符串存储起来,便于后续处理。 - 数据存储:将读取到的 ISBN 号码存储在一个字符串变量中,利用字符串的特性来处理其中的字符和数字信息。
2. 加权和计算思想
- 遍历筛选:通过遍历 ISBN 号码字符串,排除其中的分隔符(
-
),只对有效的数字字符进行处理。这样可以准确地获取到前 9 位数字,为后续的加权求和做准备。 - 加权累积:根据 ISBN 号码识别码的计算规则,从左到右依次对前 9 位数字进行加权处理。第 1 位数字乘以 1,第 2 位数字乘以 2,以此类推,将每一位数字与其对应的权重相乘后累加到一个总和变量中。这个过程使用循环来实现,循环变量同时作为权重的计数器,确保每一位数字都能正确地乘以相应的权重。
3. 识别码计算思想
- 取模运算:在得到前 9 位数字的加权和后,对其进行取模运算,即计算加权和除以 11 的余数。取模运算的结果是一个介于 0 到 10 之间的整数,这个整数就是根据规则计算出的正确识别码的数值表示。
- 特殊处理:当取模结果为 10 时,根据 ISBN 号码的规则,识别码用大写字母
'X'
表示。因此,需要对这种特殊情况进行判断和处理,将计算结果转换为对应的字符形式。
4. 验证与输出思想
- 对比判断:将计算得到的正确识别码与输入的 ISBN 号码中的最后一位识别码进行比较。通过比较两个字符是否相等,来判断输入的识别码是否正确。
- 结果输出:根据比较的结果进行不同的输出处理。如果两个识别码相等,说明输入的 ISBN 号码识别码正确,输出
"Right"
;如果不相等,将输入的 ISBN 号码的最后一位替换为计算得到的正确识别码,然后输出修改后的完整 ISBN 号码。