Problem 17:Number letter counts

原题链接:http://projecteuler.net/problem=17


If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?


NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.


题目大意是:

如果用英文写出数字1到5: one, two, three, four, five, 那么一共需要3 + 3 + 5 + 4 + 4 = 19个字母。

如果数字1到1000(包含1000)用英文写出,那么一共需要多少个字母?

注意:  空格和连字符不算在内。例如,342 (three hundred and forty-two)包含23个字母; 115 (one hundred and fifteen)包含20个字母。"and" 的使用与英国标准一致。


解法1:

1.先初始化1~20,30,40,50,60,70,80,90,100,1000这些数字对应的英文的长度的字典

2.对于1~20的英文字符的长度,直接从第1步的字典里取得其长度

3.对于21~99,则分解成两部分,一部分是个位数,可从第1步的字典取得其长度,另一部分是这个数减去个位数的值,亦从第1步的字典里取得其长度

4.对于100~999的number,也要分解成两部分,一部分是a,其中a=100n,0<n<10,另一部分是b,其中b=number-a. 对于a转换成英文的话,长度等于百位数对应的英文长度和"hundred"的长度之和,对于b转换成英文的话,则用第3步的方法,则number对应的英文长度为a,b及"and"这三者的长度之和

5.对于1000,直接从第1步的字典里取得其长度

6.求和

php代码如下:

<?php


$dict = array(
    1 => 3, //one
    2 => 3, //two
    3 => 5, //three
    4 => 4, //four
    5 => 4, //five
    6 => 3, //six
    7 => 5, //seven
    8 => 5, //eight
    9 => 4, //nine
    10 => 3, //ten
    11 => 6, //eleven
    12 => 6, //twelve
    13 => 8, //thirteen
    14 => 8, //fourteen
    15 => 7, //fifteen
    16 => 7, //sixteen
    17 => 9, //seventeen
    18 => 8, //eighteen
    19 => 8, //nineteen
    20 => 6, //twenty
    30 => 6, //thirty
    40 => 5, //forty
    50 => 5, //fifty
    60 => 5, //sixty
    70 => 7, //seventy
    80 => 6, //eighty
    90 => 6, //ninety
    100 => 7, //hundred
    1000 => 8, //thousand
);


function get_letter_num_of_number_which_under_100($number, $dict) {
    $letter_num = 0;
    if ($number <= 20) {
        $letter_num = $dict[$number];
    } elseif ($number < 100) {
        $mod = $number % 10;
        if ($mod == 0) {
            $letter_num = $dict[$number - $mod];
        } else {
            $letter_num = $dict[$number - $mod] + $dict[$mod];
        }
    }
    return $letter_num;
}


function get_letter_num_of_number_which_between_100_and_999($number, $dict) {
    $letter_num = 0;
    $h = intval($number / 100);
    $remain = $number - ($h * 100);
    $letter_num+=$dict[$h] + $dict[100];
    if ($remain > 0) {
        $letter_num+=3; //and
        $letter_num+=get_letter_num_of_number_which_under_100($remain, $dict);
    }
    return $letter_num;
}


$up = 1000;
$letter_num = 0;
for ($i = 1; $i <= $up; $i++) {
    if ($i < 100) {
        $letter_num+=get_letter_num_of_number_which_under_100($i, $dict);
    } elseif ($i < 1000) {
        $letter_num+=get_letter_num_of_number_which_between_100_and_999($i, $dict);
    } else {
        $letter_num+=$dict[1] + $dict[1000];
    }
}
echo $letter_num;



注:题目的中文翻译源自http://pe.spiritzhang.com

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值