描述
每一本正式出版的图书都有一个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号码。
题目来源:牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网 (nowcoder.com)
我采用的是模块化设计,将本题分解成了几个块,拼接在一起完成了本题.
以下有说不对的地方,敬请指出😅😅
首先,我们看到题目非常长,所以要提炼题目精华,粗略一扫得出
ISBN码包括9位数字 1位识别码和3位分隔符 其规定格式如“x-xxx-xxxxx-x” “-”是分隔符,最后一位是识别码
识别码的计算方法如下:
用所得的结果mod 11 所得的余数即为识别码 如果余数为10,则识别码为大写字母X。
编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。
虽然还是有点多 ,但大概意思是 一串数 ,最后一位是识别码(我理解为校验位), 识别方式为 第一位*1+...+第九位*9 的和(权重) 对 11 取余(校验方式)
再判断校验是否正确,正确返回"Right" ,否则返会正确的这一串数(修正校验位);
题目意思懂了,那首先考虑怎么将这一串数分解出来,所以我采用了每一个间隔符前的所有数为一个整形
int a, b, c;
char x, x1;
scanf("%d-%d-%d-%c", &a, &b, &c, &x);
注: 最后一位为字符,因为 10 = X 所以将最后的识别码转为字符将是最后的对比
然后,开始考虑怎么将 第一位*1+...+第九位*9 的和 求出,因为我把这一串数拆分成了四个整形,所以方便我对每一个整形进行修改
于是,我想到了设计一个函数来求出这个整形的和,再将三个整形(最后一个是标识符)的和加在一起就是 第一位*1+...+第九位*9 的和
设计这个函数需要 一个数(a,b,c) 和 它的权重(1,2~4,5~9) 暂定这两个.
// 数据 权重
int fin(int number, int dis) { //每位乘
if (number != 0)
return fin(number / 10, dis + 1) + number % 10 * dis;
else
return 0;
}
我用的是递归的写法 但是我发现这样写虽然简单,但是求出的和却不是我想要的, 因为题目是从左向右乘以权重的,而我是从右到左
所以需要翻转数字(你以为我会重写??开玩笑😎😎)
于是...
// 数据
int renum(int number) { //反转数字
int result = 0, num = number;
while (num) {
result = result * 10 + num % 10;
num /= 10;
}
return result;
}
将这两个结合就可以完成 第一位*1+...+第九位*9的和了
接下来将求出的标识符存放在 X1 中
x1 = (a * 1 + fin(renum(b), 2) + fin(renum(c), 5)) % 11;
但此时x1为整形,还不能与x(识别码)做对比,因此再做一下判断,因为x可能是'X'(10)
x1 = x1 == 10 ? 'X' : x1 + '0';
注:一个整形加上'0'就可以变成对应的字符(int->char,0~9)
1 + '0' = '1'
9 + '0' = '9'
接下来做判断就可以了
if (x == x1)
printf("Right");
else
printf("%d-%d-%d-%c", a, b, c, x1);
完整代码
#include <stdio.h>
// 数据
int renum(int number) { //反转数字
int result = 0, num = number;
while (num) {
result = result * 10 + num % 10;
num /= 10;
}
return result;
}
// 数据 权重
int fin(int number, int dis) { //每位乘
if (number != 0)
return fin(number / 10, dis + 1) + number % 10 * dis;
else
return 0;
}
int main() {
int a, b, c;
char x, x1;
scanf("%d-%d-%d-%c", &a, &b, &c, &x);
x1 = (a * 1 + fin(renum(b), 2) + fin(renum(c), 5)) % 11;
x1 = x1 == 10 ? 'X' : x1 + '0';
if (x == x1)
printf("Right");
else
printf("%d-%d-%d-%c", a, b, c, x1);
return 0;
}