擦,今天在网上搜了好久,居然没有阿拉伯数字替换中文数字的算法,
后来好不容易找了一个,居然是错的,日了狗了.
搞了半天,最后还是自己动手写了一个.
测试:
import static org.junit.Assert.*;
import org.junit.Test;
public class S2Test {
@Test
public void testS2() {
assertEquals(S2.s2("零"), 0);
assertEquals(S2.s2("一"), 1);
assertEquals(S2.s2("十四"), 14);
assertEquals(S2.s2("二十二"), 22);
assertEquals(S2.s2("一百零一"), 101);
assertEquals(S2.s2("一千零一十"), 1010);
assertEquals(S2.s2("三万九千八百五十七"), 39857);
assertEquals(S2.s2("二十万"), 200000);
assertEquals(S2.s2("九千七百零六万五百零一"), 97060501);
}
}
源码:
import java.util.HashMap;
import java.util.Map;
public class S2 {
public final static Map<Character,Integer> digit = new HashMap<>();
public final static Map<Character,Integer> position = new HashMap<>();
static{
digit.put('零', 0);
digit.put('一', 1);
digit.put('二', 2);
digit.put('三', 3);
digit.put('四', 4);
digit.put('五', 5);
digit.put('六', 6);
digit.put('七', 7);
digit.put('八', 8);
digit.put('九', 9);
position.put('十', 1);
position.put('百',2);
position.put('千', 3);
}
/**
* 将num中文转为阿拉伯数字
* 考虑范围: 0~9999_9999
* @param num
* @return
*/
public static int s2(String num){
//一共八位
char []nums = new char[8];
int p = 7,now = 7;
char []c = num.toCharArray();
/**
* 从右到左逐个字符解析
* 通过p控制万位,pp控制万以下的单位,now记录当前单位
*/
for(int i = c.length-1;i>=0;i--){
if(c[i]=='万'){
now = p = 3;
}else{
int d = digit.getOrDefault(c[i], -1);
if(d==0){
continue;
}if(d==-1){
int pp = position.getOrDefault(c[i], -1);
if(pp==-1)
throw new RuntimeException("\""+num+"\"中存在无法解析的字符: "+i+":"+c[i]);
else{
now = p-pp;
//允许"一十"省略"一",即"十"
if(now==6)
nums[now] = 1;
}
}else{
nums[now] = (char) d;
}
}
}
for (int i = 0; i < nums.length; i++) {
nums[i] = (char) (nums[i]+'0');
}
return Integer.parseInt(new String(nums));
}
}