• 请不要在回答技术问题时复制粘贴 AI 生成的内容
jin5354
V2EX  ›  程序员

出题:如何优雅转换大写数字? 19 转成 十九

  •  
  •   jin5354 ·
    jin5354 · Sep 6, 2017 · 6937 views
  •   You need to sign in to view this topic
    This topic created in 3347 days ago, the information mentioned may be changed or developed.
    天杀的需求竟然要展示大写数字,我要和产品搏命

    0 -> 零
    5 -> 五
    19 -> 十九
    20 -> 二十
    21 -> 二十一
    100 -> 一百
    Supplement 1  ·  Sep 6, 2017
    我知道有轮子。
    本来是想看看这种繁琐的小需求,有没人有搞出优雅姿势让我学习学习(比如 codewar 上的炫酷单行题解),所以说是出题。
    46 replies  •  2017-09-07 11:25:19 +08:00
    Light3
    Light3
    Sep 6, 2017❤️3
    1
    https://github.com/wilon/php-number2chinese

    一会给下我帮你搜的电费
    xfspace
    xfspace
    Sep 6, 2017 via Android
    2
    数字前加个“大写”

    大写 0
    大写 1

    没毛病
    Famio
    Famio
    Sep 6, 2017
    3
    上古:<big>1234567890</big>
    Sanko
    Sanko
    Sep 6, 2017 via Android
    4
    记得给二楼转一下电费
    顺带给我发一下流量费
    zonyitoo
    zonyitoo
    Sep 6, 2017
    5
    自己写一个到底有多难?
    misaka19000
    misaka19000
    Sep 6, 2017 via Android
    6
    赔我点进来的流量费
    asj
    asj
    Sep 6, 2017
    7
    这个自己写写也就一两个小时吧
    maplerecall
    maplerecall
    Sep 6, 2017 via Android
    8
    @asj 这个很简单吧,十分钟就够了…
    yuanfnadi
    yuanfnadi
    Sep 6, 2017
    9
    这种普遍的需求,git 上任何语言肯定有轮子。
    debuggerx
    debuggerx
    Sep 6, 2017❤️1
    10

    当年自学 java 的笔记……
    虽然早就不写 java 了,这个小本子却总是习惯性地装在包里。。。
    0ZXYDDu796nVCFxq
    0ZXYDDu796nVCFxq
    Sep 6, 2017 via iPhone
    11
    提这需求不是很正常吗?
    再说调个轮子也就两行代码
    xinghelee
    xinghelee
    Sep 6, 2017
    12
    xinghelee
    xinghelee
    Sep 6, 2017
    13
    看错了,以为是日常使用,请忽略楼上截图
    ipconfiger
    ipconfiger
    Sep 6, 2017
    14
    大写应该是 拾玖 才对吧
    kslr
    kslr
    Sep 6, 2017
    15
    arr [
    0 = 零
    1 = 壹
    2 = 贰
    3 = 叁
    ]

    第 1 天
    第 arr[1]天
    aksoft
    aksoft
    Sep 6, 2017
    16
    @debuggerx 你这个本子 我喜欢
    8Cangtou
    8Cangtou
    Sep 6, 2017
    17
    reduce~~~~map~~~~
    silymore
    silymore
    Sep 6, 2017 via iPhone
    18
    可以来个 web api
    ipconfiger
    ipconfiger
    Sep 6, 2017
    19
    这个单行搞不出来, 就算你憋着搞出来了, 一是无法容错, 二是无法调试, 三是没有可读性 所以一点实用价值也没有
    AlisterTT
    AlisterTT
    Sep 6, 2017
    20
    alfred 有个 workflow 有这功能的,你可以参考一下 https://github.com/yourtion/Alfred_NumToCny
    debuggerx
    debuggerx
    Sep 6, 2017
    22
    @debuggerx 只记了记不住的正则替换部分,完整方法和测试如下:

    public class Int2Big {
    static String int2big(int src) {
    final String num[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    final String unit[] = {"圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};
    String dst = "";
    int count = 0;
    while (src > 0) {
    dst = (num[src % 10] + unit[count]) + dst;
    src = src / 10;
    count++;
    }
    return dst.replaceAll("零[仟佰拾]", "零").replaceAll("零+万", "万")
    .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
    .replaceAll("零+", "零").replaceAll("零圆", "圆");
    }

    public static void main(String[] args) {
    System.out.println(int2big(123004506)); //-->壹亿贰仟叁佰万肆仟伍佰零陆圆
    System.out.println(int2big(6523464)); //-->陆佰伍拾贰万叁仟肆佰陆拾肆圆
    System.out.println(int2big(1001000100));//-->壹拾亿零壹佰万零壹佰圆
    System.out.println(int2big(808)); //-->捌佰零捌圆
    }
    }
    haohaozaici
    haohaozaici
    Sep 6, 2017
    23
    https://gist.github.com/binjoo

    记得给电费。。。
    haohaozaici
    haohaozaici
    Sep 6, 2017
    24
    https://gist.github.com/binjoo/6028263

    记得给电费。。。 这个。。。
    BlackBerry
    BlackBerry
    Sep 6, 2017
    25
    0 零 〇
    ipconfiger
    ipconfiger
    Sep 6, 2017
    26
    Python 一行的实现方式 之一:
    "".join(list(reversed(["%s%s" % (["", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])], unit) for idx, unit in enumerate(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))) if idx<len(seq)])))

    能实现千兆以下数字的大写转换

    But 并没有什么卵用, 为了实现一行写下, 牺牲了效率, 这是其一, 可读性差, 这是其二, 且, 对于 19 => 拾玖 这种省略转换, 并不支持, 会转换成 壹拾玖 所以, 不要这么干
    mengyaoss77
    mengyaoss77
    Sep 6, 2017
    27
    @ipconfiger #26 对于发票上面写大写的话 好像 19 就需要写成 一十九吧
    wenzhoou
    wenzhoou
    Sep 6, 2017 via Android
    28
    19 转成 十九 优雅还是 一十九 优雅。119 呢?
    ipconfiger
    ipconfiger
    Sep 6, 2017
    29
    @mengyaoss77 还有别的问题, 比如中间全是 0 的时候省略的问题
    ipconfiger
    ipconfiger
    Sep 6, 2017
    30
    再改一版:
    lambda seq:"".join(list(reversed([("%s%s" % (["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])], unit)) if idx>0 or int(list(reversed(seq))[1]) else ("零%s" % ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(list(reversed(seq))[idx])]) for idx, unit in enumerate(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))) if idx<len(seq) and int(list(reversed(seq))[idx])>0])))

    支持了中间一堆 0 的情况, but, 代码完全没有可读性了, Orz
    a87150
    a87150
    Sep 6, 2017
    31
    @ipconfiger from functools import reduce 我信了你的邪
    Kisesy
    Kisesy
    Sep 6, 2017
    32
    @ShiHou 你这个有点像 youtube 上关注数的显示方式,太机械
    比如 2000105 会翻成 二百万一百五,掉了中间的零还行,后面的也掉了,读出来成了 2000150
    应该是 二百万零一百零五
    ipconfiger
    ipconfiger
    Sep 6, 2017
    33
    @a87150 并没有啊, 不信你试试, 2.7 哈
    ShiHou
    ShiHou
    Sep 6, 2017
    34
    @Kisesy 更新了下。
    KaKaGoSki
    KaKaGoSki
    Sep 6, 2017
    35
    百度不会吗
    sirm2z
    sirm2z
    Sep 6, 2017
    36
    js 自带:

    ```
    var number = 1000
    number.toLocaleString('zh-Hans-CN-u-nu-hanidec')
    ```
    Kisesy
    Kisesy
    Sep 6, 2017
    38
    @ShiHou 好多了,虽然还有不少数掉零,读起来不顺,不过念出来不至于错了,不错
    Kisesy
    Kisesy
    Sep 6, 2017
    39
    @ShiHou 还有一个.. 20001 翻成了 二万一
    ipconfiger
    ipconfiger
    Sep 6, 2017
    40
    第二种方法:

    lambda seq: "".join(reversed(["".join([prefix, ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(num)], unit]) for prefix, num, unit in [["零", tp[0], tp[1]] if idx<(len(seq)-1) and int(seq[len(seq)-idx-2])<1 else ["", tp[0], tp[1]] for idx, tp in enumerate(zip(list(reversed(seq)) , list(reversed(reduce(list.__add__, [ ["仟", "佰", "拾", big_unit] for big_unit in ["兆", "亿", "万", ""]]))))) if int(tp[0])]]))
    ipconfiger
    ipconfiger
    Sep 6, 2017❤️1
    42
    终极一行写法, 解决了大部分已知问题, 并且支持输入数字

    lambda number_string: (lambda seq: "".join(reversed(["".join(["".join([p, ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"][int(n)], u]) for p, n, u in reversed(s[0])]) + s[1] for s in [(lambda sub_seq: [[["零", tp[0], tp[1]] if i<(len(sub_seq)-1) and int(sub_seq[i+1])< 1 else ["", tp[0], tp[1]] for i, tp in enumerate(zip(sub_seq, ["", "拾", "佰", "仟"])) if int(tp[0])], unit])(seq[idx*4:(idx+1)*4] or []) for idx, unit in enumerate(["", "万", "亿", "兆", "京"])] if s[0]])))("".join(reversed(str(number_string))))
    natforum
    natforum
    Sep 6, 2017
    43
    @debuggerx 大佬,收徒吗
    zhx1991
    zhx1991
    Sep 6, 2017
    44
    一百二 120
    两百零二 202
    两百二 220
    asj
    asj
    Sep 7, 2017
    45
    @maplerecall
    我没做过,不过练习过几次数字转成英文的。反正我自己的水平是需要 1,2 个小时的。
    转汉字可能细节上有不同,我应该还是达不到十分钟完全解决的。
    calebx
    calebx
    Sep 7, 2017
    46
    https://github.com/calebx/number_to_cn
    这是我多年前搞的。

    可以看看,其实挺复杂的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2705 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 85ms · UTC 13:36 · PVG 21:36 · LAX 05:36 · JFK 08:36
    ♥ Do have faith in what you're doing.