今天整理电脑中的文件夹,发现要处理一下人民币大写转数字的问题,于是上网搜了一下没找到Excel对应的方法,干脆自己用Java写一个。我写完了之后发现excel表里面有一项是这样的。
我正在想这一项不会出错吧,这个程序应该只会读其中某一个数据,然后我看一眼输出结果,218000。然后手动计算了一下,发现答案正好是218000。有一种突如其来的激动,想不到这货还能计算这个。以前写代码时没有考虑的地方都会出错,现在没有考虑到的地方它居然也算出来了。然后我看了一眼自己写的代码才反应过来。
不管有几个数据,它都会相加的,因为我转化的时候是对权值和数字的积来求和的,有多少项并不影响。虽然不是什么大程序,但是这货带来的惊喜(以前只有惊,没有喜)还是蛮有意思的。这里附上源码,分享一下这突如其来的爽。
——————————-华丽的分割线——————————–
代码改了一下,顺便把数字转大写加进去。
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
/**
*注意:暂时只能处理千亿级别的数据。
*/
public class MoneyUtil{
private static final char [] RMB_NUMBER = {
'零','壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖',
};
private static final Character RMB_START='元';
private static final char [] RMB_DEC={'角','分'};
private static final char RMB_ZHENG='整';
private static final char RMB_YUAN='元';
private static final char RMB_WAN='万';
private static final char RMB_YI='亿';
private static final char RMB_SHI='拾';
private static final char RMB_BAI='佰';
private static final char RMB_QIAN='仟';
private static final char [] RMB_RIGHT={RMB_YUAN,RMB_WAN,RMB_YI};
private static final char [] RMB_WEIGHT={RMB_SHI,RMB_BAI,RMB_QIAN};
private static long getNumber(char ch){
for(int i=0;i<RMB_NUMBER.length;i++){
if(ch==RMB_NUMBER[i]){
return i;
}
}
return -1;
}
private static long getWeight(char ch){
switch(ch){
case RMB_SHI:
return 10;
case RMB_BAI:
return 100;
case RMB_QIAN:
return 1000;
}
return -1;
}
private static long getRight(char ch){
switch(ch){
case RMB_YUAN:
return 1;
case RMB_WAN:
return 10000;
case RMB_YI:
return 100000000;
}
return -1;
}
public static String moneyToNumber(String money){
long right=1;
long weight=1;
long sum=0;
int index=money.lastIndexOf(RMB_START);
if(index==-1){
return "Error";
}
//处理整数部分
for(int i=index;i>=0;i--){
char ch=money.charAt(i);
long temp=-1;
if((temp=getWeight(ch))!=-1){
weight=temp;
}else if((temp=getRight(ch))!=-1){
right=temp;
weight=1;
}else if((temp=getNumber(ch))!=-1){
sum+=temp*weight*right;
}
}
//处理部分省略掉开头“壹”情况
if((weight=getWeight(money.charAt(0)))!=-1){
sum+=weight*right;
}
//处理小数部分
String str="";
for(int i=index;i<money.length();i++){
long line;
if((line=getNumber(money.charAt(i)))!=-1){
str+=line;
}
}
if(!str.isEmpty()){
str="."+str;
}
return String.valueOf(sum)+str;
}
//将不规范的输入数据规范化
private static String numberFormat(String target){
target=target.trim();
target=target.replaceAll(",","");//去掉数据里面的逗号
//对于数据中含有非法字符的返回error
try{
Double.parseDouble(target);
}catch(NumberFormatException ne){
return "Error";
}
StringBuilder sb=new StringBuilder(target);
while(sb.length()>0 && sb.charAt(0)=='0'){//去掉数据前面的零
sb.delete(0,1);
}
return sb.toString();
}
public static String numberToMoney(String target){
target=numberFormat(target);
if(target.equals("Error")){
return target;
}
//处理target为“0”的情况
if(target.equals("")){
return ""+RMB_NUMBER[0]+RMB_YUAN+RMB_ZHENG;
}
StringBuilder sb=new StringBuilder(target);
int index=target.lastIndexOf(".");
int start=target.length()-1;
String str="";
if(index!=-1){
start=index-1;
index++;
//处理小数部分
for(int i=0;i<2 && index<target.length();i++,index++){
int temp=target.charAt(index)-48;
if(temp>0 && temp<RMB_NUMBER.length){
str=str+RMB_NUMBER[temp]+RMB_DEC[i];
}
}
}else{
str="整";
}
boolean addZero=false;//是否添加零
for(int i=start;i>=0;i--){
int temp=target.charAt(i)-48;
if( (start-i)%4==0 ||start==i){
//每四位加入一个界值,如万、亿。
str=RMB_RIGHT[(start-i)/4]+str;
addZero=false;
if(temp>0 && temp<RMB_NUMBER.length){
str=RMB_NUMBER[temp]+str;
addZero=true;
}
}else{
if(temp>0 && temp<RMB_NUMBER.length){
//不是整四位时且不是零值的时候,加入权值如拾、佰、仟。
str=RMB_NUMBER[temp]+""+RMB_WEIGHT[(start-i)%4-1]+str;
addZero=true;
}else if(temp==0 && addZero){
str=RMB_NUMBER[temp]+str;
addZero=false;
}
}
System.out.println(i+"\t"+str);
}
return str;
}
public static void main(String[] args) throws FileNotFoundException {
if(args.length>0){
//System.out.println(moneyToNumber(args[0]));
System.out.println(numberToMoney(args[0]));
return;
}
Scanner sc=new Scanner(new File("f:/a.txt"));
while(sc.hasNext()){
System.out.println(numberToMoney(sc.nextLine()));
}
sc.close();
}
}