原题链接: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;