I changed the integer into string. If the length is not multiple of 3, append "0" ahead. Then, deal three digits by chunks.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/*
Convert a non-negative integer to its English words representation.
Given input is guaranteed to be less then 2 ^ 31 - 1.
For example:
123 ---> "One Hundred Twenty Three"
12345 --> "Twelve Thousand Three Hundred Forty Five"
1234567 --> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
Seems the best way is to cut the number by 3-digits.
1234567 --> 1, 234, 567
*/
vector<string> digit_1{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Tweleve", "Thirteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
vector<string> digit_2{"Twenty", "Thrity", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety", "Hundred"};
vector<string> digit_3{"", "Thousand", "Million", "Billion"};
string threeDigits(string tmp) {
string res = "";
int n = tmp.size();
if(n == 1) return digit_1[tmp[2] - '0'];
else if(n == 2){
if(tmp[1] >= '2') return res = digit_2[tmp[1] - '0' - 2] + " " + digit_1[tmp[2] - '0'];
else {
int number = (tmp[1] - '0') * 10 + tmp[2] - '0';
return res = digit_1[number];
}
} else {
if(tmp[0] != '0') {
res = res + digit_1[tmp[0] - '0'] + " " + "Hundred";
if(tmp[1] >= '2') res = res + " " + digit_2[tmp[1] - '0' - 2] + " " + digit_1[tmp[2] - '0'];
else {
int number = (tmp[1] - '0') * 10 + tmp[2] - '0';
res += " " + digit_1[number];
}
}
else {
if(tmp[1] >= '2') res = res + digit_2[tmp[1] - '0' - 2] + " " + digit_1[tmp[2] - '0'];
else {
int number = (tmp[1] - '0') * 10 + tmp[2] - '0';
res += " " + digit_1[number];
}
}
}
return res;
}
string numberToWords(int num) {
string tmp = to_string(num);
int i = 0;
int count = 0;
if(tmp.size() % 3) count = 3 - (tmp.size() % 3);
string res = "";
for(int k = 0; k < count; ++k) {
tmp = "0" + tmp;
}
int digits = tmp.size() / 3;
count = tmp.size() / 3;
while(i + 3 <= tmp.size()) {
string a = threeDigits(tmp.substr(i, 3)) + " " + digit_3[--count];
i = i + 3;
res = res + " " + a;
}
return res;
}
int main(void) {
string res = numberToWords(1200);
cout << res << endl;
}
The above way is easy to come up but hard to be bug free.
The following code is more cleaner.
class Solution {
public:
static string numberToWords(int n) {
if(n == 0) return "Zero";
else return int_string(n).substr(1);
}
private:
static const char * const below_20[];
static const char * const below_100[];
static string int_string(int n) {
if(n >= 1000000000) return int_string(n / 1000000000) + " Billion" + int_string(n - 1000000000 * (n / 1000000000));
else if(n >= 1000000) return int_string(n / 1000000) + " Million" + int_string(n - 1000000 * (n / 1000000));
else if(n >= 1000) return int_string(n / 1000) + " Thousand" + int_string(n - 1000 * (n / 1000));
else if(n >= 100) return int_string(n / 100) + " Hundred" + int_string(n - 100 * (n / 100));
else if(n >= 20) return string(" ") + below_100[n / 10 - 2] + int_string(n - 10 * (n / 10));
else if(n >= 1) return string(" ") + below_20[n - 1];
else return "";
}
}
};
const char * const Solution::below_20[] = {"One", "Two", "Three", "Four","Five","Six","Seven","Eight","Nine","Ten", "Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
const char * const Solution::below_100[] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};