Number letter counts
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.
note:不包括空格和短横线 , 例如: 342:(three hundred and forty-two) 一共23个字符, 115(one hundred and fifteen)包含20个字符。使用“and”是依照英式英语的语法(在千或百 到 十或个位之间要添加“and”,但是此时十位和个位不能同时为0,比如:100 为 one hundred, 没有and。 101为 one hundred and one.
代码:
package projectEuler;
public class Problem17 {
private static int[] numbers = new int[100];
public static void main(String[] args) {
int sum = 0;
init_numbers();
for(int i=1; i<=1000; i++){
sum += analysis_num(i);
}
System.out.println("sum:"+sum);
// System.out.println(""+analysis_num(342));
}
private static int analysis_num(int num) {
int[] wei = new int[4];
wei[0] = num/1000; //千位
wei[1] = (num-wei[0]*1000)/100; //百位
wei[2] = (num-wei[0]*1000 - wei[1]*100) / 10; //十位
wei[3] = num%10; //个位
int[] wordsNumber = new int[4];
wordsNumber[0] = wei[0]>0? (numbers[wei[0]]+8) : 0; // 千位字母数 = 数字 + thousand
wordsNumber[1] = wei[1]>0? (numbers[wei[1]]+7) : 0; // 百位字母数 = 数字 + hundred
if( wei[2] >= 2 ){
wordsNumber[2] = numbers[wei[2]*10];
wordsNumber[3] = numbers[wei[3]];
}
else{
wordsNumber[2] = 0;
wordsNumber[3] = numbers[wei[2]*10+wei[3]];
}
int sum = 0;
for(int i=0; i<wordsNumber.length; i++){
sum += wordsNumber[i];
}
if( (wei[1]>0 || wei[1]>0) && (wei[2]>0 || wei[3]>0)){ // 如果有千位百位,十位和个位
sum += 3;
}
return sum;
}
private static void init_numbers() {
numbers[0] = 0;// no pronunciation for zero
numbers[1] = 3;// "one"
numbers[2] = 3;// "two"
numbers[3] = 5;// "three"
numbers[4] = 4;// "four"
numbers[5] = 4;// "five"
numbers[6] = 3;// "six"
numbers[7] = 5;// "seven"
numbers[8] = 5;// "eight"
numbers[9] = 4;// "nine"
numbers[10] = 3;// "ten"
numbers[11] = 6;// "eleven"
numbers[12] = 6;// "twelve"
numbers[13] = 8;// "thirteen"
numbers[14] = 8;// "fourteen"
numbers[15] = 7;// "fifteen"
numbers[16] = 7;// "sixteen"
numbers[17] = 9;// "seventeen"
numbers[18] = 8;// "eighteen"
numbers[19] = 8;// "nineteen"
numbers[20] = 6;// "twenty"
numbers[30] = 6;// "thirty"
numbers[40] = 5;// "forty"
numbers[50] = 5;// "fifty"
numbers[60] = 5;// "sixty"
numbers[70] = 7;// "seventy"
numbers[80] = 6;// "eighty"
numbers[90] = 6;// "ninety"
}
}
这道题其实不是很难,主要是逻辑有点复杂。然后看init_numbers() 这个函数,这个是我看到别人这样用才用的,就是用数组的下边来表示这个数是几,这个比较巧妙。
比如 111,算法中可以看到我会先分离出千位,百位,十位,个位。
千位的字母个数: 数字 + thousand -> numbers[ 千位数字 ] + 8
十位和个位需要判断: 如果大于20, 则需要单独分离出十位,再与个位字母数相加。如果小于20, 直接得到 numbers[数字].
好了就讲到这里,代码里有注释,参照看一下就可以了。