为了账号安全,请及时绑定邮箱和手机立即绑定

代码高尔夫:数字到单词

/ 猿问

代码高尔夫:数字到单词

慕运维1137616 2019-09-20 15:04:38

代码高尔夫系列似乎相当受欢迎。我遇到了一些将数字转换为单词表示的代码。一些例子是(编程乐趣的2的权力):

  • 2 - >两个

  • 1024 - >一千二十四

  • 1048576 - >百万四万八千七百六十六

我的同事出现的算法差不多有两百行。似乎会有更简洁的方法来做到这一点。

现行指南:

  • 以任何编程语言欢迎提交的内容(我向PhiLho道歉,因为最初对此不太清楚)

  • 最大输入为2 ^ 64(请参阅以下链接,感谢mmeyers)

  • 英语输出的缩放比例较低,但欢迎使用任何算法。只需对编程语言一起评论所使用的方法。


查看完整描述

3 回答

?
手掌心

Lisp,仅使用标准函数:


(format nil "~r" 1234) ==> "one thousand two hundred thirty-four"

奖金:


(format nil "~@r" 1234)  ==> "MCCXXXIV"


查看完整回答
反对 回复 2019-09-20
?
弑天下

好吧,我认为是时候在Windows BATCH脚本中自己实现了(应该适用于Windows 2000或更高版本)。


这是代码:


@echo off


set zero_to_nineteen=Zero One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen

set twenty_to_ninety=ignore ignore Twenty Thirty Forty Fifty Sixty Seventy Eighty Ninety

set big_numbers=ignore Thousand Million Billion Trillion Quadrillion Quintillion Sextillion Septillion Octillion Nonillion Decillion Undecillion Duodecillion Tredecillion Quattuordecillion Quindecillion Sexdecillion Septendecillion Octodecillion Novemdecillion Vigintillion

rem             10^0   10^3     10^6    10^9    10^12    10^15       10^18       10^21      10^24      10^27     10^30     10^33     10^36       10^39        10^42        10^45             10^48         10^51        10^54           10^57         10^60          10^63


call :parse_numbers %*


exit /B 0


:parse_numbers

    :parse_numbers_loop

        if "$%~1" == "$" goto parse_numbers_end

        call :parse_number %~1

        echo %~1 -^> %parse_number_result%

        shift

        goto parse_numbers_loop

    :parse_numbers_end

    exit /B 0


:parse_number

    call :get_sign %~1

    set number_sign=%get_sign_result%

    call :remove_groups %get_sign_result_number%

    call :trim_leading_zeros %remove_groups_result%

    set number=%trim_leading_zeros_result%

    if "$%number%" == "$0" (

        set parse_number_result=Zero

        exit /B 0

    )

    set counter=0

    set parse_number_result=

    :parse_number_loop

        set last_three=%number:~-3%

        set number=%number:~0,-3%

        call :parse_three %last_three%

        call :get_from %counter% %big_numbers%

        if "$%get_from_result%" == "$" (

            set parse_number_result=* ERR: the number is too big! Even wikipedia doesn't know how it's called!

            exit /B 0

        )

        if not "$%parse_three_result%" == "$Zero" (

            if %counter% == 0 (

                set parse_number_result=%parse_three_result%

            ) else (

                if not "$%parse_number_result%" == "$" (

                    set parse_number_result=%parse_three_result% %get_from_result% %parse_number_result%

                ) else (

                    set parse_number_result=%parse_three_result% %get_from_result%

                )

            )

        )

        set /A counter+=1

        if not "$%number%" == "$" goto parse_number_loop

    if "$%parse_number_result%" == "$" (

        set parse_number_result=Zero

        exit /B 0

    ) else if not "$%number_sign%" == "$" (

        set parse_number_result=%number_sign% %parse_number_result%

    )

    exit /B 0


:parse_three

    call :trim_leading_zeros %~1

    set three=%trim_leading_zeros_result%

    set /A three=%three% %% 1000

    set /A two=%three% %% 100

    call :parse_two %two%

    set parse_three_result=

    set /A digit=%three% / 100

    if not "$%digit%" == "$0" (

        call :get_from %digit% %zero_to_nineteen%

    )

    if not "$%digit%" == "$0" (

        if not "$%get_from_result%" == "$Zero" (

            set parse_three_result=%get_from_result% Hundred

        )

    )

    if "$%parse_two_result%" == "$Zero" (

        if "$%parse_three_result%" == "$" (

            set parse_three_result=Zero

        )

    ) else (

        if "$%parse_three_result%" == "$" (

            set parse_three_result=%parse_two_result%

        ) else (

            set parse_three_result=%parse_three_result% %parse_two_result%

        )

    )

    exit /B 0


