蓝桥杯网站修好了,今天才关注到,补上上次没有发的BASIC-20和开始今天的五道题:
【BASIC-20】 基础练习 数的读法
问题描述
Tom教授正在给研究生讲授一门关于基因的课程,有一件事情让他颇为头疼:一条染色体上有成千上万个碱基对,它们从0开始编号,到几百万,几千万,甚至上亿。
比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。
所以,他迫切地需要一个系统,然后当他输入12 3456 7009时,会给出相应的念法:
十二亿三千四百五十六万七千零九
用汉语拼音表示为
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
这样他只需要照着念就可以了。
你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。
注意必须严格按照规范,比如说“10010”读作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”读作“shi wan”而不是“yi shi wan”,“2000”读作“er qian”而不是“liang qian”。
比如说,在对学生讲解第1234567009号位置上的碱基时,光看着数字是很难准确的念出来的。
所以,他迫切地需要一个系统,然后当他输入12 3456 7009时,会给出相应的念法:
十二亿三千四百五十六万七千零九
用汉语拼音表示为
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
这样他只需要照着念就可以了。
你的任务是帮他设计这样一个系统:给定一个阿拉伯数字串,你帮他按照中文读写的规范转为汉语拼音字串,相邻的两个音节用一个空格符格开。
注意必须严格按照规范,比如说“10010”读作“yi wan ling yi shi”而不是“yi wan ling shi”,“100000”读作“shi wan”而不是“yi shi wan”,“2000”读作“er qian”而不是“liang qian”。
输入格式
有一个数字串,数值大小不超过2,000,000,000。
输出格式
是一个由小写英文字母,逗号和空格组成的字符串,表示该数的英文读法。
样例输入
1234567009
样例输出
shi er yi san qian si bai wu shi liu wan qi qian ling jiu
(虽然这题测试用例通过了,但这题写的代码仍然有bug,例如:43000403,我注释在代码处了,纠结的地方就是当块内结构是 "0_0_"如何处理,因为我的思路是块内遇到一个零就将“判断是否输出ling标志”置false了,所以20403结果是"er qian ling si bai san",初步解决方案是每次判断是否将“输出ling标志”置false时判断(除块内最后一位外)块内后面还有没有0,如果有0,则保留true值,但感觉这样很麻烦,如果有简便方法的朋友请指导我下,谢谢~)
Code:
import java.util.Scanner ;
public class Main {
// 局部判断从ch[start]~ch[end]是否全为'0',如果是,则后面不必在判断了(以免输出多个"ling"),例如1000300,看1的时候要看到十万位和万位是不是0,是的话直接输出yi bai wan就好了,而不是yi bai ling ling wan
public static boolean isEnd( String str, int start, int end ) {
char[] ch = str.toCharArray() ;
boolean flag = true ; // 假定全为 '0'
for( int i = start; i <= end; i ++ ) {
if( ch[i] != '0' ) {
flag = false ;
break ;
}
}
return flag ;
}
// 将数字转换成拼音
public static String num_string( int num) {
switch( num ) {
case 0: return "" ;
case 1: return "yi" ;
case 2: return "er" ;
case 3: return "san" ;
case 4: return "si" ;
case 5: return "wu" ;
case 6: return "liu" ;
case 7: return "qi" ;
case 8: return "ba" ;
case 9: return "jiu" ;
}
return "ERROR" ;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner( System.in ) ;
String str = sc.next() ;
char[] ch = str.toCharArray() ;
String result = "" ;
boolean flag_shi = true ; // 做个标志,区分输出 "..... shi yi wan" 还是" .... yi shi yi wan"。例如: 110000-->"shi yi wan"(而不是"yi shi yi wan") ; 8110000-->"ba bai yi shi yi wan"(而不是ba bai shi yi wan)
// 也就是说:当十万位 / 十位 前面有数字时且该位为 '1' 时输出"yi shi",否则只输出"shi"
int start = 0 ; // 还未考虑怎么读ch的起始判断位置
int end = ch.length - 1 ; // 还未考虑怎么读ch的终了判断位置
if( ch[0] == '-' ) { // 负号处理
result += "fu " ;
start ++ ;
}
while( start <= end ) {
/**
* 这里的思想是分块:
* 第一块:十亿位、亿位
* 第二块:千万位、百万位、十万位、万位
* 第三块:千位、百位、十位、个位
* 原因:除非块内全零,否则第一块后一定会输出"yi" 第二块后一定会输出"wan"
*/
/** 第一块 部分**/
if( end >= 9 ) { // 十亿位
if( num_string( (int) (ch[start] - '0') ).equals("yi") ) { // 如果最高位是'1',则是"shi ...."而不是"yi shi ...."
result += "shi" ;
start ++ ; // 不要把这句话加到上两行的if中 ( if(num_string( (int) (ch[start++] - '0') ).equals("yi")) ),这样每当判断后无论正确与否start已经++修改了,这里应该只有当进入if才start ++
}
else {
result += num_string( (int) (ch[start++] - '0') ) + " shi " ;
}
if( isEnd( str, start, start + 1 ) ) { // 查看十亿位后第一块后面是否全为0。是,则直接字符串+"yi", 否,则看该块内的下一位
result += " yi " ;
}
flag_shi = false ; // 判断十万位和十位特殊处理时用
}
if( end >= 8 ) { // 亿位
// if( isEnd( str, start, start ) ) { // 木有必要~
// result += "" ;
// start ++;
// }
// else {
result += num_string( (int) (ch[start ++] - '0') ) + " yi " ; // 亿位
// }
i