此题是一个数字字符转化类问题。没有什么复杂的技巧,只要想清楚2个转化的规律:
1,此题给出的非负数字上限是2^31-1,大约是十亿的数量级(2^10 = 1024, (2^10)^3 ~1billion)。而我们已知每1000进位方式有三种后缀,thousand, million和billion,这就可以看作三重循环,刚好cover这个范围。
2.每重循环内部的命名规则是一致的,都是百位,十位和个位。唯一要注意的是在输出十位时,在20以内的命名都有专有名称,20以上都是*ten+个位。这几个情况并不复杂也不难实现(可分为 100位,大于20,小于20大于10,小于10大于0这四种情况)。
Corner Case: 1) num =0时; 2)如果是倒序生成,需注意最后次序;3) 1,000,000情况,千位无需表达; 4)空格处理,在每个字符后先加空格
1 vectora ={ "","Thousand ", "Million ", "Billion "}; 2 vector b ={ "Ten ", "Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "}; 3 vector c ={ "Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "}; 4 vector d ={ "One ", "Two ", "Three ", "Four ", "Five ", "Six ", "Seven ", "Eight ", "Nine "}; 5 string numberToWords(int num) { 6 string res; 7 if(num == 0) return "Zero"; 8 for(int i=0; i<4; i++){ 9 if(num == 0) break;10 int advance = num / 1000;11 int left = num % 1000;12 if(left > 0){13 res = convert(left) + a[i] + res; 14 }15 num = advance;16 }17 res.pop_back();18 return res;19 }20 string convert(int num){21 string res;22 if(num >= 100){23 res += d[num/100-1] + "Hundred ";24 num = num % 100;25 }26 if(num >= 20){27 res += b[num/10-1];28 if(num % 10 > 0) res += d[num % 10 - 1];29 }else if(num >= 10){30 res += c[num - 10];31 }else if(num > 0){32 res += d[num-1];33 }34 return res;35 }