题目描述
每一本正式出版的图书都有一个 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 号码(包括分隔符“-”)。
实现代码
代码1:
#include<bits/stdc++.h>
#include<string>
#include<iostream>
using namespace std;
int caculate(string a)
{
int checksum=0;
int sum=0;
sum=(a[0]-'0')+2*(a[2]-'0')+3*(a[3]-'0')+4*(a[4]-'0')
+5*(a[6]-'0')+6*(a[7]-'0')+7*(a[8]-'0')+8*(a[9]-'0')+9*(a[10]-'0');
checksum=sum%11;
return checksum;
}
int main()
{
string ISBN;
// 根据输入的前几位先算正确数据
// 如果和输入的不一样,输出正确ISBN
// 一样的话输出“Right”
cin>>ISBN;
string checksum;
checksum=to_string(caculate(ISBN));
if(checksum=="10")
{
checksum="X";
}
if(checksum[0]==ISBN[12])
{
cout<<"Right"<<endl;
}
else
{
for(int i=0;i<ISBN.length()-1;i++)
{
cout<<ISBN[i];
}
cout<<checksum<<endl;
}
}
代码2:
#include<bits/stdc++.h>
using namespace std;
int main()
{
string isbn;
cin>>isbn;
int crc=0,sum=0;
string isbn_num;
isbn_num=isbn.substr(0,1)+isbn.substr(2,3)+isbn.substr(6,5);
int slen=isbn_num.length(); // 从 0 开始
for(int i=0;i<slen;i++)
{
sum=sum+(isbn_num[i]-'0')*(i+1);
}
crc=sum%11;
if((isbn[12]-'0')==crc)
{
cout<<"Right";
}
else if(((isbn[12]-'0')=='X'-'0') && crc==10)
{
cout<<"Right";
}
else
{
for(int i=0;i<isbn.length()-1;i++)
{
cout<<isbn[i];
}
if(sum==10)
{
cout<<'X';
}
else
{
cout<<crc;
}
}
}
解题思路
首先根据输入的数计算正确的校验码是多少,然后再用输入的校验码和计算出来正确的校验码比对,如果一致的话就输出“Right”,不一致就输出正确的 ISBN。
注意点
看题要仔细,① 开始的时候没看见当 checksum 是 10 的时候要换成 X,导致出了错,② 而且 checksum 的类型用了string
,在第二个判断 checksum[0]==ISBN[12]
的时候想了很久才发现这个错误。
知识点
-
string 的用法,来源于文章 C++ string详解 。
- 需要知道字符串长度时,可以调用 string 类提供的
length()
函数。
输出结果为22。由于 string 的末尾没有’\0’字符,所以 length() 返回的是字符串的真实长度,而不是长度 +1。string s = "http://c.biancheng.net"; int len = s.length(); cout<<len<<endl;
- string 字符串也可以按照下标来访问其中的每一个字符。string 字符串的起始下标仍是 从 0 开始。
运行结果:
1 2 3 4 5 6 7 8 9 0
1234557890#include <iostream> #include <string> using namespace std; int main(){ string s = "1234567890"; for(int i=0,len=s.length(); i<len; i++){ cout<<s[i]<<" "; } cout<<endl; s[5] = '5'; cout<<s<<endl; return 0; }
- 需要知道字符串长度时,可以调用 string 类提供的
- string 截取部分用
substr(begin,length)
,可以加起来。