CSP题目如下:
问题描述
每一本正式出版的图书都有一个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
0-670-82162-4
样例输出1
Right
样例输入2
0-670-82162-0
样例输出2
0-670-82162-4
--------------------------------------------------------------------------------------------
下面附上解题的集中思路,直接附上代码。
解法1(最笨的):
package CSP2;
import java.util.*;
public class ISBNTest {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
ISBN(s);
}
public static void ISBN(String s){
s=s.trim();
int result=0;
int number;
int j=1;
for(int i=0;i<s.length()-2;i++){
if(Character.isDigit(s.charAt(i))){
number=s.charAt(i)-'0';
result+=number*j;
j++;
}
}
int k=result%11;
if(k==10){
if(s.charAt(s.length()-1)=='X'){
System.out.println("Right");
}
else{
s=s.substring(0, s.length()-1)+"X";
for(int i=0;i<s.length();i++){
System.out.print(s.charAt(i));
}
}
}
else{
if((s.charAt(s.length()-1)-'0')==k){
System.out.println("Right");
}else{
s=s.substring(0, s.length()-1)+(""+k);
for(int i=0;i<s.length();i++){
System.out.print(s.charAt(i));
}
}
}
}
}
解法2:
package CSP2;
import java.util.Scanner;
public class ISBNTest2 {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
int[] a=new int[100];
int total=0;
for(int i=0;i<s.length();i++){
a[i]=s.charAt(i)-48;
}
for(int i=0,j=1;i<11;i++,j++){
if(s.charAt(i)=='-')
i++;
total+=a[i]*j;
}
//System.out.println(total);
if(total%11==10 && s.charAt(12)=='X'||total%11==a[12]){
System.out.println("Right");
}
else{
for(int i=0;i<s.length()-1;i++){
System.out.print(s.charAt(i));
}
if(total%11==10)
System.out.print('X');
else
System.out.print(total%11);
}
}
}
解法3
package CSP2;
import java.util.Scanner;
public class ISBNTest3 {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String s = in.nextLine();
int[] a=new int[100];
int total=0;
for(int i=0;i<s.length();i++){
a[i]=s.charAt(i)-48;
//System.out.print(s[0]);这是错误的
}
//计算和时,也可采用采用暴力的方式,如s.charAt[0]-'0')*1+(s.charAt[2]-'0')*2
for(int i=0,j=1;i<11;i++,j++){
if(s.charAt(i)=='-')
i++;
total+=a[i]*j;
}
//System.out.println(total); 测试
int result=total%11;
char c='0';
if(result==10)
c='X';
else
c=(char) (result+'0'); //虽然运行结果是正确的、但感觉这一句有毛病,不加+'0'(相当于加48),或者-'0',结果会错误
if(s.charAt(12)==c)
System.out.print("Right");
else{
/*
for(int i=0;i<s.length()-1;i++)
System.out.print(s.charAt(i));
System.out.print(c);
*/
s=s.substring(0,12)+c;
System.out.print(s);
}
}
}
解法4(标准答案)
package CSP2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ISBNTest4 {
public static void main(String args[]) {
BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
try{
int sum=0;
char cc='0';
String isbn_0 = bin.readLine();
String isbn = isbn_0.replace("-",""); //去掉字符流中的-
//String isbn = isbn_0.replace('-',' ');结果出错,replace解释见http://www.blogjava.net/hefang/articles/324456.html
for(int i=0; i<9; i++){
int ii = (int)isbn.charAt(i)-48;
sum += ii * (i+1);
}
sum = sum % 11;
if(sum == 10)
cc = 'X';
else
cc = (char)(sum+48);
if(cc == isbn.charAt(9))
System.out.println("Right");
else{
isbn_0 = isbn_0.substring(0,12) + cc; //此处巧妙、可用于其他的解法
System.out.println(isbn_0); //字符串可直接输出
}
}catch(Exception e){
e.printStackTrace();
}
}
}
-------------------------------------------------------------------------------------------
就解法四,补充一些知识:
1、BufferedReader类和InputStreamReader 类
参考文章:Java 中BufferedReader & InputStreamReader 用法
BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
一般用法:
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ming.txt")));
String data = null;
while((data = br.readLine())!=null)
{
System.out.println(data);
}
InputStreamReader 类
是字节流通向字符流的桥梁,封裝了InputStream在里头, 它以较高级的方式,一次读取一个一个字符,以文本格式输入 / 输出,可以指定编码格式;
一般用法:
InputStreamReader isr = new InputStreamReader(new FileInputStream("ming.txt"));
while((ch = isr.read())!=-1)
{
System.out.print((char)ch);
}
2、replace的使用(解法4的代码注释那块需注意)
参考文章:replace的使用
1)replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串);
2)replaceAll的参数是regex,即基于规则表达式的替换,比如,可以通过replaceAll("\\d", "*")把一个字符串所有的数字字符都换成星号;
举例如下:
String src = new String("ab43a2c43d");
System.out.println(src.replace("3","f"));=>ab4f2c4fd.
System.out.println(src.replace('3','f'));=>ab4f2c4fd.
System.out.println(src.replaceAll("\\d","f"));=>abffafcffd.
System.out.println(src.replaceAll("a","f"));=>fb43fc23d.
System.out.println(src.replaceFirst("\\d,"f"));=>abf32c43d
System.out.println(src.replaceFirst("4","h"));=>abh32c43d.