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

昨天博客上看到一童鞋面试微软的题目:
将中文数字转换成阿拉伯数字表示:
如 五千零一-->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("零七零"));
}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值