1、解题思路:
求解这道题,需要把输入的数字,三位三位拆开来进行一个处理。那么就会发现,求解超过三位数的thousand时,thousand的左起三位“个十百”,与“个十百”的处理方式相似;同理,超过六位数的million左起的六位数和million的六位数处理方式相似,超过九位数的billion左起九位数和billion的九位数处理方式相似。
故而,下面的代码看着很长,但string san_san(string str)、string six_san(string str)、string six_san2(string str)、string nine_san(string str)、string twelve_san(string str)这几个函数的代码几乎一样,只不过在特定位置做了下修改。
之所以这样复杂,就是没有用到递归的思想,如果用上递归的思想,则代码量会减少五分之四。
2、代码如下:
#include <iostream>
#include <string>
using namespace std;
string tens[] = { "", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
string ones[] = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
string ones2[] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen" };
string san_san(string str)
{
if (str.size() == 1)
{
int i = 0;
int num = (str[i]-'0') % 10;
return ones[num];
}
else if (str.size() == 2)
{
int i = 0;
string ten;
int num = (str[i] - '0') % 10;
ten = tens[num];
if (ten == "ten")
{
int i = 0;
int num = (str[i + 1] - '0') % 10;
return ones2[num];
}
else
{
int i = 0;
string strapp;
int num = (str[i + 1] - '0') % 10;
if (str[i] == '0')
{
strapp = ones[num];
return strapp;
}
else
{
strapp = ten + " " + ones[num];
return strapp;
}
}
}
else //str.size()=3
{
int i = 0;
string bai;
int num = (str[i] - '0') % 10;
bai = ones[num] + " " + "hundred";
//重复之前两位数时
string ten; //十位数
int num2 = (str[i+1] - '0') % 10;
ten = tens[num2];
if (ten == "ten") //十位数为1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i] != '0')
{
strapp = bai + " and " + ones2[num];
return strapp;
}
else
{
strapp = ones2[num];
return strapp;
}
}
else //十位数不是1
{
int i = 0;
string strapp;
if (str[i] != '0') //百位不是0
{
if (str[i + 1] != '0') //十位不是0
{
int num = (str[i+2] - '0') % 10;
if (str[i + 2] != '0')
{
strapp = bai + " and " + ten + " " + ones[num];
return strapp;
}
else
{
strapp = bai + " and " + ten;
return strapp;
}
}
else //十位等于0
{
int num = (str[i + 2] - '0') % 10;
if (str[i + 2] != '0')
{
strapp = bai + " and " + ones[num];
return strapp;
}
else
{
strapp = bai;
return strapp;
}
}
}
else //百位为0
{
if (str[i + 1] != '0') //十位不是0
{
int num = (str[i + 2] - '0') % 10;
if (str[i + 2] != '0')
{
strapp = ten + " " + ones[num];
return strapp;
}
else
{
strapp = ten;
return strapp;
}
}
else //十位等于0
{
int num = (str[i + 2] - '0') % 10;
if (str[i + 2] != '0')
{
strapp = ones[num];
return strapp;
}
else
{
strapp = bai;
return strapp;
}
}
}
}
}
}
string six_san(string str)
{
if (str.size() == 4)
{
int i = 0;
int num = (str[i] - '0') % 10;
return ones[num] + " thousand";
}
else if (str.size() == 5)
{
int i = 0;
string ten;
int num = (str[i] - '0') % 10;
ten = tens[num];
if (ten == "ten")
{
int i = 0;
int num = (str[i + 1] - '0') % 10;
return ones2[num] + " thousand";
}
else //十位不是1
{
int i = 0;
string strapp;
int num = (str[i + 1] - '0') % 10;
if (str[i + 1] != '0')
{
if (str[i] == '0')
{
strapp = ones[num] + " thousand";
return strapp;
}
else
{
strapp = ten + " " + ones[num] + " thousand";
return strapp;
}
}
else
{
if (str[i] == '0')
{
return strapp;
}
else
{
strapp = ten + " thousand";
return strapp;
}
}
}
}
else //str,size()=6
{
int i = 0;
string bai;
int num = (str[i] - '0') % 10;
bai = ones[num] + " " + "hundred";
//重复之前两位数时
string ten; //十位数
int num2 = (str[i + 1] - '0') % 10;
ten = tens[num2];
if (ten == "ten") //十位数为1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i] != '0')
{
strapp = bai + " and " + ones2[num] + " thousand";
return strapp;
}
else
{
strapp = ones2[num] + " thousand";
return strapp;
}
}
else //十位数不是1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i + 1] != '0')
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ten + " " + ones[num] + " thousand";
return strapp;
}
else
{
strapp = bai + /*" and " +*/ " thousand";
return strapp;
}
}
else // 等于0的情况
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ones[num] + " thousand";
return strapp;
}
else
{
strapp = bai + " thousand";
return strapp;
}
}
}
}
}
string six_san2(string str)
{
if (str.size() == 1)
{
int i = 0;
int num = (str[i] - '0') % 10;
return ones[num] + " thousand";
}
else if (str.size() == 2)
{
int i = 0;
string ten;
int num = (str[i] - '0') % 10;
ten = tens[num];
if (ten == "ten")
{
int i = 0;
int num = (str[i + 1] - '0') % 10;
return ones2[num] + " thousand";
}
else //十位不是1
{
int i = 0;
string strapp;
int num = (str[i + 1] - '0') % 10;
if (str[i] == '0')
{
strapp = ones[num] + " thousand";
return strapp;
}
else
{
strapp = ten + " " + ones[num] + " thousand";
return strapp;
}
}
}
else //str,size()=6
{
int i = 0;
string bai;
int num = (str[i] - '0') % 10;
bai = ones[num] + " " + "hundred";
//重复之前两位数时
string ten; //十位数
int num2 = (str[i + 1] - '0') % 10;
ten = tens[num2];
if (ten == "ten") //十位数为1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i] != '0')
{
strapp = bai + " and " + ones2[num] + " thousand";
return strapp;
}
else
{
strapp = ones2[num] + " thousand";
return strapp;
}
}
else //十位数不是1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i + 1] != '0')
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ten + " " + ones[num] + " thousand";
return strapp;
}
else
{
strapp = bai + /*" and " +*/ " thousand";
return strapp;
}
}
else // 等于0的情况
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ones[num] + " thousand";
return strapp;
}
else
{
strapp = bai + " thousand";
return strapp;
}
}
}
}
}
string nine_san(string str)
{
if (str.size() == 7)
{
int i = 0;
int num = (str[i] - '0') % 10;
return ones[num] + " million";
}
else if (str.size() == 8)
{
int i = 0;
string ten;
int num = (str[i] - '0') % 10;
ten = tens[num];
if (ten == "ten")
{
int i = 0;
int num = (str[i + 1] - '0') % 10;
return ones2[num] + " million";
}
else //十位不是1
{
int i = 0;
string strapp;
int num = (str[i + 1] - '0') % 10;
if (str[i] == '0')
{
strapp = ones[num] + " million";
return strapp;
}
else
{
strapp = ten + " " + ones[num] + " million";
return strapp;
}
}
}
else //str,size()=9
{
int i = 0;
string bai;
int num = (str[i] - '0') % 10;
bai = ones[num] + " " + "hundred";
//重复之前两位数时
string ten; //十位数
int num2 = (str[i + 1] - '0') % 10;
ten = tens[num2];
if (ten == "ten") //十位数为1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i] != '0')
{
strapp = bai + " and " + ones2[num] + " million";
return strapp;
}
else
{
strapp = ones2[num] + " million";
return strapp;
}
}
else //十位数不是1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i + 1] != '0')
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ten + " " + ones[num] + " million";
return strapp;
}
else
{
strapp = bai + /*" and " +*/ " million";
return strapp;
}
}
else // 等于0的情况
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ones[num] + " million";
return strapp;
}
else
{
strapp = bai + " million";
return strapp;
}
}
}
}
}
string twelve_san(string str)
{
if (str.size() == 10)
{
int i = 0;
int num = (str[i] - '0') % 10;
return ones[num] + " billion";
}
else if (str.size() == 11)
{
int i = 0;
string ten;
int num = (str[i] - '0') % 10;
ten = tens[num];
if (ten == "ten")
{
int i = 0;
int num = (str[i + 1] - '0') % 10;
return ones2[num] + " billion";
}
else //十位不是1
{
int i = 0;
string strapp;
int num = (str[i + 1] - '0') % 10;
if (str[i] == '0')
{
strapp = ones[num] + " billion";
return strapp;
}
else
{
strapp = ten + " " + ones[num] + " billion";
return strapp;
}
}
}
else //str,size()=12
{
int i = 0;
string bai;
int num = (str[i] - '0') % 10;
bai = ones[num] + " " + "hundred";
//重复之前两位数时
string ten; //十位数
int num2 = (str[i + 1] - '0') % 10;
ten = tens[num2];
if (ten == "ten") //十位数为1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i] != '0')
{
strapp = bai + " and " + ones2[num] + " billion";
return strapp;
}
else
{
strapp = ones2[num] + " billion";
return strapp;
}
}
else //十位数不是1
{
int i = 0;
string strapp;
int num = (str[i + 2] - '0') % 10;
if (str[i + 1] != '0')
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ten + " " + ones[num] + " billion";
return strapp;
}
else
{
strapp = bai + /*" and " +*/ " billion";
return strapp;
}
}
else // 等于0的情况
{
if (str[i + 2] != '0')
{
strapp = bai + " and " + ones[num] + " billion";
return strapp;
}
else
{
strapp = bai + " billion";
return strapp;
}
}
}
}
}
int main()
{
long number;
while (cin >> number)
{
string str = to_string(number);
if (str.size() <= 3)
{
string str1 = san_san(str);
cout << str1 << endl;
}
else if (str.size() >= 4 && str.size() <= 6)
{
string str2 = six_san(str);
string str3 = str.substr(str.size() - 3, str.size() - 1); //只取用“个位、十位、百位”
string str4 = san_san(str3);
string str5 = str2 + " " + str4;
cout << str5 << endl;
}
else if (str.size() >= 7 && str.size() <= 9)
{
string str6 = nine_san(str); //million
string str9 = str.substr(str.size() - 6, str.size() - 4);
string str10 = six_san2(str9); //thousand
string str7 = str.substr(str.size() - 3, str.size() - 1);
string str8 = san_san(str7); //个十百
string str11 = str6 + " " + str10 + " " + str8;
cout << str11 << endl;
}
else if (str.size() >= 10 && str.size() <= 12)
{
string str11 = twelve_san(str); //billion
string str12 = str.substr(str.size() - 9, str.size() - 7);
string str6 = nine_san(str12); //million
string str9 = str.substr(str.size() - 6, str.size() - 4);
string str10 = six_san(str9); //thousand
string str7 = str.substr(str.size() - 3, str.size() - 1);
string str8 = san_san(str7); //个十百
string str13 = str11 + " " + str6 + " " + str10 + " " + str8;
cout << str13 << endl;
}
}
return 0;
}
3、运行结果
如下图所示:
4、运行分析
这道题,其实代码中,只写到了12位数,而且,对于类似于“8088”输出的结果,在超过三位以后,没有进行修改,但是依然AC通过,猜测这道题的测试点取的比较少,而且测试点不全面。
接下来,要做的,就是对代码做一个优化缩减,再重新运行。
5、代码优化
此处的代码,是其他同学AC通过的代码,这段代码比较简洁,逻辑上比较好理解,方法很巧妙。代码存在一个小小的问题,在判决条件上,已在代码中修改。
#include <iostream>
#include <sstream>
using namespace std;
string tens[] = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
string ones[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
"nineteen" };
string others[] = { "", "thousand", "million", "billion" };
int scopes[] = { 1, 1000, 1000000, 1000000000 };
string convert(int num) {
int lower;
int hundred;
stringstream ss;
// 处理小于1000的情况
if (num <= 19) return ones[num];
if (num >= 20 && num <= 99) return tens[num / 10] + ((num % 10 > 0) ? " " + ones[num % 10] : "");
if (num >= 100 && num <= 999) {
ss << ones[num / 100] << " hundred";
if (num % 100 > 0) {
ss << " and " << convert(num % 100);
}
return ss.str();
}
// 处理大于1000的情况
for (int i = 3; i >= 0; i--) {
// if (num > scopes[i]) {
if (num >= scopes[i]) { //此处做了修改,判决条件应该包含等于号
ss << convert(num / scopes[i]) << " " << others[i];
num %= scopes[i];
// 后续仍然有数字
if (num > 0) {
ss << ' ';
}
}
}
return ss.str();
}
int main() {
int num;
while (cin >> num)
{
getchar();
cout << convert(num) << endl;
}
return 0;
}
运行结果如下图所示: