`
javaboy2006
  • 浏览: 183019 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

脑残系列之二:汉字转换数字

阅读更多
这是google的一道面试题.

将汉字转换成数字, 如下
一          1
十          10
十一        11
二十        20
二十一      21
一百        100
一百零一    101
一百一十    110
一百一十一  111

当然算法要能将所有的汉字数字转换成阿拉伯数字,同时兼顾性能.

路过的大家不妨试试看... ...

转自:http://topic.csdn.net/u/20081120/17/c66e30f9-ac70-4f8b-b046-eb5fcd8d2d61.html?seed=1739753267

javaeyer有更好的方法吗?

        java.util.List<String> chnList = new java.util.ArrayList<String>();
        chnList.add("一");
        chnList.add("十");
        chnList.add("一十五");
        chnList.add("十五");
        chnList.add("二十");
        chnList.add("二十三");
        chnList.add("一百");
        chnList.add("一百零一");
        chnList.add("一百一十");
        chnList.add("一百一十一");
        chnList.add("一千");
        chnList.add("一千零一");
        chnList.add("一千零三十一");
        chnList.add("一万零一");
        chnList.add("一万零二十一");
        chnList.add("一万零三百二十一");
        chnList.add("一万一千三百二十一");
        chnList.add("三千零十五万");
        chnList.add("三千零一十五万");
        chnList.add("三千五百六十八万零一百零一");
        chnList.add("五十亿三千零七十五万零六百二十二");
        chnList.add("十三亿三千零十五万零三百一十二");
        chnList.add("三千零七十八亿三千零十五万零三百一十二");
        chnList.add("一千二百五十八亿");
        chnList.add("一千二百五十八万亿零三千三百二十一");

        for (String chnStr : chnList) {
            chn2digit(chnStr);
        }

    //没有考虑兆及更大单位的情况
    public static void chn2digit(String chnStr) {
        //init map
        java.util.Map<String, Integer> unitMap = new java.util.HashMap<String, Integer>();
        unitMap.put("十", 10);
        unitMap.put("百", 100);
        unitMap.put("千", 1000);
        unitMap.put("万", 10000);
        unitMap.put("亿", 100000000);

        java.util.Map<String, Integer> numMap = new java.util.HashMap<String, Integer>();
        numMap.put("零", 0);
        numMap.put("一", 1);
        numMap.put("二", 2);
        numMap.put("三", 3);
        numMap.put("四", 4);
        numMap.put("五", 5);
        numMap.put("六", 6);
        numMap.put("七", 7);
        numMap.put("八", 8);
        numMap.put("九", 9);

        //队列
        List<Long> queue = new ArrayList<Long>();
        long tempNum = 0;
        for (int i = 0; i < chnStr.length(); i++) {
            char bit = chnStr.charAt(i);
            System.out.print(bit);
            //数字
            if (numMap.containsKey(bit + "")) {

                tempNum = tempNum + numMap.get(bit + "");

                //一位数、末位数、亿或万的前一位进队列
                if (chnStr.length() == 1
                    | i == chnStr.length() - 1
                    | (i + 1 < chnStr.length() && (chnStr.charAt(i + 1) == '亿' | chnStr
                        .charAt(i + 1) == '万'))) {
                    queue.add(tempNum);
                }
            }
            //单位
            else if (unitMap.containsKey(bit + "")) {

                //遇到十 转换为一十、临时变量进队列
                if (bit == '十') {
                    if (tempNum != 0) {
                        tempNum = tempNum * unitMap.get(bit + "");
                    } else {
                        tempNum = 1 * unitMap.get(bit + "");
                    }
                    queue.add(tempNum);
                    tempNum = 0;
                }

                //遇到千、百 临时变量进队列
                if (bit == '千' | bit == '百') {
                    if (tempNum != 0) {
                        tempNum = tempNum * unitMap.get(bit + "");
                    }
                    queue.add(tempNum);
                    tempNum = 0;
                }

                //遇到亿、万 队列中各元素依次累加*单位值、清空队列、新结果值进队列
                if (bit == '亿' | bit == '万') {
                    long tempSum = 0;
                    if (queue.size() != 0) {
                        for (int j = 0; j < queue.size(); j++) {
                            tempSum += queue.get(j);
                        }
                    } else {
                        tempSum = 1;
                    }
                    tempNum = tempSum * unitMap.get(bit + "");
                    queue.clear();//清空队列
                    queue.add(tempNum);//新结果值进队列
                    tempNum = 0;
                }
            }
        }

        //output
        System.out.println();
        long sum = 0;
        for (Long i : queue) {
            sum += i;
        }
        System.out.println(sum);
    }

一
1
十
10
一十五
15
十五
15
二十
20
二十三
23
一百
100
一百零一
101
一百一十
110
一百一十一
111
一千
1000
一千零一
1001
一千零三十一
1031
一万零一
10001
一万零二十一
10021
一万零三百二十一
10321
一万一千三百二十一
11321
三千零十五万
30150000
三千零一十五万
30150000
三千五百六十八万零一百零一
35680101
五十亿三千零七十五万零六百二十二
50000030750622
十三亿三千零十五万零三百一十二
13000030150312
三千零七十八亿三千零十五万零三百一十二
3078000030150312
一千二百五十八亿
125800000000
一千二百五十八万亿零三千三百二十一
1258000000003321


上面的代码有bug,“一亿三千万”等汉字转换时结果不正确。

更换数据结构和算法如下:

		java.util.List<String> chnNumList = new java.util.ArrayList<String>();
		chnNumList.add("一");
		chnNumList.add("十");
		chnNumList.add("一十五");
		chnNumList.add("十五");
		chnNumList.add("二十");
		chnNumList.add("二十三");
		chnNumList.add("一百");
		chnNumList.add("一百零一");
		chnNumList.add("一百一十");
		chnNumList.add("一百一十一");
		chnNumList.add("一千");
		chnNumList.add("一千零一");
		chnNumList.add("一千零三十一");
		chnNumList.add("一万零一");
		chnNumList.add("一万零二十一");
		chnNumList.add("一万零三百二十一");
		chnNumList.add("一万一千三百二十一");
		chnNumList.add("三千零十五万");
		chnNumList.add("三千零一十五亿");
		chnNumList.add("三千五百六十八万零一百零一");
		chnNumList.add("五十亿三千零七十五万零六百二十二");
		chnNumList.add("十三亿三千零十五万零三百一十二");
		chnNumList.add("三千零七十八亿三千零十五万零三百一十二");
		chnNumList.add("一千二百五十八亿");
		chnNumList.add("二十一亿三千万");
		chnNumList.add("一亿三千万");
		chnNumList.add("一亿零三千万");
		chnNumList.add("一千二百五十八万亿零三千三百二十一");

		for (String chnNum : chnNumList) {
			chnNum2Digit(chnNum);
		}
	}

	// 没有考虑兆及更大单位情况
	public static void chnNum2Digit(String chnNum) {
		// initialize map
		java.util.Map<String, Integer> unitMap = new java.util.HashMap<String, Integer>();
		unitMap.put("个", 1);// 仅在数据存储时使用
		unitMap.put("十", 10);
		unitMap.put("百", 100);
		unitMap.put("千", 1000);
		unitMap.put("万", 10000);
		unitMap.put("亿", 100000000);

		java.util.Map<String, Integer> numMap = new java.util.HashMap<String, Integer>();
		numMap.put("零", 0);
		numMap.put("一", 1);
		numMap.put("二", 2);
		numMap.put("三", 3);
		numMap.put("四", 4);
		numMap.put("五", 5);
		numMap.put("六", 6);
		numMap.put("七", 7);
		numMap.put("八", 8);
		numMap.put("九", 9);

		// 数据存储结构:
		// 单位 数量
		// "个" num
		// "十" num
		// "百" num
		// "千" num
		// "万" num
		// "亿" num
		java.util.Map<String, Long> dataMap = new java.util.LinkedHashMap<String, Long>();

		// 保存"亿"或"万"之前存在的多位数
		java.util.List<Long> multiNumList = new java.util.ArrayList<Long>();

		long tempNum = 0;
		for (int i = 0; i < chnNum.length(); i++) {
			char bit = chnNum.charAt(i);
			System.out.print(bit);

			// 因为"亿"或"万"存在多位情况,所以需要进行判断
			boolean isExist = false;
			// 存在"亿"或"万"情况(不计算当前索引位)
			if ((chnNum.indexOf('亿', i) != -1 || chnNum.indexOf('万', i) != -1)
					&& chnNum.charAt(i) != '亿' && chnNum.charAt(i) != '万') {
				isExist = true;
			}

			// 数字
			if (numMap.containsKey(bit + "")) {
				if (i != chnNum.length() - 1) {
					tempNum = tempNum + numMap.get(bit + "");
				}
				// 最末位数字情况
				else {
					dataMap.put("个", Long.valueOf(numMap.get(bit + "") + ""));
					tempNum = 0;
				}
			} else if (bit == '亿') {
				// 存在"万亿"情况,取出"万"位值*10000,0000后重新put到map
				if (i - 1 >= 0 && chnNum.charAt(i - 1) == '万') {
					Long dataValue = dataMap.get("万");
					if (dataValue != null && dataValue > 0) {
						dataMap.put("万", dataValue * unitMap.get(bit + ""));
					}
					continue;
				}

				// 最后一位数进list等待处理
				if (tempNum != 0) {
					multiNumList.add(tempNum);
				}
				// 处理"亿"之前的多位数
				long sum = 0;
				for (Long num : multiNumList) {
					sum += num;
				}
				multiNumList.clear();
				dataMap.put("亿", sum);
				tempNum = 0;
			} else if (bit == '万') {
				// 最后一位数进list等待处理
				if (tempNum != 0) {
					multiNumList.add(tempNum);
				}
				// 处理"万"之前的多位数
				long sum = 0;
				for (Long num : multiNumList) {
					sum += num;
				}
				multiNumList.clear();
				dataMap.put("万", sum);
				tempNum = 0;
			} else if (bit == '千' && tempNum > 0) {
				// 存在"亿"或"万"情况,临时变量值*"千"单位值进list等待处理
				if (isExist) {
					multiNumList.add(tempNum * unitMap.get(bit + ""));
					tempNum = 0;
				}
				// 不存在"亿"或"万"情况,临时变量值put到map
				else {
					dataMap.put("千", tempNum);
					tempNum = 0;
				}
			} else if (bit == '百' && tempNum > 0) {
				// 存在"亿"或"万"情况,临时变量值*"百"单位值进list等待处理
				if (isExist) {
					multiNumList.add(tempNum * unitMap.get(bit + ""));
					tempNum = 0;
				}
				// 不存在"亿"或"万"情况,临时变量值put到map
				else {
					dataMap.put("百", tempNum);
					tempNum = 0;
				}
			} else if (bit == '十') {
				// 存在"亿"或"万"情况,临时变量值*"十"单位值进list等待处理
				if (isExist) {
					if (tempNum != 0) {
						multiNumList.add(tempNum * unitMap.get(bit + ""));
						tempNum = 0;
					}
					// 将"十"转换成"一十"
					else {
						tempNum = 1 * unitMap.get(bit + "");
					}
				}
				// 不存在"亿"或"万"情况,临时变量值put到map
				else {
					if (tempNum != 0) {
						dataMap.put("十", tempNum);
					}
					// 将"十"转换成"一十"
					else {
						dataMap.put("十", 1l);
					}
					tempNum = 0;
				}
			}
		}

		// output
		System.out.println();
		long sum = 0;
		java.util.Set<String> keys = dataMap.keySet();
		for (String key : keys) {
			Integer unitValue = unitMap.get(key);
			Long dataValue = dataMap.get(key);
			sum += unitValue * dataValue;
		}
		System.out.println(sum);
	}

一
1
十
10
一十五
15
十五
15
二十
20
二十三
23
一百
100
一百零一
101
一百一十
110
一百一十一
111
一千
1000
一千零一
1001
一千零三十一
1031
一万零一
10001
一万零二十一
10021
一万零三百二十一
10321
一万一千三百二十一
11321
三千零十五万
30150000
三千零一十五亿
301500000000
三千五百六十八万零一百零一
35680101
五十亿三千零七十五万零六百二十二
5030750622
十三亿三千零十五万零三百一十二
1330150312
三千零七十八亿三千零十五万零三百一十二
307830150312
一千二百五十八亿
125800000000
二十一亿三千万
2130000000
一亿三千万
130000000
一亿零三千万
130000000
一千二百五十八万亿零三千三百二十一
1258000000003321
分享到:
评论
4 楼 cloverprince 2011-08-20  
记得小学学过,“按级读,数的中间有多少0都只读一个‘零’,每级末尾的0都不读。”
3 楼 javaboy2006 2008-11-24  
jasongreen 写道
stringToken 按优先级拆解 亿、万、千、百、十 是不是更好些

亿和万会存在多位情况,比如:三千五百零一万。拆分可能不是最佳方案。

bonny 写道
靠。没事干了

素质,素质,注意你的素质。
2 楼 bonny 2008-11-24  
靠。没事干了
1 楼 jasongreen 2008-11-24  
stringToken 按优先级拆解 亿、万、千、百、十 是不是更好些

相关推荐

Global site tag (gtag.js) - Google Analytics