Java浮点数转化为人民币读法字符串
效果图(零的处理有点复杂)
效果是出来了,但是觉得代码好臃肿
主要思路
整数部分比较难处理
1、把12位整数划分为3组一组4位数字
2、分别遍历这三组数字
3、每遍历一组计算一次有效位数
4、根据有效位数的不同来判别零的增减
每一组数字“0”的分布有16种情况:
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
通过有效位数分为4组,然后在进行判断
import java.awt.desktop.SystemSleepEvent;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Scanner;
public class Num2Rmb {
private String[] hanArr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
private String[] unitArr = {"十","百","千"};
boolean flag3 = true;
/**
* 把一个浮点数分解成整数部分和小数部分的字符串
* @param num 需要被分解的浮点数
* @return 分解出来的整数部分和小数部分。第一个数组元素是整数部分,第二个数组元素是小数部分
*/
private String[] divide(double num){
//将一个浮点数强制转化成long型,即可得到整数部分
var zheng = (long)num;
//将浮点数减去整数部分得到小数部分,小数部分乘100取整得到2位小数
var xiao = Math.round((num - zheng)*100);
//使用了两种方法将整数转化为字符串
return new String[]{zheng+"",String.valueOf(xiao)};
}
/**
* 将浮点数转化为人民币读法的字符串
* @param haveDivedNum 已经由divide()函数分离得到的字符数组。第一个数组元素是整数部分,第二个数组元素是小数部分。
* @return 将浮点数转化成人民币读法的字符串
*/
private String toHanStr(String[] haveDivedNum){
var result = "";
var zhengDigit = haveDivedNum[0].length();
if (zhengDigit < 5){ //如果整数位数小于5,直接遍历后4位
//如果整数部分长度为1,并且字符串的值为0,则不输出”元“
if (haveDivedNum[0].length() == 1 && haveDivedNum[0].charAt(0)-48 == 0){
result = erLastFourNum(haveDivedNum[0]) + xiao2RMB(haveDivedNum[1]) ;
}else {
result = erLastFourNum(haveDivedNum[0]) + "元" + xiao2RMB(haveDivedNum[1]) ;
}
}else if (zhengDigit < 9){//如果整数位数大于4小于9
result = erMidForNum(haveDivedNum[0]) + erLastFourNum(haveDivedNum[0]) + "元" + xiao2RMB(haveDivedNum[1]);
}else if (zhengDigit < 13 ){
result = erFirstFourNum(haveDivedNum[0])+erMidForNum(haveDivedNum[0]) + erLastFourNum(haveDivedNum[0]) + "元" + xiao2RMB(haveDivedNum[1]);
}else result = "暂时不支持12位数字!";
return result;
}
/**
* 将浮点数分离后的小数部分转化为人民币读法的字符串
* @param numStr 浮点数分离后的小数部分
* @return 浮点数分离后的小数部分转化为人民币读法的字符串
*/
private String xiao2RMB(String numStr){
if(numStr.charAt(0)-48 != 0){
return hanArr[numStr.charAt(0)-48] + "角" + hanArr[numStr.charAt(1)-48] + "分";
}else return "";
}
/**
* 遍历整数部分的最后四位
* @param numStr 浮点数分离后的整数部分
* @return 整数部分最后四位的中文读法
*/
private String erLastFourNum(String numStr) {
var effectNum = 4;
StringBuilder result = new StringBuilder();
int digit = numStr.length();
var notAdd0_digit = digit;
var startIndex = digit - 4;
if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
//补零操作,(4 - digit)为所需补零的个数
StringBuilder numStrBuilder = new StringBuilder(numStr);
for (var i = 0; i < 4 - digit; i++) {
numStrBuilder.insert(0, "0");
}
numStr = numStrBuilder.toString();
//更新startIndex和digit
startIndex = 0;
digit = numStr.length();
}
for (var i = startIndex; i < digit; i++) {//遍历最后四位
//计算有效位数effectNum
//将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
var num = numStr.charAt(i) - 48;
if (num == 0) {
effectNum -= 1;
} else {//遇到num不为0则跳出循环,得到有效位数
break;
}
}
// System.out.println(effectNum);
switch (effectNum) {
case 0://全是0
result.append("");//不输出
break;
case 1://个位不为0,中文读法为几万"零"几
var num1 = numStr.charAt(digit - 1) - 48;
if (notAdd0_digit < 5){//如果没有补零时的实际位数小于5,则前面需要加"零",否则不用加
result.append(hanArr[num1]);
}else result.append("零").append(hanArr[num1]);
break;
case 2:
for (var i = startIndex; i < digit; i++) {//遍历最后四位
var num2 = numStr.charAt(i) - 48;
if (i != digit - 1 && num2 != 0) {
if (num2 == 1){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
result.append(unitArr[digit - 2 - i]);
}else result.append(hanArr[num2]).append(unitArr[digit - 2 - i]);
} else if (i == digit - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
result.append(hanArr[num2]);
}else if (i == digit - 1 && num2 == 0){//如果个位为0则不用加零
result.append("");
}
}
if (notAdd0_digit < 5){
result.append("");
}else result.insert(0,"零");//实际位数大于5则需要在前面补0
break;
case 3:
for (var i = startIndex; i < digit; i++) {
var num3 = numStr.charAt(i)-48;
if (i != digit - 1 && num3 != 0){//这里没有处理个位数
result.append(hanArr[num3]).append(unitArr[digit - 2 - i]);
}else if (i != digit - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
if (numStr.charAt(digit-1)-48==0) result.append("");
else result.append("零");
}else if (i == digit - 1 && num3 !=0){
result.append(hanArr[num3]);
}
}
if (notAdd0_digit < 5){
result.append("");
}else {
result.insert(0,"零");
}
break;
case 4:
boolean flag = false;
//先加单位
for (var i = startIndex; i < digit; i++) {
var num4 = numStr.charAt(i)-48;
if (i != digit -1 && num4 != 0){
result.append(hanArr[num4]).append(unitArr[digit - 2 - i]);
}else if (i != digit -1 && num4 == 0 && (numStr.charAt(digit-1)-48 != 0|numStr.charAt(digit-2)-48!=0)){
if (flag == false){
result.append("零");
flag = true;
}else {
result.append("");
}
}else if (i == digit - 1 && num4 !=0){
result.append(hanArr[num4]);
}
}
break;
}
return result.toString();
}
/**
* 将5~8位数字转化为中文读法
* @param numStr 浮点数分离后的整数部分
* @return 5~8位数字的中文读法
*/
private String erMidForNum(String numStr){
var flag1 = true;
var effectNum = 4;
StringBuilder result = new StringBuilder();
int digit = numStr.length();
var notAdd0_digit = digit;
var startIndex = digit - 8;
var endIndex = digit - 4 ;
if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
//补零操作,(4 - digit)为所需补零的个数
StringBuilder numStrBuilder = new StringBuilder(numStr);
for (var i = 0; i < 8 - digit; i++) {
numStrBuilder.insert(0, "0");
}
numStr = numStrBuilder.toString();
//更新startIndex和digit
startIndex = 0;
digit = numStr.length();
endIndex = digit - 4;
}
for (var i = startIndex; i <endIndex; i++) {//遍历最后四位
//计算有效位数effectNum
//将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
var num = numStr.charAt(i) - 48;
if (num == 0) {
effectNum -= 1;
} else {//遇到num不为0则跳出循环,得到有效位数
break;
}
}
switch (effectNum) {
case 0://全是0
boolean flag4 = false;
for (var i = digit - 4; i < digit; i++){
if (numStr.charAt(i)-48!=0){
flag4 = true;
break;
}
}
if (flag4){//为真说明最后4位都为0
result.append("零");
}else {
result.append("");
}
flag1 =false;
break;
case 1://个位不为0,中文读法为几万"零"几
var num1 = numStr.charAt(endIndex - 1) - 48;
if (notAdd0_digit <= 5){//如果没有补零时的实际位数小于5,则前面需要加"零",否则不用加
result.append(hanArr[num1]);
}else result.append("零").append(hanArr[num1]);
break;
case 2:
for (var i = startIndex; i < endIndex; i++) {//遍历最后四位
var num2 = numStr.charAt(i) - 48;
if (i != endIndex - 1 && num2 != 0) {
if (num2 == 1 && notAdd0_digit == 6){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
result.append(unitArr[endIndex - 2 - i]);
}else result.append(hanArr[num2]).append(unitArr[endIndex - 2 - i]);
} else if (i == endIndex - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
result.append(hanArr[num2]);
}else if (i == endIndex - 1 && num2 == 0){//如果个位为0则不用加零
result.append("");
}
}
if (notAdd0_digit < 8){
result.append("");
}else result.insert(0,"零");//实际位数大于8则需要在前面补0
break;
case 3:
for (var i = startIndex; i < endIndex; i++) {
var num3 = numStr.charAt(i)-48;
if (i != endIndex - 1 && num3 != 0){//这里没有处理个位数
result.append(hanArr[num3]).append(unitArr[endIndex - 2 - i]);
}else if (i != endIndex - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
if (numStr.charAt(endIndex-1)-48==0) result.append("");
else result.append("零");
}else if (i == endIndex - 1 && num3 !=0){
result.append(hanArr[num3]);
}
}
if (notAdd0_digit < 8){
result.append("");
}else {
result.insert(0,"零");
}
break;
case 4:
boolean flag = false;
//先加单位
for (var i = startIndex; i < endIndex; i++) {
var num4 = numStr.charAt(i)-48;
if (i != endIndex -1 && num4 != 0){
result.append(hanArr[num4]).append(unitArr[endIndex - 2 - i]);
}else if (i != endIndex -1 && num4 == 0 && (numStr.charAt(endIndex-1)-48 != 0|numStr.charAt(endIndex-2)-48!=0)){
if (flag == false){
result.append("零");
flag = true;
}else {
result.append("");
}
}else if (i == endIndex - 1 && num4 !=0){
result.append(hanArr[num4]);
}
}
break;
}
if(flag1){
return result.append("万").toString();
}else {
return result.toString();
}
}
/**
* 将9~12位数字转化为中文读法
* @param numStr 分离后的整数部分
* @return 9~12位数字的中文读法
*/
private String erFirstFourNum(String numStr){
var effectNum = 4;
StringBuilder result = new StringBuilder();
int digit = numStr.length();
var notAdd0_digit = digit;
var startIndex = 8 - digit;
var endIndex = digit - 8 ;
if (startIndex < 0) {//如果小于0,说明输入浮点数的整数部分位数小于4位需要补0
StringBuilder numStrBuilder = new StringBuilder(numStr);
for (var i = 0; i < 12- digit; i++) {
numStrBuilder.insert(0, "0");
}
numStr = numStrBuilder.toString();
//更新startIndex和digit
startIndex = 0;
digit = numStr.length();
endIndex = digit - 8;
}
for (var i = startIndex; i <endIndex; i++) {//遍历最后四位
//计算有效位数effectNum
//将char型的数字转化为int型的数字,因为它们的ASCII码相差48所以减去48
var num = numStr.charAt(i) - 48;
if (num == 0) {
effectNum -= 1;
} else {//遇到num不为0则跳出循环,得到有效位数
break;
}
}
switch (effectNum) {
case 0://全是0
result.append("");//
break;
case 1://个位不为0,中文读法为几万"零"几
var num1 = numStr.charAt(endIndex - 1) - 48;
result.append(hanArr[num1]);
break;
case 2:
for (var i = startIndex; i < endIndex; i++) {//遍历最后四位
var num2 = numStr.charAt(i) - 48;
if (i != endIndex - 1 && num2 != 0) {
if (num2 == 1 && notAdd0_digit == 10){//如果十位为1那么“壹”不用读,壹十壹元读作十壹元
result.append(unitArr[endIndex - 2 - i]);
}else result.append(hanArr[num2]).append(unitArr[endIndex - 2 - i]);
} else if (i == endIndex - 1 && num2 != 0){//如果个位不为0则加上对应数值的汉字
result.append(hanArr[num2]);
}else if (i == endIndex - 1 && num2 == 0){//如果个位为0则不用加零
result.append("");
}
}
break;
case 3:
for (var i = startIndex; i < endIndex; i++) {
var num3 = numStr.charAt(i)-48;
if (i != endIndex - 1 && num3 != 0){//这里没有处理个位数
result.append(hanArr[num3]).append(unitArr[endIndex - 2 - i]);
}else if (i != endIndex - 1 && i != startIndex && num3 ==0){//如果中间有个0,第一个零不能算进去
if (numStr.charAt(endIndex-1)-48==0) result.append("");
else result.append("零");
}else if (i == endIndex - 1 && num3 !=0){
result.append(hanArr[num3]);
}
}
break;
case 4:
boolean flag = false;
//先加单位
for (var i = startIndex; i < endIndex; i++) {
var num4 = numStr.charAt(i)-48;
if (i != endIndex -1 && num4 != 0){
result.append(hanArr[num4]).append(unitArr[endIndex - 2 - i]);
}else if (i != endIndex -1 && num4 == 0 && (numStr.charAt(endIndex-1)-48 != 0|numStr.charAt(endIndex-2)-48!=0)){
if (flag == false){
result.append("零");
flag = true;
}else {
result.append("");
}
}else if (i == endIndex - 1 && num4 !=0){
result.append(hanArr[num4]);
}
}
break;
}
return result.append("亿").toString();
}
public static void main(String[] args) {
var nr = new Num2Rmb();
var line = "";
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("请输入一个浮点数:(输入“q”退出):");
line = scanner.nextLine();
if (line.equals("q")){
break;
}
try {
var d = Double.parseDouble(line);
var result = nr.toHanStr(nr.divide(d));
if (result.isEmpty()) {
System.out.println("请输入大于0的数");
} else {
System.out.println("中文读法为:" + result);
System.out.println("-----------------------------------------------");
}
} catch (Exception e) {
System.out.println("输入错误!");
System.out.println("----------------------------");
}
}
}
}