实现一个将输入的浮点型数值转化为一个按照人名币读写方式大写的字符串。
由于部分已经比较详细了,不再做多余说明。思路可以参考开头的多行注释。有一点要提醒,String类定义的字符串是不能改变的,此处为了能够方便的实现字符串的增删,采用的是StringBuilder类。详见本博客中java学习123之String类。
package floatToRMB;
import java.lang.Math;
import java.util.Scanner;
/*
* 编写一个程序,将浮点数转换为人名币读法字符串,例如将1006.333转换为壹仟零陆元三角三分
* 注意:人民币的数字读法为:
* 1、壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整
* 2、中文大写金额数字到“元”为止的,在“元”之后,应写“整”字;
* 3、数字中间连续有几个“0”时,中文大写只写一个“零”字。
* 4、数字万位和元为是“0”;或者数字中间连续有几个“0”,并且万位、元位也是“0”,但千位、角位不是“0”时,中文大写金额不写“零”字。
* 5、数字分位是“0”,但角位不是“0”,则“元”后面要写“零”字。
* 思路:
* 1、先将浮点数分为整数部分(不超过12)和小数部分(保留2位)。
* 2、将整数部分从低到高按照4位一位,划分成几个段,分别从高到低存放到一个二维数组array的每一行中,也即每个段都是*千*百*十*几,array[0]是以亿为单位,array[1]以万为单位,array[2]以元为单位
* 将四舍五入后的小数部分从高到低存放到数组array1中,
* 3、用pos[i]记录array[i]的首个不为0的数字的位置,若全不为0,则pos[i]=-1.
* 4、用str[i]存放array[i]的每一位数字转换后的大写汉字。若pos[i]==-1,则str[i]="零",否则按次序转换,并分别加上“千”、“佰”、“拾”
* 5、对每一段也即array[i],若个位(array[i][3])为0,则不读零;若个位、十位都为0,则不读零;若个十百都为0,则不读零
* 6、对每一段也即array[i],在个位不为0,十位为0的前提下,若百位为0,则只读一个0,若百位千位都为0,也只读一个0
* 7、从不全为0的那段开始,在每一个str[i]后分别加上单位“亿”、“万”“元”
* 8、按照类似的方法处理小数部分。
* 9、删掉开头的零”
*/
public class Change {
//
public char numToChar(int num){
if(num>9 || num<0)
return ' ';
else{
switch(num){
case 0:return '零';
case 1:return '壹';
case 2:return '贰';
case 3:return '叁';
case 4:return '肆';
case 5:return '伍';
case 6:return '陆';
case 7:return '柒';
case 8:return '捌';
case 9:return '玖';
default:return ' ';
}
}
}
public int firstNotZero(int []num){
for(int i=0;i<num.length;i++){
if(num[i]!=0)
return i;
}
//若该数组的每一位都为0,则返回-1
return -1;
}
public String floatToRMB(double rmb){
StringBuilder []str=new StringBuilder[4]; //保存转换后的字符串
for(int i=0;i<4;i++)
str[i] = new StringBuilder("");
StringBuilder str2 =new StringBuilder("");
int []pos = new int[3];
int intnum = (int)Math.floor(rmb);
int decimal = (int)Math.round((rmb - intnum)*100);//四舍五入得到2位小数并化成整数
//将整数部分按照每四位一组将数字存放在一个二维数组中。
int [][]array= new int[3][4];
for(int i=2;i>=0;i--){
int arraynum = intnum%10000;
intnum /=10000;
for(int j=3;j>=0;j--){
array[i][j] = arraynum%10;
arraynum /=10;
}
}
//将两位小数部分存在一个数组中
int []array1 = new int[2];
//System.out.println(decimal);
array1[1] = decimal%10;
array1[0] = decimal/10%10;
//System.out.println(array1[0] +" "+array1[1]);
for(int i=0;i<3;i++){
pos[i] = firstNotZero(array[i]);
//若pos[i]为-1,则该段全为0
if(pos[i]==-1){
str[i].append("零");
}
else {
for(int j=0;j<4;j++){
str[i].append(numToChar(array[i][j]));
if(j==0 && array[i][j]!=0)
str[i].append('仟');
else if(j==1 && array[i][j]!=0)
str[i].append('佰');
else if(j==2 && array[i][j]!=0)
str[i].append('拾');
}
//若个位为0,则不读0;若个位、十位都为0,则不读零;若个十百都为0,则不读零
if(array[i][3]==0){
str[i].deleteCharAt(str[i].lastIndexOf("零"));
if(array[i][2]==0){
str[i].deleteCharAt(str[i].lastIndexOf("零"));
if(array[i][1]==0)
str[i].deleteCharAt(str[i].lastIndexOf("零"));
}
}
//若个位不为0,十位为0:并且若百位为0,则只读一个0,若百位千位都为0,则只读一个0
else if(array[i][2]==0){
if(array[i][1]==0){
str[i].deleteCharAt(str[i].lastIndexOf("零"));
if(array[i][0]==0)
str[i].deleteCharAt(str[i].lastIndexOf("零"));
}
}
}
}
//若首段(即以亿为单位的)四位都为0,则将该段的“零”字删掉,否则加“亿”
if(pos[0]==-1)
str[0].deleteCharAt(0);
else
str[0].append("亿");
//若首段和第二段8位都为0,则再删掉第二段的“零”,否则加“万”
if(pos[1]==-1 && pos[0]==-1)
str[1].deleteCharAt(0);
else
str[1].append("万");
//若三段12位都为0,则再删一个“零”,否则加“元”
if(pos[0]!=-1 && pos[1]!=-1 && pos[2]==-1)
str[2].deleteCharAt(0);
else
str[2].append("元");
//处理小数部分
//若无小数部分,则“元”后面加上“整”
if(array1[1]==0 && array1[0]==0)
str[2].append("整");
else {
if(array1[0]==0)
str[3].append("零");
else{
str[3].append(numToChar(array1[0])+"角");
}
if(array1[1]!=0)
str[3].append(numToChar(array1[1])+"分");
}
str2.append(str[0].toString()+str[1]+str[2]+str[3]) ;
//使得首位不为0
int index = str2.indexOf("零");
while(index==0){
str2.deleteCharAt(index);
index = str2.indexOf("零");
}
return str2.toString();
}
public static void main(String[] args) {
Change change = new Change();
Scanner input = new Scanner(System.in);
System.out.println("请输入数字金额,以“0”结束");
double rmb = input.nextDouble();
while(rmb!=0){
String a = change.floatToRMB(rmb);
System.out.println(a);
rmb = input.nextDouble();
}
}
}