:parse_two

    call :trim_leading_zeros %~1

    set two=%trim_leading_zeros_result%

    set /A two=%two% %% 100

    call :get_from %two% %zero_to_nineteen%

    if not "$%get_from_result%" == "$" (

        set parse_two_result=%get_from_result%

        goto parse_two_20_end

    )

    set /A digit=%two% %% 10

    call :get_from %digit% %zero_to_nineteen%

    set parse_two_result=%get_from_result%

    set /A digit=%two% / 10

    call :get_from %digit% %twenty_to_ninety%

    if not "$%parse_two_result%" == "$Zero" (

        set parse_two_result=%get_from_result% %parse_two_result%

    ) else (

        set parse_two_result=%get_from_result%

    )

    goto parse_two_20_end

    :parse_two_20_end

    exit /B 0


:get_from

    call :trim_leading_zeros %~1

    set idx=%trim_leading_zeros_result%

    set /A idx=0+%~1

    shift

    :get_from_loop

        if "$%idx%" == "$0" goto get_from_loop_end

        set /A idx-=1

        shift

        goto get_from_loop

    :get_from_loop_end

    set get_from_result=%~1

    exit /B 0


:trim_leading_zeros

    set str=%~1

    set trim_leading_zeros_result=

    :trim_leading_zeros_loop

        if not "$%str:~0,1%" == "$0" (

            set trim_leading_zeros_result=%trim_leading_zeros_result%%str%

            exit /B 0

        )

        set str=%str:~1%

        if not "$%str%" == "$" goto trim_leading_zeros_loop

    if "$%trim_leading_zeros_result%" == "$" set trim_leading_zeros_result=0

    exit /B 0


:get_sign

    set str=%~1

    set sign=%str:~0,1%

    set get_sign_result=

    if "$%sign%" == "$-" (

        set get_sign_result=Minus

        set get_sign_result_number=%str:~1%

    ) else if "$%sign%" == "$+" (

        set get_sign_result_number=%str:~1%

    ) else (

        set get_sign_result_number=%str%

    )

    exit /B 0


:remove_groups

    set str=%~1

    set remove_groups_result=%str:'=%

    exit /B 0

这是我使用的测试脚本:


@echo off

rem 10^x:x= 66  63  60  57  54  51  48  45  42  39  36  33  30  27  24  21  18  15  12   9   6   3   0

call number                                                                                          0

call number                                                                                          2

call number                                                                                        -17

call number                                                                                         30

call number                                                                                         48

call number                                                                                       -256

call number                                                                                        500

call number                                                                                        874

call number                                                                                      1'024

call number                                                                                    -17'001

call number                                                                                    999'999

call number                                                                                  1'048'576

call number                                                                         -1'000'001'000'000

call number                                                                    912'345'014'587'957'003

call number                                                       -999'912'345'014'587'124'337'999'999

call number                                        111'222'333'444'555'666'777'888'999'000'000'000'001

call number                               -912'345'014'587'912'345'014'587'124'912'345'014'587'124'337

call number    999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999

call number  1'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000

rem 10^x:x= 66  63  60  57  54  51  48  45  42  39  36  33  30  27  24  21  18  15  12   9   6   3   0

这是我从测试脚本中得到的输出:


0 -> Zero

2 -> Two

-17 -> Minus Seventeen

30 -> Thirty

48 -> Forty Eight

-256 -> Minus Two Hundred Fifty Six

500 -> Five Hundred

874 -> Eight Hundred Seventy Four

1'024 -> One Thousand Twenty Four

-17'001 -> Minus Seventeen Thousand One

999'999 -> Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine

1'048'576 -> One Million Forty Eight Thousand Five Hundred Seventy Six

-1'000'001'000'000 -> Minus One Trillion One Million

912'345'014'587'957'003 -> Nine Hundred Twelve Quadrillion Three Hundred Forty Five Trillion Fourteen Billion Five Hundred Eighty Seven Million Nine Hundred Fifty Seven Thousand Three

-999'912'345'014'587'124'337'999'999 -> Minus Nine Hundred Ninety Nine Septillion Nine Hundred Twelve Sextillion Three Hundred Forty Five Quintillion Fourteen Quadrillion Five Hundred Eighty Seven Trillion One Hundred Twenty Four Billion Three Hundred Thirty Seven Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine

