第一次写题解,请来访的各位大佬多多包涵 awa(完整程序见文末,已验证全AC)
一、大话题目~
每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符,其规定格式如
x-xxx-xxxxx-x
,其中符号-
就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4
就是一个标准的 ISBN 码。识别码的计算方法如下:
首位数字*1 加上 次位数字* 2 ……以此类推,用所得的结果 mod11(即%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码(A)
- 计算:依照9位数字计算ISBN码(B)
- 验证:验证A识别码与B识别码是否相等,并输出对应结果
二、开敲代码~~
1、读取
读取就是输入数字嘛,而像我这样的萌新很容易会想到直接导入整型。
scanf("%d-%d%d%d-%d%d%d%d%d-%d",...);
这样造成的问题就是无法正常读取。因为%d对应的并不是数字,而是一个数。也就是说,如果我输入32-456-...哪怕32就会被读取到第一个%d的位置上!
那么正确的思路是什么呢?让我们一起看后面的程序要求:
首位数字*1 加上 次位数字* 2 ……
由于第二步中我们会需要对9位数字分别进行对应的乘法运算,所以在程序开头我们需要以字符串的形式输入数据,这样才能对第1、2、3...的数字进行单独的操作。(ps:字符串的输入可省略求址符号&)
9位数字+3位间隔符+1位识别码,总共是13位字符。由于C++编码的特点,我们需要再开一个空间,用于保存字符串输入最后的'\0',即我们结束时按下的回车键。
char a[14];
scanf("%s",a);
但是呢,如果创建a[13],在此程序中也不会出现问题。
那么什么情况下数组缺少空间会出现问题呢?
——在需要多次输入数据的时候。
由于数组长度不够,所以多出来的'\0'会影响下次输入。
可以打上以下代码用于清空scanf的缓存区。
setbuf(stdin,NULL);
回到正题,那么现在我们有了数组a[14],就可以进入计算的模块啦。
2、计算
接下来我们需要做的,就是对9个数字各自做乘法再求和。计算规则是:
第1位数字*1 + 第2位数字*2 + 第3位数字*3 + ... +第9位数字*9,得到总和。后%11得到余数,即识别码。
这里令i为位数,则总和可以表示为
sum =
(2.1)
之后再对sum求余数即可。
接下来就让我们用程序来实现它吧!
先创建一个int型变量code,用于保存总和。然后使用for循环,按公式(2.1)处理第一位数字到第九位数字,将结果累加给code。
但是在循环的过程中,要把ISBN码位数i和数字位数j区分开。否则可能会出现将a[1](即'-')乘以2的滑稽结果。
int code = 0;
int i,j=0;
for(i=0;i<12;i++){
if(a[i]=='-') continue;
code += ((a[i]-48)*(j+1));
j++;
}
经过for循环,我们终于成功得到了正确的总和,然后 code %= 11就能得到余数了~
3、验证
验证结果分为“识别码无误,输出RIght”和“识别码错误,输出正确识别码”两种情况。
现在我们需要创建一个数组,用来返回正确的识别码。即:
choice[12] = "0123456789X";
嘿嘿,现在使用choice[code]就能输出对应的识别码啦。
最后再进行判断就大功告成了!
完整程序如下:
#include <bits/stdc++.h>
int main(){
//数字
char a[14],choice[12]="0123456789X";
//计算识别码
int code=0;
scanf("%s",a);
int i,j=0;
for(i=0;i<12;i++){
if(a[i]=='-') continue;
code += ((a[i]-48)*(j+1));
j++;
}
code %= 11;
//判断识别码
if(choice[code]==a[12]) printf("Right");
else{
a[12] = choice[code];
printf("%s",a);
}
return 0;
}