偶然发现了一个以前写的小程序,发在博客上,共同研究一下。
记得是以前一个博客上面的需求,就是将数字转换成人民币大写。
不过,代码没有经过优化,估计效率不算高。
代码如下:
public class RMBReader {
static char [] NUMs = new char [] {'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};
static char [] UNITs = new char [] {'\0','拾','佰','仟','万','拾','佰','仟','亿','拾','佰','仟','万','拾','佰','仟'};
public static String read(String number){
String [] sub = number.split("\\.");
if(sub.length<=0 || sub.length>2)throw new NumberFormatException("数字格式有误");
StringBuilder buff = new StringBuilder();
readInteger(sub[0],buff);
if(sub.length==2){
buff.append("点");
readFloat(sub[1],buff);
}
return buff.toString();
}
private static void readFloat(String floatString, StringBuilder buff) {
char floatNums [] = floatString.toCharArray();
for(char ch : floatNums){
buff.append(NUMs[ch-'0']);
}
}
private static void readInteger(String intString, StringBuilder buff) {
char intNumbs [] = intString.toCharArray();
if(intNumbs.length<=0){
buff.append(NUMs[0]);
return;
}
for(int i=intNumbs.length-1;i>=0;i--){
if(intNumbs[i]!='0'){
buff.insert(0,NUMs[intNumbs[i]-'0']);
}else{
if(buff.length()>0 && buff.charAt(0)!=NUMs[0])buff.insert(0, NUMs[0]);
}
int unit = intNumbs.length-i-1;
if(unit<=0 || intNumbs[i]=='0')continue;
buff.insert(1,UNITs[unit]);
}
}
/**
* 测试用例
*/
public static void main(String[] args) {
System.out.println(read("1009.168"));
}
}
上述代码没有元角分的单位,但是,算法相对简单便于理解。
较为复杂一点的代码如下:
/**
* 将包含数字的字符串中,数字替换为人民币大写形式
*
* @author 侯磊
*/
public class NumberTranslator {
/**
* 将字符串中数字和字符进行区分
*/
private static final Pattern NumberPattern = Pattern.compile("([-\\+]?\\d[\\.\\d]*)|(\\D)");
/**
* 判断字符串是否是纯数字的字符串
*/
private static final Pattern IsNumber = Pattern.compile("^[-\\+]?\\d[\\.\\d]*{1}quot;);
/**
* 该接口用于 将 数字转换成人民币大写
*/
public static interface Translateable {
char[] NumArray = {'零','壹','贰','叁','肆','伍','陆','柒','拐','玖'};
char[] UnitArray = {'元','拾','佰','仟','万','拾','佰','仟','亿','拾','佰','仟','万','拾','佰','仟'};
char[] DecimalUnitArray = {'角','分','厘'};
/**
* 传入数字字符串,传出人民币大写的字符串
*/
String translate(String number);
}
/**
* 公共代码的抽象类
*/
public static abstract class AbstractTranslateable implements Translateable{
public String translate(String number) {
//所有转换的结果都保存在buff对象里面
StringBuilder buff = new StringBuilder();
beforeTranslate(buff);
if(number.startsWith("-")){//如果数字字符串是负数
appendMinus(buff);
number = number.substring(1);
}
String subNumber [] = number.split("\\.");
if(subNumber.length==1){//数字字符串是整数(没有小数点)
appendInteger(buff,subNumber[0]);
}else{
appendInteger(buff,subNumber[0]);
appendPoint(buff);
appendDecimal(buff,subNumber[1]);
}
afterTranslate(buff);
return buff.toString();
}
protected void afterTranslate(StringBuilder buff) {
// do nothing ...
}
protected void beforeTranslate(StringBuilder buff) {
// do nothing ...
}
/**
* 对负号的处理
*/
protected void appendMinus(StringBuilder buff){
buff.append("负");
}
/**
* 对小数点的处理
*/
protected void appendPoint(StringBuilder buff){
buff.append("点");
}
/**
* 对小数部分的处理
*/
protected void appendDecimal(StringBuilder buff, String dec) {
char decArray [] = dec.toCharArray();
for(int index =0 ; index<decArray.length;index++){
buff.append(NumArray[decArray[index]-'0']);
appendDecimalUnit(buff,index);
}
}
/**
* 对小数单位的处理
*/
protected void appendDecimalUnit(StringBuilder buff, int index) {
if(index<DecimalUnitArray.length){
buff.append(DecimalUnitArray[index]);
}
}
/**
* 对整数部分的处理
*/
protected void appendInteger(StringBuilder buff, String integer) {
char intArray [] = integer.toCharArray();
for(int index=0;index<intArray.length;index++){
if(intArray[index]=='0' && intArray[index-1]=='0'){
if(buff.charAt(buff.length()-1)!=NumArray[0]){
buff.deleteCharAt(buff.length()-1);//删除由'0'引起的多余单位
}
continue;//多个'0'就不进行处理了
}
buff.append(NumArray[intArray[index]-'0']);
buff.append(UnitArray[intArray.length-index-1]);
}
if(buff.charAt(buff.length()-2)==NumArray[0]){
buff.deleteCharAt(buff.length()-2);//删掉最后个位是'0'的转换结果
}
}
}
/**
* 默认的转换处理类。通过覆盖抽象类的方法,进行功能的删改。
*/
private static class DefaultTranslateable extends AbstractTranslateable{
@Override
protected void appendDecimalUnit(StringBuilder buff, int index) {
//do nothing ...
}
@Override
protected void appendInteger(StringBuilder buff, String integer) {
super.appendInteger(buff, integer);
buff.deleteCharAt(buff.length()-1);//删除整数部分的'元'单位。
}
@Override
protected void afterTranslate(StringBuilder buff) {
buff.append(UnitArray[0]);
}
}
private static Translateable DefaultTrans = new DefaultTranslateable();
private Translateable translateable = DefaultTrans;
public String translate(String number) {
StringBuilder buff = new StringBuilder();
Matcher m = NumberPattern.matcher(number);
while (m.find()) {
String match = number.substring(m.start(), m.end());
Matcher isNum = IsNumber.matcher(match);
if (isNum.matches()) {
buff.append(translateable.translate(match));
} else {
buff.append(match);
}
}
return buff.toString();
}
public Translateable getTranslateable() {
return translateable;
}
public void setTranslateable(Translateable translateable) {
this.translateable = translateable;
}
/**
* 最土的测试方法。嗯嗯
*/
public static void main(String[] args) {
String test = "我的银行存款不可能是:-120030.45。哈哈,有可能是67,嗯嗯。";
String result = new NumberTranslator().translate(test);
System.out.println(result);
}
}