#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <sstream>
using namespace std;
/*
问题:
Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 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"
分析:
这是程序员面试金典的一道题目。
以每1000位(thousand),1000 000(million百万), 1000 000 000(billion 十亿)做区分,然后读取
0~9: Zero One Two Three Four Five Six Seven Eight Nine
10~19:Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Ninteen
20,30,...90:Twenty,Thirty,Fourty,Fifty,Sixty,Seventy,Eighty,Ninety
100:hundred
1000:thousand
1234567: 1 234 567
One Billion Two Hundred Trirty Four Thousand Five Hunded Sixty Seven
2 147 483 647
Two Billion One Hundred Fourty Seven Million Four Hundred Eighty Three Thousand Six Hundred Fourty Seven
zero似乎只有为0的时候才读取
每三位一划分,划分为组,从最低位的组到最高位的组,依次加上组的后缀:
第一组:空
第二组:Thousand
第三组:Million
第四组:Billion
然后对于每一组:生成其读数:
如果是一位数:选取0~9对应的英文
如果是两位数:如果 < 20,选取10~19对应的英文
否则,拆分出十位,个位:十位从20,30,...90中选取对应的数读取,个位如果为0:不需要继续处理
个位不为0,从个位数中选取对应的数字
如果是三位数:先拆分出百位上对应数值,从对应各位中读取该数值并添加Hundred ,拆分出的十位数同上面十位数的处理方式
输入:
2
15
30
91
100
101
123
1123
12345
212345
1234567
2147483647
1000
10000
1000000
1000000000
3055000
输出:
Two
Fifteen
Thirty
Ninety One
One Hundred
One Hundred One
One Hundred Twenty Three
One Thousand One Hundred Twenty Three
Twelve Thousand Three Hundred Forty Five
Two Hundred Twelve Thousand Three Hundred Forty Five
One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven
Two Billion One Hundred Fourty Seven Million Four Hundred Eighty Three Thousand Six Hundred Fourty Seven
One Thousand
Ten Thousand
One Million
One Billion
Three Million Fifty Five Thousand
报错:Forty写成Fourty,19拼错,Nineteen,我写成了Ninteen
Input:1000
Output:"One Thousand Zero Hundred"
Expected:"One Thousand"
划分成的每一组三位优先判断如果为0,则无需处理。但是如果本身是个位数0,则直接输出
划分后的值转化为int,个位数直接比较
关键:
1 还是逐一获取每个位置上的数,每3位划分为一组,添加后缀
2 Forty写成Fourty,19拼错,Nineteen,我写成了Ninteen
3 除了数字0本身,每一组中的0不做处理
4 还是不要转化为字符串
*/
class Solution {
public:
void init()
{
//初始化个位
string ones[10]= {"Zero", "One", "Two", "Three", "Four" ,"Five", "Six" ,"Seven", "Eight", "Nine"};
_vecOnes.clear();
_vecOnes.insert(_vecOnes.begin() , ones , ones + 10);
//初始化10~19
string ten[10] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen" ,"Eighteen", "Nineteen"};
_vecTen.clear();
_vecTen.insert(_vecTen.begin() , ten , ten + 10);
//初始化20,30,...,90,Forty才是正确的,Fourty错误
string tens[8] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
_vecTens.clear();
_vecTens.insert(_vecTens.begin() , tens, tens + 8);
//初始化后缀
string suffixStrs[4] = {"" , "Thousand" , "Million" , "Billion"};
_vecSuffixStrs.clear();
_vecSuffixStrs.insert(_vecSuffixStrs.begin() , suffixStrs , suffixStrs + 4);
}
//对当前的数字进行处理,至多包含两位
string process(string& partialNum)
{
//如果是个位数
int value = atoi(partialNum.c_str());
int size = partialNum.size();
//应该是用数值比较,比如“00”这种长度为2,但是实际表示个位数
if(value < 10)
{
return _vecOnes[value];
}
//如果是十位数,那么就需要判断,选取后两位,因为第一位可呢过为0
else if(10<= value && value <= 99)
{
if(value < 20)
{
return _vecTen[value - 10];
}
else
{
stringstream stream;
//十位
int tenValue = partialNum.at(size - 2) - '0'; //20,30,40,
stream << _vecTens[tenValue - 2];
//个位
int oneValue = partialNum.at(size - 1) - '0';
if(oneValue != 0)
{
stream << " " << _vecOnes[oneValue];
}
return stream.str();
}
}
return "";
}
string numberToWords(int num) {
if(0 == num)
{
return "Zero";
}
string sNum = to_string(num);
if(sNum.empty())
{
return "";
}
init();
//先把整数划分成组,每三位一组,从低到高处理
int len = sNum.length();
vector<string> result;
int groupNum = 0;
string partialNum;
int hundredValue;
string tempResult;
for(int i = len - 1 ; i >= 0 ; i -= 3 )
{
stringstream stream;
//将三位数进行处理,截取出这个三位数
if(i - 2 >= 0)
{
partialNum = sNum.substr(i-2 , 3);
}
else if(i - 1 >= 0)
{
partialNum = sNum.substr(i-1 , 2);
}
else
{
partialNum = sNum.substr(i , 1);
}
//如果是个位数
int value = atoi(partialNum.c_str());
//如果当前为0,则无需处理,参见1000,直接为One Thousand
if(0 == value)
{
groupNum++;
continue;
}
//如果是<100,两位数
if(value < 100)
{
tempResult = process(partialNum);
}
//三位数,获取百位
else
{
hundredValue = partialNum.at(0) - '0';
partialNum = partialNum.substr(1 , 2);
stream << _vecOnes.at(hundredValue) << " Hundred";
//如果后面两位为"00",无需处理
if(0 != atoi(partialNum.c_str()))
{
tempResult = process(partialNum);
if(!tempResult.empty())
{
stream << " " << tempResult;
}
}
tempResult = stream.str();
}
if(groupNum != 0)
{
result.push_back(tempResult + " " + _vecSuffixStrs.at(groupNum++));
}
else
{
result.push_back(tempResult + _vecSuffixStrs.at(groupNum++));
}
}
//result中存储的结果需要逆序输出,并添加" "
if(result.empty())
{
return "";
}
int size = result.size();
stringstream resultStream;
for(int i = size - 1; i >= 0 ; i--)
{
if(i != size - 1)
{
resultStream << " " << result.at(i) ;
}
else
{
resultStream << result.at(i);
}
}
return resultStream.str();
}
private:
vector<string> _vecOnes;
vector<string> _vecTen;
vector<string> _vecTens;
vector<string> _vecSuffixStrs;
};
void print(vector<int>& result)
{
if(result.empty())
{
cout << "no result" << endl;
return;
}
int size = result.size();
for(int i = 0 ; i < size ; i++)
{
cout << result.at(i) << " " ;
}
cout << endl;
}
void process()
{
int num;
Solution solution;
while(cin >> num )
{
string answer = solution.numberToWords(num);
cout << answer << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:273. Integer to English Words
最新推荐文章于 2019-03-05 08:22:21 发布