日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/14 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中文大写数字转换为阿拉伯数字(java) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、引言

昨天面試了微軟的暑期實(shí)習(xí)生,二面的時(shí)候面試官給出了這道題,起初拿到題目的時(shí)候感覺還挺簡(jiǎn)單的,想著直接用遍歷加一個(gè)緩存應(yīng)該就能搞定了,但是和面試官溝通了一會(huì)兒之后發(fā)現(xiàn)自己沒考慮到的還有很多,最后在面試官的提醒下磕磕絆絆的算是弄出了最優(yōu)解,不過時(shí)間已經(jīng)不多了,最后也沒有完全給出bug free的代碼,雖然面試應(yīng)該是涼了,不過面試體驗(yàn)還是很好的,微軟的面試官人特別溫柔,最后也給出了很多友善的建議,今天來重新復(fù)盤一遍這道題。

?

2、問題

請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù),輸入是string類型的中文數(shù)字,輸出是其對(duì)應(yīng)的long值。例如:

輸入 --> 輸出

一百零一 --> 101

廿二 --> 22

二零一二 --> 2012

二十萬五百億三千零八萬一千零卅五 --> 20050030081035

注:需要考慮的中文數(shù)字包括:零一二三四五六七八九十廿卅百千萬億。

?

3、思路

首先第一步,建立漢字?jǐn)?shù)字到阿拉伯?dāng)?shù)字的映射關(guān)系,可以使用數(shù)組、哈希表等結(jié)構(gòu),看個(gè)人愛好,我使用的是哈希表。

這道題我最后使用的是棧的思想,面試官說這道題有三種比較優(yōu)雅的解法,一種是棧,一種是遞歸,另一種他沒說我暫時(shí)還沒想到。在我這種使用棧的解法中,我們依次從左向右遍歷漢字?jǐn)?shù)字的各個(gè)字符,入棧出棧規(guī)則如下:

  • 若棧為空,直接入棧
  • 若棧非空,分為兩種情況
  • 當(dāng)前字符所代表的的數(shù)字小于棧頂數(shù)字,直接入棧
  • 當(dāng)前字符所代表的的數(shù)字小于棧頂數(shù)字,依次彈出棧頂元素,直至棧頂數(shù)字大于當(dāng)前數(shù)字,將彈出的數(shù)字相加后乘與當(dāng)前數(shù)字,再將結(jié)果入棧
  • 然后特殊的用例在于“二零一二”、“一九八七”這種類似年份的數(shù)字,實(shí)際上在真正表示數(shù)字的時(shí)候不會(huì)這么寫(應(yīng)該是二千零十二、一千九百八十七),不過這種說法在年份上的確可以這么說,所以這一部分用例特殊處理,遍歷整個(gè)字符串,如果所有數(shù)字都小于10,那么直接生成答案返回(從末位向前依次乘上10的冪次再相加即可)

    4、代碼實(shí)現(xiàn)

    import java.util.HashMap; import java.util.Stack;/*** @author Huang Yirui* Created on 2020/4/25 9:45* <p>* MicroSoft 二面試題* 請(qǐng)實(shí)現(xiàn)一個(gè)函數(shù),輸入是string類型的中文數(shù)字,輸出是其對(duì)應(yīng)的long值。例如:* 輸入 --> 輸出* 一百零一 --> 101* 廿二 --> 22* 二零一二 --> 2012* 二十萬五百億三千零八萬一千零卅五 --> 20050030081035* 注:需要考慮的中文數(shù)字包括:零一二三四五六七八九十廿卅百千萬億。*/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;//特殊情況 :例如 二零一二 一九八七 這種類似年份的數(shù)字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、運(yùn)行結(jié)果

    ?

    因?yàn)闇y(cè)試樣例不多,所以可能還會(huì)有考慮不周的情況,如果有人發(fā)現(xiàn)有錯(cuò)誤的地方,歡迎留言指正,謝謝!

    ?

    原創(chuàng)博客,轉(zhuǎn)載請(qǐng)標(biāo)明作者鏈接,謝謝!

    總結(jié)

    以上是生活随笔為你收集整理的中文大写数字转换为阿拉伯数字(java)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。