关于ISBN号码的一些解法

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是这样得到的:对0670821629个数字,从左至右,分别乘以129,再求和,即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.

你可能感兴趣的:(replace,bufferedreader,ISBN,字符读取)