中文大写数字转换为阿拉伯数字(java)
1、引言
昨天面試了微軟的暑期實習生,二面的時候面試官給出了這道題,起初拿到題目的時候感覺還挺簡單的,想著直接用遍歷加一個緩存應該就能搞定了,但是和面試官溝通了一會兒之后發現自己沒考慮到的還有很多,最后在面試官的提醒下磕磕絆絆的算是弄出了最優解,不過時間已經不多了,最后也沒有完全給出bug free的代碼,雖然面試應該是涼了,不過面試體驗還是很好的,微軟的面試官人特別溫柔,最后也給出了很多友善的建議,今天來重新復盤一遍這道題。
?
2、問題
請實現一個函數,輸入是string類型的中文數字,輸出是其對應的long值。例如:
輸入 --> 輸出
一百零一 --> 101
廿二 --> 22
二零一二 --> 2012
二十萬五百億三千零八萬一千零卅五 --> 20050030081035
注:需要考慮的中文數字包括:零一二三四五六七八九十廿卅百千萬億。
?
3、思路
首先第一步,建立漢字數字到阿拉伯數字的映射關系,可以使用數組、哈希表等結構,看個人愛好,我使用的是哈希表。
這道題我最后使用的是棧的思想,面試官說這道題有三種比較優雅的解法,一種是棧,一種是遞歸,另一種他沒說我暫時還沒想到。在我這種使用棧的解法中,我們依次從左向右遍歷漢字數字的各個字符,入棧出棧規則如下:
然后特殊的用例在于“二零一二”、“一九八七”這種類似年份的數字,實際上在真正表示數字的時候不會這么寫(應該是二千零十二、一千九百八十七),不過這種說法在年份上的確可以這么說,所以這一部分用例特殊處理,遍歷整個字符串,如果所有數字都小于10,那么直接生成答案返回(從末位向前依次乘上10的冪次再相加即可)
4、代碼實現
import java.util.HashMap; import java.util.Stack;/*** @author Huang Yirui* Created on 2020/4/25 9:45* <p>* MicroSoft 二面試題* 請實現一個函數,輸入是string類型的中文數字,輸出是其對應的long值。例如:* 輸入 --> 輸出* 一百零一 --> 101* 廿二 --> 22* 二零一二 --> 2012* 二十萬五百億三千零八萬一千零卅五 --> 20050030081035* 注:需要考慮的中文數字包括:零一二三四五六七八九十廿卅百千萬億。*/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、運行結果
?
因為測試樣例不多,所以可能還會有考慮不周的情況,如果有人發現有錯誤的地方,歡迎留言指正,謝謝!
?
原創博客,轉載請標明作者鏈接,謝謝!
總結
以上是生活随笔為你收集整理的中文大写数字转换为阿拉伯数字(java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯云服务器有多垃圾,腾讯云真的垃圾,无
- 下一篇: 201812CCF-CCSP竞赛:第1题