111'222'333'444'555'666'777'888'999'000'000'000'001 -> One Hundred Eleven Undecillion Two Hundred Twenty Two Decillion Three Hundred Thirty Three Nonillion Four Hundred Forty Four Octillion Five Hundred Fifty Five Septillion Six Hundred Sixty Six Sextillion Seven Hundred Seventy Seven Quintillion Eight Hundred Eighty Eight Quadrillion Nine Hundred Ninety Nine Trillion One

-912'345'014'587'912'345'014'587'124'912'345'014'587'124'337 -> Minus Nine Hundred Twelve Tredecillion Three Hundred Forty Five Duodecillion Fourteen Undecillion Five Hundred Eighty Seven Decillion Nine Hundred Twelve Nonillion Three Hundred Forty Five Octillion Fourteen Septillion Five Hundred Eighty Seven Sextillion One Hundred Twenty Four Quintillion Nine Hundred Twelve Quadrillion Three Hundred Forty Five Trillion Fourteen Billion Five Hundred Eighty Seven Million One Hundred Twenty Four Thousand Three Hundred Thirty Seven

999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999'999 -> Nine Hundred Ninety Nine Vigintillion Nine Hundred Ninety Nine Novemdecillion Nine Hundred Ninety Nine Octodecillion Nine Hundred Ninety Nine Septendecillion Nine Hundred Ninety Nine Sexdecillion Nine Hundred Ninety Nine Quindecillion Nine Hundred Ninety Nine Quattuordecillion Nine Hundred Ninety Nine Tredecillion Nine Hundred Ninety Nine Duodecillion Nine Hundred Ninety Nine Undecillion Nine Hundred Ninety Nine Decillion Nine Hundred Ninety Nine Nonillion Nine Hundred Ninety Nine Octillion Nine Hundred Ninety Nine Septillion Nine Hundred Ninety Nine Sextillion Nine Hundred Ninety Nine Quintillion Nine Hundred Ninety Nine Quadrillion Nine Hundred Ninety Nine Trillion Nine Hundred Ninety Nine Billion Nine Hundred Ninety Nine Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine

1'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000'000 -> * ERR: the number is too big! Even wikipedia doesn't know how it's called!

如果我能找到更多的大数字名称,脚本将支持更大的数字。但是,目前,该脚本将使用从 - (10 ^ 66-1)到(10 ^ 66-1)的所有数字。


我必须提一下,我在BATCH中解决这个问题很有意思。:)


查看完整回答
反对 回复 2019-09-20
?
慕的地2183247

C# - 30行包括 方法声明和{} s:


考虑所有前面提到的逗号,连字符和连字符。我只包括octillion因为decimal.MaxValue只在octillions中。对于更大的整数,您需要将相应的项添加到thou []数组中,并且可能将数字作为字符串传递,修改该行以使用最后3个字符提取块,而不是像我在这里使用模数。


    static string wordify(decimal v)

    {

        if (v == 0) return "zero";

        var units = " one two three four five six seven eight nine".Split();

        var teens = " eleven twelve thir# four# fif# six# seven# eigh# nine#".Replace("#", "teen").Split();

        var tens = " ten twenty thirty forty fifty sixty seventy eighty ninety".Split();

        var thou = " thousand m# b# tr# quadr# quint# sext# sept# oct#".Replace("#", "illion").Split();

        var g = (v < 0) ? "minus " : "";

        var w = "";

        var p = 0;

        v = Math.Abs(v);

        while (v > 0)

        {

            int b = (int)(v % 1000);

            if (b > 0)

            {

                var h = (b / 100);

                var t = (b - h * 100) / 10;

                var u = (b - h * 100 - t * 10);

                var s = ((h > 0) ? units[h] + " hundred" + ((t > 0 | u > 0) ? " and " : "") : "")

                      + ((t > 0) ? (t == 1 && u > 0) ? teens[u] : tens[t] + ((u > 0) ? "-" : "") : "")

                      + ((t != 1) ? units[u] : "");

                s = (((v > 1000) && (h == 0) && (p == 0)) ? " and " : (v > 1000) ? ", " : "") + s;

                w = s + " " + thou[p] + w;

            }

            v = v / 1000;

            p++;

        }

        return g + w;

    }

叫做使用:


static void Main(string[] args)

{

  Console.WriteLine(wordify(decimal.MaxValue));

}

输出:


七十九个八十八岁,一百二十二个二十八岁,一百六十二个五十四岁,二百六十四万亿,三亿三千七百万,一百五十九十三亿,五亿四千三百万,九十五万,三百三十五


查看完整回答
反对 回复 2019-09-20

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信