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)); } } } } }
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); } } }
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); } } }
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.