中文数字到阿拉伯数字转换
昨天博客上看到一童鞋面试微软的题目:
将中文数字转换成阿拉伯数字表示:
如 五千零一-->5001 五千一 5100
package org.jf.alg;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Stack;/** * * @author junfeng.chen * */public class DigitTranslator {private static String [] CH_NUM_ARRAY = {"零","一","二","三","四","五","六","七","八","九"};private static String [] CH_UNIT_ARRAY = {"个","十","百","千","万","亿"};private static final Map<String,Integer> UNIT_MAP = new HashMap<String,Integer>();private static final Map<String,Integer> DIGIT_MAP = new HashMap<String,Integer>();static {UNIT_MAP.put("个", 1);UNIT_MAP.put("十", 10);UNIT_MAP.put("百",100);UNIT_MAP.put("千",1000);UNIT_MAP.put("万",10000);UNIT_MAP.put("亿",100000000);for(int i=0;i<CH_NUM_ARRAY.length;i++){DIGIT_MAP.put(CH_NUM_ARRAY[i], i);}}/** * 将中文格式的数字字符串转换为数字 * @param ch_style_str * @return */public static long toMathNumber(String ch_style_str){List<String> groups = split(ch_style_str);long sum = 0 ;for(String str : groups){sum += translate(str);}return sum;}private static int translate(String str){String last_char = str.charAt(str.length()-1)+"";if(DIGIT_MAP.containsKey(last_char))//如果最后一个是数字 查找前一个单位 {String last_unit = "";for(int indx = str.length()-2;indx>=0;indx--){String ch = str.charAt(indx)+"";if(UNIT_MAP.containsKey(ch)){int i=0;for(;i<CH_UNIT_ARRAY.length;i++){if(CH_UNIT_ARRAY[i] .equals(ch) )break;}last_unit = CH_UNIT_ARRAY[--i];break;}else if(ch.equals("零")){last_unit = "个";break;}}str = str+last_unit;}int pre_unit = 1;boolean is_last_unit = false;Stack<Integer> stack = new Stack<Integer>();for(int i=0;i<str.length();i++){String ch = str.charAt(i)+"";if(UNIT_MAP.get(ch)!=null){int unit = UNIT_MAP.get(ch);if(stack.isEmpty()){stack.push(unit*1);}else{if(is_last_unit){int t = stack.pop();t = t* unit;stack.push(t);}else{if(unit > pre_unit){int t = stack.pop();if(!stack.isEmpty())t = t+stack.pop();t*=unit;stack.push(t);}else{int t = stack.pop();t*=unit;if(!stack.isEmpty())stack.push(t+stack.pop());}}}is_last_unit = true;pre_unit = unit;}else{int num = DIGIT_MAP.get(ch);stack.push(num);is_last_unit = false;}}int res = stack.pop();while(!stack.isEmpty())res = stack.pop() + res;return res;}private static List<String> split(String ch_style_str){int unit = -1;int last_pre_num = 0;String ch = "";Stack<UnitRecord> unit_stack = new Stack<UnitRecord>();List<String> groups = new ArrayList<String>();//遍历字符串 获得一个单位字符时:/** * 查看栈顶元素 * 如果栈顶 > unit 则push * 如果 栈顶 < = unit 则 * pop 直到栈顶 > unit * 并用unit与最后一个pop出来的元素的下标取子字符串 形成一个分组 */for(int i=0;i<ch_style_str.length();i++){ch = ch_style_str.charAt(i)+"";if(UNIT_MAP.get(ch)!=null){unit = UNIT_MAP.get(ch);UnitRecord record = new UnitRecord();record.unit = unit;record.index = i;record.pre_num = last_pre_num;last_pre_num = 0;if(unit_stack.isEmpty()){unit_stack.push(record);}else{UnitRecord pre_record = unit_stack.peek();UnitRecord pre_record1 = null;//最后一次pop出来的元素if(record.compareTo(pre_record)>0){while(record.compareTo(pre_record)>0 && !unit_stack.isEmpty()){pre_record1 = unit_stack.pop();if(!unit_stack.isEmpty())pre_record = unit_stack.peek();}groups.add(ch_style_str.substring(pre_record1.index-pre_record1.pre_num, i+1));}else{unit_stack.push(record);}}}else{last_pre_num ++;}}if(!unit_stack.isEmpty()){UnitRecord pre_record = unit_stack.peek();while(!unit_stack.isEmpty()){pre_record = unit_stack.pop();}groups.add(ch_style_str.substring(pre_record.index - pre_record.pre_num));}return groups;}private static class UnitRecord implements Comparable{ int index; int unit; int pre_num = 0;//与前一个单位之间的元素个数@Overridepublic int compareTo(Object o) {UnitRecord u = (UnitRecord)o;if(this.unit == u.unit)return 0;if (this.unit > u.unit)return 1;return -1;} }public static void main(String args[]){String s = "十四亿零二十三万五千一百二十";//String ss = "五千万零四百七十";System.out.println(toMathNumber(s));System.out.println(toMathNumber(ss));System.out.println(translate("五千零一百"));System.out.println(translate("二千零一"));System.out.println(translate("零七零"));}}