题目的主要信息:
- 1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。
- 2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。
- 3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如6007.14,应写成“人民币陆仟零柒元壹角肆分“。
- 4、10应写作“拾”,100应写作“壹佰”。例如,1010.00应写作“人民币壹仟零拾元整”,110.00应写作“人民币壹佰拾元整”
- 5、十万以上的数字接千不用加“零”,例如,30105000.00应写作“人民币叁仟零拾万伍仟元整”
方法一:
用calPart1函数将整数部分转为中文,用calPart2函数将角分转为中文。calPart1的原理是,遍历一遍整数部分字符串,i表示当前字符在整数中的位数。如果当前字符不为'0',且当前位置不是10位,则转为中文;如果当前位置不是个位,则需要添加亿、万、仟等单位。当前位位数大于8位为亿位,大于4位为万位,第3位为千位,第2位为百位,第一位1为十位。转换过程中需要特别注意"零"的使用。
calPart2的原理是判断角位、分位是否位0,如果不为0转换为中文。需要注意的是如果整数部分为0,不需要加上"元"。
整个过程用res字符串暂存转换结果。
具体做法:
#include <iostream>
using namespace std;
string gewei[10] = {"", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
string res;
void calPart1(string str){
for(int i = str.size() - 1, j = 0; i >= 0; i--, j++){ //i表示这是数字的第几位,j表示字符串下标
if(str[j] != '0'){//将当前位置的数字转为中文
if(!(str[j] == '1' && i % 4 == 1)) //10应写作“拾”
res += gewei[str[j] - '0'];
}
if(i != 0){//当前不是个位
if(i % 8 == 0 && i >= 8){ //亿位
res += "亿";
}
if(i % 4 == 0 && i % 8 != 0){ //万位
res += "万";
if(str[j + 1] == '0') //如果千位为0
res += "零";
}
if(i % 4 == 3 && str[j] != '0'){ //千
res += "仟";
if(str[j + 1] == '0' && str[j + 2] != '0') //百位为0
res += "零";
}
if(i % 4 == 2 && str[j] != '0'){ //百
res += "佰";
if(str[j + 1] == '0' && str[j + 2] != '0') //十位为0
res += "零";
}
if(i % 4 == 1 && str[j] != '0') //十位
res += "拾";
}
}
}
//小数点之后的部分转换
void calPart2(string str){
if(str == "00")
{
res += "整";
return;
}
if (str[0] > '0')
{
res += gewei[str[0]-'0'] + "角";
}
if (str[1] > '0')
{
res += gewei[str[1]-'0'] + "分";
}
return;
}
//主函数
int main()
{
string str;
while(getline(cin, str))
{
//获取小数点的位置
int index = str.find('.');
//获取小数点前的子字符串
string str1 = str.substr(0, index);
//获取小数点后的子字符串
string str2 = str.substr(index + 1);
//输出人民币
cout << "人民币";
//输出元钱
calPart1(str1);
//输出角分零钱
if(str1!="0"){
res += "元";
}
calPart2(str2);
//换行
cout << res << endl;
res.clear();
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串。
- 空间复杂度:,只用了常数空间。
方法二:
将输入的数字转化int整数部分和小数点部分。首先对整数的大小进行判断,如果数字是0-9或者10-19、20-99可以直接逐位判断转换;如果数字大于100,我们判断先输出千位及以下的内容,然后对剩余的高位进行递归。
对于小数部分,是判断角位、分位是否位0,如果不为0转换为中文。需要注意的是如果小数部分为0,需要加上"整"。
具体做法:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
const vector<string> helper1 = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
const vector<string> helper2 = {"元", "万", "亿"};
const vector<string> helper3 = {"", "拾", "佰", "仟"};
string parts(int num)
{
string str;
if(num > 0 && num <= 9)
str += helper1[num];
else if(num >= 10 && num <= 19)
{
if(num % 10 == 0)
str += helper3[1];
else
str += helper3[1] + helper1[num%10];
}
else if(num >= 20 && num <= 99)
{
if(num % 10 == 0)
str += helper1[num/10] + helper3[1];
else
str += helper1[num/10] + helper3[1] + helper1[num%10];
}
else if(num >= 100 && num <= 999)
{
if(num % 100 == 0)
str += helper1[num/100] + helper3[2];
else if(num % 100 <= 9)
str += helper1[num/100] + helper1[0] + helper1[num%100];
else
str += helper1[num/100] + helper3[2] + parts(num % 100);
}
else if(num >= 1000 && num <= 9999)
{
if(num % 1000 == 0)
str += helper1[num/1000] + helper3[3];
else if(num % 1000 <= 99)
str += helper1[num/1000] + helper3[3] + helper1[0] + parts(num % 1000);
else
str += helper1[num/1000] + helper3[3] + parts(num % 1000);
}
return str;
}
int main(){
double money;
while (cin >> money)
{
money += 0.0001; // 此处+0.0001防止double转换int产生误差
// 分两步,第一步处理整数
int data = static_cast<int>(money);//强制转换,用来强迫隐式转换
vector<int> vec;
string res = "人民币";
while (data)
{
vec.push_back(data % 10000);
data /= 10000;
}
for (int i = vec.size() - 1; i >= 0; --i)
{
res += parts(vec[i]);
res += helper2[i];
if (i != 0 && i - 1 >= 0 && vec[i - 1] <= 999 && vec[i - 1] != 0)
res += helper1[0];
}
// 第二步处理小数
int deci = static_cast<int>((money - static_cast<int>(money)) * 100);
if (deci == 0)
res += "整";
else if (deci < 10)
res += helper1[deci] + "分";
else if (deci % 10 == 0)
res += helper1[deci / 10] + "角";
else
res += helper1[deci / 10] + "角" + helper1[deci % 10] + "分";
cout << res << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,递归需要遍历一遍字符串。
- 空间复杂度:,只用了常数空间。