中文数字到阿拉伯数字转换

昨天博客上看到一童鞋面试微软的题目:
将中文数字转换成阿拉伯数字表示:
如 五千零一-->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;//与前一个单位之间的元素个数
		@Override
		public 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("零七零"));
	}
}

你可能感兴趣的:(中文)