1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 中文大写数字转换为阿拉伯数字(java)

中文大写数字转换为阿拉伯数字(java)

时间:2018-06-10 17:26:47

相关推荐

中文大写数字转换为阿拉伯数字(java)

1、引言

昨天面试了微软的暑期实习生,二面的时候面试官给出了这道题,起初拿到题目的时候感觉还挺简单的,想着直接用遍历加一个缓存应该就能搞定了,但是和面试官沟通了一会儿之后发现自己没考虑到的还有很多,最后在面试官的提醒下磕磕绊绊的算是弄出了最优解,不过时间已经不多了,最后也没有完全给出bug free的代码,虽然面试应该是凉了,不过面试体验还是很好的,微软的面试官人特别温柔,最后也给出了很多友善的建议,今天来重新复盘一遍这道题。

2、问题

请实现一个函数,输入是string类型的中文数字,输出是其对应的long值。例如:

输入 --> 输出

一百零一 --> 101

廿二 --> 22

二零一二 -->

二十万五百亿三千零八万一千零卅五 --> 0030081035

注:需要考虑的中文数字包括:零一二三四五六七八九十廿卅百千万亿。

3、思路

首先第一步,建立汉字数字到阿拉伯数字的映射关系,可以使用数组、哈希表等结构,看个人爱好,我使用的是哈希表。

这道题我最后使用的是栈的思想,面试官说这道题有三种比较优雅的解法,一种是栈,一种是递归,另一种他没说我暂时还没想到。在我这种使用栈的解法中,我们依次从左向右遍历汉字数字的各个字符,入栈出栈规则如下:

若栈为空,直接入栈若栈非空,分为两种情况 当前字符所代表的的数字小于栈顶数字,直接入栈当前字符所代表的的数字小于栈顶数字,依次弹出栈顶元素,直至栈顶数字大于当前数字,将弹出的数字相加后乘与当前数字,再将结果入栈

然后特殊的用例在于“二零一二”、“一九八七”这种类似年份的数字,实际上在真正表示数字的时候不会这么写(应该是二千零十二、一千九百八十七),不过这种说法在年份上的确可以这么说,所以这一部分用例特殊处理,遍历整个字符串,如果所有数字都小于10,那么直接生成答案返回(从末位向前依次乘上10的幂次再相加即可)

4、代码实现

import java.util.HashMap;import java.util.Stack;/*** @author Huang Yirui* Created on /4/25 9:45* <p>* MicroSoft 二面试题* 请实现一个函数,输入是string类型的中文数字,输出是其对应的long值。例如:* 输入 --> 输出* 一百零一 --> 101* 廿二 --> 22* 二零一二 --> * 二十万五百亿三千零八万一千零卅五 --> 0030081035* 注:需要考虑的中文数字包括:零一二三四五六七八九十廿卅百千万亿。*/public class ChineseToArabicNumerals {private static final HashMap<Character, Long> numMap = new HashMap<>();static {numMap.put('零', 0L);numMap.put('一', 1L);numMap.put('二', 2L);numMap.put('三', 3L);numMap.put('四', 4L);numMap.put('五', 5L);numMap.put('六', 6L);numMap.put('七', 7L);numMap.put('八', 8L);numMap.put('九', 9L);numMap.put('十', 10L);numMap.put('廿', 20L);numMap.put('卅', 30L);numMap.put('百', 100L);numMap.put('千', 1000L);numMap.put('万', 10_000L);numMap.put('亿', 100_000_000L);}public ChineseToArabicNumerals() {}public static long transChineseNum(String num) {if (num == null || num.length() == 0) return 0L;//特殊情况 :例如 二零一二 一九八七 这种类似年份的数字long result = 0;if ((result = transChineseNumYears(num)) != -1) {return result;}result = 0;Stack<Long> s = new Stack<>();for (int i = 0; i < num.length(); i++) {long curNum = numMap.get(num.charAt(i));if (s.isEmpty() || curNum < s.peek()) {s.push(curNum);} else {int temp = 0;while (!s.isEmpty() && s.peek() < curNum) {temp += s.pop();}temp = (temp == 0 ? 1 : temp);s.push(temp * curNum);}}while (!s.isEmpty()) {result += s.pop();}return result;}private static long transChineseNumYears(String num) {for (char c : num.toCharArray()) {if (numMap.get(c) >= 10L) {return -1;}}long result = 0;long unit = 1;for (int i = num.length() - 1; i >= 0; i--) {result += numMap.get(num.charAt(i)) * unit;unit *= 10;}return result;}public static void main(String[] args) {System.out.println("一百零一" + "--->" + transChineseNum("一百零一"));System.out.println("廿二" + "--->" + transChineseNum("廿二"));System.out.println("二十万五百亿三千零八万一千零卅五" + "--->" + transChineseNum("二十万五百亿三千零八万一千零卅五"));System.out.println("一百一十七" + "--->" + transChineseNum("一百一十七"));System.out.println("九千四百零二" + "--->" + transChineseNum("九千四百零二"));System.out.println("二零一二" + "--->" + transChineseNum("二零一二"));System.out.println("一九八七" + "--->" + transChineseNum("一九八七"));}}

5、运行结果

因为测试样例不多,所以可能还会有考虑不周的情况,如果有人发现有错误的地方,欢迎留言指正,谢谢!

原创博客,转载请标明作者链接,谢谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。