关于《中文数字阿拉伯数字相互转换》的代码
今天逛园子的时候看到一篇文章《中文数字阿拉伯数字相互转换》。感觉很有用,但是文中的代码不全,自己本地补写了,测试通过。记录一下。
DigitUtil.java
import java.util.*;
public class DigitUtil {
private static DigitUtil util;
public static DigitUtil getInstance() {
if (null == util) {
util = new DigitUtil();
}
return util;
}
/**
* 中文数字转阿拉伯数字
* 一万两千三百五十四 --> 12354
*
* @param chinese 阿拉伯数字
* @return 中文数字
*/
public String getNumberFromChinese(String chinese) {
String result = "0";
//将中文数字按四位进行截取。这样每一位里只有单一
List<String> lists = new ArrayList<>();
//暂时未使用到
int lastLevelIndex = 0;
//循环遍历,目的是将亿万进行分离
for (int i = ChineseNumber.highLevel.size() - 1; i >= 0; i--) {
//判断亿万单位出现索引
int levelIndex = chinese.indexOf(ChineseNumber.highLevel.get(i));
if (levelIndex > 0) {
//表示有单位索引 , 将单位前数据进行截取装入lists中。后面的继续循环截取
lists.add(chinese.substring(0, levelIndex));
chinese = chinese.substring(levelIndex + 1);
} else if (levelIndex == -1) {
//表示已经是最低单位了,不超过万。直接加入lists中 , 这里情况对应的是高位分离后,次高位开头是0的情况
lists.add(String.valueOf(ChineseNumber.number.get(0)));
} else if (levelIndex == 0) {
while (levelIndex > 1) {
levelIndex--;
lists.add(String.valueOf(ChineseNumber.number.get(0)));
}
//直接加入
lists.add(chinese);
}
}
//针对分离的四位数据,进行单独翻译
for (int i = 0; i < lists.size(); i++) {
//未使用
Integer highLevelIndex = lists.size() - i - 1;
//获取单元数据
String single = lists.get(i);
//对单元数据进行翻译 。
String nextResult = getNumberFromFChinese(single);
//lists中每位都是4位数截取 ,所以这里需要乘以10000进行叠加
Long next = Long.valueOf(Integer.valueOf(result) * (int) (Math.pow(10, 4)) + Integer.valueOf(nextResult));
result = next.toString();
}
//将开头0抹掉
result = result.replaceFirst("^(0+)", "");
return result;
}
/**
* 通过中文数字获取4位数阿拉伯数字
* 万以内的数据转换
*
* @param single
* @return
*/
private String getNumberFromFChinese(String single) {
String result = "0";
Integer highIndex = 1;
for (int i = 0; i < single.length(); i++) {
String str = String.valueOf(single.charAt(i));
int unit = ChineseNumber.level.indexOf(str);
int number = ChineseNumber.number.indexOf(str);
if (unit == -1) {
//当前数字是万以内的单位即 千百十其中之一
int next = 0;
if (i < single.length() - 1) {
//如果不是最后一位,则需要考虑当前位的权重
next = ChineseNumber.level.indexOf(String.valueOf(single.charAt(i + 1)));
}
result = String.valueOf(Integer.valueOf(result) + number * (int) (Math.pow(10, next)));
}
}
//权重叠加
result = "" + Integer.valueOf(result) * (int) (Math.pow(10, highIndex - 1));
return result;
}
/**
* 阿拉伯数字转中文数字
* 12354 --> 一万两千三百五十四
*
* @param alabo 阿拉伯数字
* @return 中文数字
*/
public String getNumberFromAlabo(String alabo) {
String result = "";
List<String> list = new ArrayList<>();
for (int length = alabo.length() - 1; length >= 0; length--) {
list.add(String.valueOf(alabo.charAt(length)));
}
List<List<String>> lists = CollectionUtil.averageSize(list, 4);
Collections.reverse(lists);
if (CollectionUtil.isNotEmpty(lists)) {
for (int index = 0; index < lists.size(); index++) {
List<String> singleNumList = lists.get(index);
//反转集合
Collections.reverse(singleNumList);
//默认0 false
Boolean zeroflag = false;
String chinese = "";
for (int j = 0; j < singleNumList.size(); j++) {
Integer number = Integer.valueOf(singleNumList.get(j));
if (number == 0 && !zeroflag && afterNotAllZero(singleNumList, j)) {
//第一次遇到0 且后面有小单位内并不是全为0
chinese += ChineseNumber.number.get(number);
//修改遇零状态true
zeroflag = true;
} else if (number != 0) {
//映射出对应的中文数字
chinese += ChineseNumber.number.get(number) + ChineseNumber.level.get(singleNumList.size() - j - 1);
}
}
if (index == lists.size() && chinese.substring(0, 1).equals(ChineseNumber.number.get(0))) {
//条件永远不成立。
chinese = chinese.substring(1);
}
//并不是全部为0,该高级单位才会生效
if (chinese.length() > 0 && !ChineseNumber.highLevel.contains(chinese.substring(chinese.length() - 1))) {
result += chinese + ChineseNumber.highLevel.get(lists.size() - 1 - index);
}
}
}
return result;
}
/**
* 判断singleNumList在j位置之后是否全是0
*
* @param singleNumList
* @param j
* @return
*/
private boolean afterNotAllZero(List<String> singleNumList, int j) {
for (int i = j + 1; i < singleNumList.size(); i++) {
if (!"0".equals(singleNumList.get(i))) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Integer right = 0;
Integer total = 1000000;
Integer number = 411011989;
System.out.println(number);
String chinese = DigitUtil.getInstance().getNumberFromAlabo(number.toString());
System.out.println(chinese);
String alabo = DigitUtil.getInstance().getNumberFromChinese(chinese);
System.out.println(alabo);
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < total; i++) {
number = MathUtil.getRandom(1, 1000000000);
//System.out.println(i);
//Integer number = 400001989;
chinese = DigitUtil.getInstance().getNumberFromAlabo(number.toString());
alabo = DigitUtil.getInstance().getNumberFromChinese(chinese);
boolean equals = alabo.equals(number.toString());
if (equals) {
right++;
} else {
Map<String, Object> map = new HashMap<>();
map.put("number", number);
map.put("alabo", alabo);
map.put("chinese", chinese);
list.add(map);
}
}
for (Map<String, Object> map : list) {
System.out.println(map);
}
System.out.println("成功率:" + Double.valueOf(right / (double) total));
}
}
ChineseNumber.java
import java.util.ArrayList;
import java.util.List;
public class ChineseNumber {
public static final List<String> highLevel;
public static final List<String> number;
public static final List<String> level;
static {
highLevel = new ArrayList<>();
highLevel.add("");
highLevel.add("万");
highLevel.add("亿");
number = new ArrayList<>();
number.add("零");
number.add("一");
number.add("二");
number.add("三");
number.add("四");
number.add("五");
number.add("六");
number.add("七");
number.add("八");
number.add("九");
level = new ArrayList<>();
level.add("");
level.add("十");
level.add("百");
level.add("千");
}
}
MathUtil.java
import java.util.Random;
public class MathUtil {
public static Integer getRandom(int min, int max) {
Random rand = new Random();
return rand.nextInt(max - min + 1) + min;
}
}
CollectionUtil.java
import java.util.ArrayList;
import java.util.List;
public class CollectionUtil {
public static List averageSize(List list, int count) {
List<List<String>> result = new ArrayList();
int size = list.size();
List temp;
for (int i = 0; i < size; i = i + count) {
temp = new ArrayList<>();
for (int j = 0; j < count; j++) {
if (i + j < size) {
temp.add(list.get(i + j));
} else {
break;
}
}
result.add(temp);
}
return result;
}
public static boolean isNotEmpty(List lists) {
if (lists == null) {
return false;
}
return !lists.isEmpty();
}
}